JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<nav>
<span class="active" data-section="section_1">
Secção 1
</span>
<span data-section="section_2">
Secção 2
</span>
<span data-section="section_3">
Secção 3
</span>
<span data-section="section_4">
Secção 4
</span>
</nav>
<div id="section_1" class="section">
Secção 1
</div>
<div id="section_2" class="section">
Secção 2
</div>
<div id="section_3" class="section">
Secção 3
</div>
<div id="section_4" class="section">
Secção 4
</div>
CSS
body {
margin:0;
}
nav {
position:fixed;
top:0;
background-color: #ffffff;
left:0;
height:100%;
}
span {
display:block;
border:1px solid;
cursor: pointer;
}
.active {
background-color: red;
}
.section {
height:600px;
width:400px;
border:1px solid;
text-align:center;
}
JavaScript
// animação scroll quando se clica no menu
$('span').on('click', function() {
$("html, body").animate({
scrollTop: $('#' +$(this).data('section')).offset().top // ir para a secção cujo o id é o valor do atributo `data-section` do item do menu onde clicamos
}, 500);
});
// guardamos todas as distancias de cada secção até ao todo da página e respetivo id
var alturas = {};
$('.section').each(function () {
alturas[$(this).prop('id')] = $(this).offset().top; // ex: alturas['section_2'] = 600
});
// quando fazemos scoll vamos percorrer o nosso obj alturas e comparar a altura de cada secção com o que já andamos em scroll
$(window).on('scroll', function() {
for(var seccao in alturas) {
if($(window).scrollTop() >= alturas[seccao]) {
$('span').removeClass('active'); // removemos a classe ative
$('span[data-section="' +seccao+ '"]').addClass('active'); // adicionamos a class active ao item do menu cuja data-section é igual ao id da secção que está a uma maior ou igual distancia do topo do que aquela que percorremos com o scroll
}
}
});