Alterando Item de Menu Ativo ao Rolagem: JavaScript
Resumo Rápido
Você pode destacar o item de menu ativo usando o manipulador de eventos de rolagem em JavaScript. Quando o usuário rola a página para baixo, o script determina a seção atualmente ativa e atualiza a classe active
para o item de menu correspondente.
window.addEventListener('scroll', () => {
document.querySelectorAll('section').forEach((sec) => {
let menuLink = document.querySelector(`.menu-item[href="#${sec.id}"]`);
if (window.scrollY >= sec.offsetTop && window.scrollY < sec.offsetTop + sec.offsetHeight) {
menuLink.classList.add('active');
} else {
menuLink.classList.remove('active');
}
});
});
Cada seção da sua página deve ter um identificador (ID), e os links no menu devem conter o atributo href
apontando para o ID da seção respectiva. Para definir a aparência da classe ativa, utilize CSS.
Melhorando o Desempenho: Throttling e Debouncing
Triggers de eventos de rolagem muito frequentes podem degradar o desempenho. Para evitar isso, você pode usar métodos como Throttling e Debouncing.
O método Throttling limita a frequência das chamadas do manipulador de eventos, ajudando a evitar problemas de desempenho.
let ultima_posicao_de_rolagem_conhecida = 0;
let ticking = false;
let fazerAlgo = (posicao_de_rolagem) => {
// Rastreia a posição de rolagem atual
};
window.addEventListener('scroll', function(e) {
ultima_posicao_de_rolagem_conhecida = window.scrollY;
if (!ticking) {
window.requestAnimationFrame(function() {
fazerAlgo(ultima_posicao_de_rolagem_conhecida);
ticking = false;
});
ticking = true;
}
});
O método Debounce atrasa a execução da função até que um tempo específico tenha passado desde a última invocação.
function debounce(func, wait) {
let timeout;
return function executedFunction() {
let depois = function() {
clearTimeout(timeout);
func();
};
clearTimeout(timeout);
timeout = setTimeout(depois, wait);
};
}
window.addEventListener('scroll', debounce(function() {
// Lidar com a rolagem
}, 100));
Suave e Gentil: Fazendo a Rolagem Ser Suave
Para uma rolagem suave na página, use a seguinte propriedade CSS:
html {
scroll-behavior: smooth;
}
Se precisar de mais controle sobre o processo de rolagem, use JavaScript:
document.querySelectorAll('.menu-item').forEach(ancla => {
ancla.addEventListener('click', function(e) {
e.preventDefault();
let destino = document.querySelector(this.getAttribute('href'));
destino.scrollIntoView({ behavior: 'smooth' });
});
});
Assumindo Responsabilidade: Garantindo Responsividade e Compatibilidade entre Navegadores
Menus responsivos aprimoram a interação do usuário com o site. Use media queries CSS para estilizar itens de menu ativos em diferentes dispositivos.
@media screen and (max-width: 600px) {
/* Alterações para versões móveis */
}
Para garantir compatibilidade entre diferentes navegadores, verifique o suporte para eventos de rolagem e outras funções usadas em seus scripts para cada versão do navegador. Use polyfills, se necessário, para suportar versões de navegadores mais antigas.
Estando Visível: Indicações Visuais e Navegação Eficaz
O menu deve ser facilmente reconhecível pelos usuários. Use acentos visuais (cores, texto em negrito, ícones) para destacar a seção ativa atual.
.menu-item.active {
color: #fff;
background-color: #333;
font-weight: bold;
}
Para facilitar a navegação, fixe o menu na página:
.menu {
position: fixed;
top: 0;
width: 100%;
}
Visualização
O conceito do menu pode ser representado como um sistema de pontos de verificação ou estações de metrô:
🚂 == 🚏 (Início) === 🚏 (Sobre Nós) === 🚏 (Serviços) === 🚏 (Contato)
À medida que você rola a página, o item de menu ativo se move como um trem parando em várias estações:
Na Início: 🚂💡== 🚏 === 🚏 === 🚏
Durante a Rolagem: 🚏 == 🚂💡== 🚏 === 🚏
Nos Serviços: 🚏 == 🚏 === 🚂💡== 🚏
Assim, a seção ativa muda com base na posição da rolagem.
Adaptando-se às Mudanças: Lidando com Conteúdo Dinâmico e SPA
Elementos dinâmicos, como novos conteúdos ou aplicações de página única (SPA), requerem uma abordagem especial:
// Usando MutationObserver para monitorar mudanças na estrutura do DOM
const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
if (mutation.addedNodes.length || mutation.removedNodes.length) {
// Atualizar o estado do item de menu ativo
}
});
});
observer.observe(document.body, { childList: true, subtree: true });
// Monitorando mudanças de caminho na SPA
window.onhashchange = function() {
// Atualizar estado ativo dos itens de menu
}
Ao usar links de âncora, considere a altura do cabeçalho do site para que os títulos das seções não fiquem ocultos:
let altura_do_cabecalho = document.querySelector('.header').offsetHeight;
document.querySelectorAll('.menu-item').forEach(ancla => {
ancla.addEventListener('click', function(e) {
let id_do_destino = this.getAttribute('href').substring(1);
let destino = document.getElementById(id_do_destino);
window.scrollTo(0, destino.offsetTop - altura_do_cabecalho);
});
});
Recursos Úteis
- Documentação da API jQuery: Evento de Rolagem — mais detalhes sobre rolagem em jQuery.
- Scrollspy · Bootstrap v4.6 — ferramentas do Bootstrap para rastreamento da rolagem da página.
- API Intersection Observer - Web API | MDN — rastreamento da visibilidade de elementos na página.
- Tratando a Frequência de Chamadas de Manipuladores de Eventos de Rolagem para Melhoria de Desempenho — otimizando o tratamento de eventos de rolagem.
- Tabela de Conteúdos Fixa com Estados Ativos de Rolagem | CSS-Tricks — um guia para criar navegação útil.