Comment puis-je trouver l'ancêtre d'un élément le plus proche de l'arbre qui a une classe particulière, en pur JavaScript ? Par exemple, dans un arbre comme celui-ci:
<div class="far ancestor">
<div class="near ancestor">
<p>Where am I?</p>
</div>
</div>
Alors je veux div.near.ancestor
si j'essaye ceci sur le p
et cherche ancestor
.
javascript
html
dom
rvighne
la source
la source
p
élément. Si vous ne souhaitez réellement obtenir que le nœud parent, vous pouvez le faireele.parentNode
.Réponses:
Mise à jour: désormais prise en charge dans la plupart des principaux navigateurs
Notez que cela peut correspondre aux sélecteurs, pas seulement aux classes
https://developer.mozilla.org/en-US/docs/Web/API/Element.closest
Pour les navigateurs hérités qui ne prennent pas en charge
closest()
mais qui en ontmatches()
un, vous pouvez créer une correspondance de sélecteur similaire à la correspondance de classe de @ rvighne:la source
closest
plus de nombreuses fonctionnalités de traversée DOM plus avancées. Vous pouvez extraire cette implémentation seule ou inclure l'ensemble complet pour obtenir de nombreuses nouvelles fonctionnalités dans votre code.Cela fait l'affaire:
La boucle while attend jusqu'à ce qu'elle
el
ait la classe souhaitée, et elle est définieel
surel
le parent de chaque itération, donc à la fin, vous avez l'ancêtre avec cette classe ounull
.Voici un violon , si quelqu'un veut l'améliorer. Cela ne fonctionnera pas sur les anciens navigateurs (ie IE); voir ce tableau de compatibilité pour classList .
parentElement
est utilisé ici carparentNode
cela impliquerait plus de travail pour s'assurer que le nœud est un élément.la source
.classList
, voir stackoverflow.com/q/5898656/218196 .parentElement
est une propriété plutôt nouvelle (DOM niveau 4) etparentNode
existe depuis ... pour toujours. Fonctionne doncparentNode
également dans les navigateurs plus anciens, alorsparentElement
que non. Bien sûr, vous pourriez faire le même argument pour / contreclassList
, mais il n'a pas d'alternative simple, commeparentElement
has. En fait, je me demande pourquoiparentElement
existe-t-il, cela ne semble pas ajouter de valeurparentNode
.while (!el.classList.contains(cls) && (el = el.parentElement));
Utilisez element.closest ()
https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
Voir cet exemple DOM:
Voici comment vous utiliseriez element.closest:
la source
Sur la base de la réponse the8472 et https://developer.mozilla.org/en-US/docs/Web/API/Element/matches voici la solution multiplateforme 2017:
la source
La solution @rvighne fonctionne bien, mais comme identifié dans les commentaires
ParentElement
et lesClassList
deux ont des problèmes de compatibilité. Pour le rendre plus compatible, j'ai utilisé:parentNode
propriété au lieu de laparentElement
propriétéindexOf
sur laclassName
propriété au lieu de lacontains
méthode sur laclassList
propriété.Bien sûr, indexOf recherche simplement la présence de cette chaîne, peu importe si c'est la chaîne entière ou non. Donc, si vous aviez un autre élément avec la classe 'ancestor-type', il retournerait toujours comme ayant trouvé 'ancestor', si cela vous pose problème, vous pouvez peut-être utiliser regexp pour trouver une correspondance exacte.
la source