Como posso encontrar o ancestral de um elemento mais próximo da árvore que possui uma classe específica, em JavaScript puro ? Por exemplo, em uma árvore como esta:
<div class="far ancestor">
<div class="near ancestor">
<p>Where am I?</p>
</div>
</div>
Então eu quero div.near.ancestor
se eu tentar isso no p
e procurar ancestor
.
javascript
html
dom
rvighne
fonte
fonte
p
elemento. Se você realmente deseja apenas obter o nó pai, pode fazê-loele.parentNode
.Respostas:
Atualização: agora suportada na maioria dos principais navegadores
Observe que isso pode corresponder aos seletores, não apenas às classes
https://developer.mozilla.org/en-US/docs/Web/API/Element.closest
Para navegadores herdados que não oferecem suporte,
closest()
masmatches()
podem criar correspondência de seletor semelhante à correspondência de classe do @ rvighne:fonte
closest
muitos outros recursos avançados de travessia do DOM. Você pode executar essa implementação por conta própria ou incluir todo o pacote para obter muitos novos recursos em seu código.Isso faz o truque:
O loop while espera até
el
ter a classe desejada e defineel
comoel
pai a cada iteração. No final, você tem o ancestral dessa classe ounull
.Aqui está um violino , se alguém quiser melhorá-lo. Não funcionará em navegadores antigos (ie IE); consulte esta tabela de compatibilidade para classList .
parentElement
é usado aqui porqueparentNode
envolveria mais trabalho para garantir que o nó seja um elemento.fonte
.classList
, consulte stackoverflow.com/q/5898656/218196 .parentElement
é uma propriedade bastante nova (nível 4 do DOM) eparentNode
existe desde ... para sempre. O mesmoparentNode
também funciona em navegadores mais antigos, ao passo queparentElement
talvez não. Claro que você poderia argumentar a favor / contraclassList
, mas ele não tem uma alternativa simples, comoparentElement
tem. Na verdade, eu me pergunto por queparentElement
existe, não parece agregar nenhum valorparentNode
.while (!el.classList.contains(cls) && (el = el.parentElement));
Use element.closest ()
https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
Veja este exemplo DOM:
É assim que você usaria o element.closest:
fonte
Com base na resposta the8472 e https://developer.mozilla.org/en-US/docs/Web/API/Element/matches, aqui está a solução 2017 para várias plataformas:
fonte
A solução @rvighne funciona bem, mas conforme identificado nos comentários
ParentElement
eClassList
ambos têm problemas de compatibilidade. Para torná-lo mais compatível, eu usei:parentNode
propriedade em vez daparentElement
propriedadeindexOf
método naclassName
propriedade em vez docontains
método naclassList
propriedadeObviamente, o indexOf está simplesmente procurando a presença dessa string, não importa se é a string inteira ou não. Portanto, se você tivesse outro elemento com a classe 'tipo de ancestral', ele ainda retornaria como tendo encontrado 'ancestral', se esse for um problema para você, talvez você possa usar o regexp para encontrar uma correspondência exata.
fonte