¿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.ancestor
si intento esto en el p
y busco ancestor
.
javascript
html
dom
rvighne
fuente
fuente
p
elemento. 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
closest
muchas 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
el
tenga la clase deseada, y se estableceel
enel
el 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 .
parentElement
se usa aquí porqueparentNode
implicaría más trabajo para asegurarse de que el nodo sea un elemento.fuente
.classList
, consulte stackoverflow.com/q/5898656/218196 .parentElement
es una propiedad bastante nueva (DOM nivel 4) yparentNode
existe desde ... para siempre. Por lo tanto,parentNode
también funciona en navegadores antiguos, mientras queparentElement
puede que no. Por supuesto, podría hacer el mismo argumento a favor / en contraclassList
, pero no tiene una alternativa simple, comoparentElement
tiene. De hecho, me pregunto por quéparentElement
existe 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
ParentElement
yClassList
ambos tienen problemas de compatibilidad. Para hacerlo más compatible, he usado:parentNode
propiedad en lugar de laparentElement
propiedadindexOf
método en laclassName
propiedad en lugar delcontains
método en laclassList
propiedad.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