¿Cómo puedo encontrar el ancestro de un elemento que está más cerca del árbol que tiene una clase particular, en JavaScript puro ? Por ejemplo, en un árbol así:
<div class="far ancestor">
<div class="near ancestor">
<p>Where am I?</p>
</div>
</div>
Entonces quiero div.near.ancestorsi intento esto en el py busco ancestor.
javascript
html
dom
rvighne
fuente
fuente

pelemento. Si en realidad solo desea obtener el nodo primario, puede hacerloele.parentNode.Respuestas:
Actualización: ahora compatible con la mayoría de los principales navegadores
Tenga en cuenta que esto puede coincidir con selectores, no solo clases
https://developer.mozilla.org/en-US/docs/Web/API/Element.closest
Para los navegadores heredados que no son compatibles
closest()pero tienenmatches()uno, puede crear una coincidencia de selector similar a la coincidencia de clase de @ rvighne:fuente
closestmuchas más características de recorrido DOM más avanzadas. Puede extraer esa implementación por sí solo o incluir todo el paquete para obtener muchas características nuevas en su código.Esto hace el truco:
El ciclo while espera hasta que
eltenga la clase deseada, y se estableceelenelel padre de cada iteración para que al final, tenga el antepasado con esa clase onull.Aquí hay un violín , si alguien quiere mejorarlo. No funcionará en navegadores antiguos (es decir, IE); vea esta tabla de compatibilidad para classList .
parentElementse usa aquí porqueparentNodeimplicaría más trabajo para asegurarse de que el nodo sea un elemento.fuente
.classList, consulte stackoverflow.com/q/5898656/218196 .parentElementes una propiedad bastante nueva (DOM nivel 4) yparentNodeexiste desde ... para siempre. Por lo tanto,parentNodetambién funciona en navegadores antiguos, mientras queparentElementpuede que no. Por supuesto, podría hacer el mismo argumento a favor / en contraclassList, pero no tiene una alternativa simple, comoparentElementtiene. De hecho, me pregunto por quéparentElementexiste en absoluto, no parece agregar ningún valorparentNode.while (!el.classList.contains(cls) && (el = el.parentElement));Use element.closest ()
https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
Ver este ejemplo DOM:
Así es como usarías element.closest:
fuente
Basado en la respuesta the8472 y https://developer.mozilla.org/en-US/docs/Web/API/Element/matches aquí está la solución multiplataforma 2017:
fuente
La solución @rvighne funciona bien, pero como se identifica en los comentarios
ParentElementyClassListambos tienen problemas de compatibilidad. Para hacerlo más compatible, he usado:parentNodepropiedad en lugar de laparentElementpropiedadindexOfmétodo en laclassNamepropiedad en lugar delcontainsmétodo en laclassListpropiedad.Por supuesto, indexOf simplemente está buscando la presencia de esa cadena, no le importa si es la cadena completa o no. Entonces, si tuviera otro elemento con la clase 'ancestro-type', aún así devolvería haber encontrado 'ancestor', si esto es un problema para usted, tal vez pueda usar regexp para encontrar una coincidencia exacta.
fuente