Determinando o Primeiro Elemento Pai Deslizável em JS
Resposta Rápida
A função JavaScript abaixo permite identificar o elemento pai deslizável mais próximo:
function getScrollableParent(node) {
let isScrollable = node => /^(auto|scroll)$/.test(window.getComputedStyle(node)['overflow-y']);
while (node && node !== document.body && !isScrollable(node)) {
node = node.parentElement; // Subindo para o elemento pai!
}
return node || document.body; // Retornando o pai deslizável ou, se nenhum for encontrado, document.body.
}
const scrollableParent = getScrollableParent(element);
Você deve substituir element
pelo elemento específico para o qual deseja encontrar o primeiro pai deslizável. Se nenhum for encontrado, a função retornará document.body
.
Analisando a Função com Mais Detalhes
Vamos dar uma olhada mais de perto em como a função determina o elemento pai deslizável.
Determinando a Capacidade de Deslizamento através de Propriedades CSS
A função examina o valor da propriedade overflow-y
nos estilos computados de cada elemento. Se o valor for 'auto' ou 'scroll', significa que o elemento suporta rolagem vertical.
Subindo na Estrutura do DOM
A função percorre um elemento pai para outro usando node.parentElement
. Isso é semelhante a subir uma escada na estrutura do DOM.
document.body como Alternativa
Se nenhum elemento pai com suporte a rolagem for encontrado durante essa "subida", a função retorna document.body
. Este elemento pode sempre funcionar como um contêiner deslizável, especialmente quando se usa posicionamento fixo.
Melhorando a Solução com Algumas Extensões
Tratando Mudanças de Orientação
Lembre-se de que em um layout de site responsivo, mudar a orientação pode afetar o elemento deslizável. Essas mudanças podem ser capturadas através de um ouvinte de eventos de redimensionamento:
window.addEventListener('resize', function() {
// O manipulador de redimensionamento captura alterações na orientação da tela.
const scrollableParent = getScrollableParent(element);
});
Assim, ao redimensionar a janela, a função reavalia o elemento pai deslizável.
Suportando Rolagem em Ambas as Direções
Você também deve considerar a possibilidade de rolagem horizontal e, consequentemente, expandir a verificação de condições:
const isScrollable = n =>
/^(auto|scroll|overlay)$/.test(window.getComputedStyle(n).overflowY) ||
/^(auto|scroll|overlay)$/.test(window.getComputedStyle(n).overflowX);
Refatorando Usando ES6
Uma sintaxe moderna pode melhorar a legibilidade e a manutenção do código:
const getScrollableParent = (node) => {
const { body } = document;
const isScrollable = ({ overflowY, overflowX }) =>
/^(auto|scroll|overlay)$/.test(overflowY) || /^(auto|scroll|overlay)$/.test(overflowX);
while (node && node !== body && !isScrollable(window.getComputedStyle(node))) {
node = node.parentElement;
}
return node || body; // A função retornará o corpo encontrado ou o resultado da expressão após o OR.
};
Visualização
Você pode visualizar o processo de encontrar o primeiro pai deslizável como uma expedição: a função verifica cada elemento em um determinado nível da hierarquia para sua capacidade de oculta conteúdo maior do que o exibido.
A "expedição" termina assim que um pai capaz de ocultar parte do conteúdo é encontrado.
Recursos Úteis
- Método Element.scrollIntoView() - Web API | MDN — Aprenda mais sobre o mecanismo de rolagem até um elemento selecionado.
- Criando um Botão "Voltar ao Topo" — Instruções sobre como implementar uma funcionalidade que retorna ao topo da página.
- overflow - CSS | MDN — Trabalhando com a propriedade CSS
overflow
, que pode ser usada para gerenciar a rolagem da página. - Estilização Moderna de Scrollbars em CSS (Atualização 2022) | CSS-Tricks — Uma visão geral dos métodos modernos para estilizar barras de rolagem.
- Método EventTarget.addEventListener() - Web API | MDN — Como trabalhar com eventos de rolagem.
- Determinando as Dimensões de Elementos - Web API | MDN — Informações sobre como determinar as dimensões de um elemento, o que é importante para gerenciar a rolagem.