¿Cómo puedo verificar si un elemento DOM es hijo de otro elemento DOM? ¿Hay algún método incorporado para esto? Por ejemplo, algo como:
if (element1.hasDescendant(element2))
o
if (element2.hasParent(element1))
Si no, ¿alguna idea de cómo hacer esto? También debe ser un navegador cruzado. También debo mencionar que el niño podría estar anidado muchos niveles por debajo del padre.
javascript
dom
AJ
fuente
fuente
Respuestas:
Actualización: ahora hay una forma nativa de lograr esto.
Node.contains()
. Mencionado en comentarios y respuestas a continuación también.Vieja respuesta:
Usar la
parentNode
propiedad debería funcionar. También es bastante seguro desde el punto de vista del navegador cruzado. Si se sabe que la relación tiene un nivel de profundidad, puede verificarla simplemente:Si el hijo puede anidarse arbitrariamente en el interior del padre, puede usar una función similar a la siguiente para probar la relación:
fuente
Node.contains
(sin embargo, no hay página de caniuse)Node.contains
? :)Debe usarlo
Node.contains
, ya que ahora es estándar y está disponible en todos los navegadores.https://developer.mozilla.org/en-US/docs/Web/API/Node.contains
fuente
var parent = document.getElementById('menu'); var allElements = document.getElementsByTagName('a'); if (parent.contains(allElements[i]) { alert('Link is inside meni'); }
Solo tenía que compartir 'el mío'.
Aunque conceptualmente es lo mismo que la respuesta de Asaph (que se beneficia de la misma compatibilidad entre navegadores, incluso IE6), es mucho más pequeño y resulta útil cuando el tamaño es muy alto y / o cuando no se necesita con tanta frecuencia.
..o como una línea (¡ solo 64 caracteres !):
y jsfiddle aquí .
Uso:
childOf(child, parent)
devuelve booleanotrue
|false
.Explicación: se
while
evalúa siempre que la condición while se evalúe comotrue
.El
&&
operador (AND) devuelve este booleano verdadero / falso después de evaluar el lado izquierdo y el lado derecho, pero solo si el lado izquierdo era verdadero (left-hand && right-hand
) .El lado izquierdo (de
&&
) es:(c=c.parentNode)
.Esto asignará primero el
parentNode
dec
ac
y luego el operador AND evaluará el resultadoc
como un booleano.Como
parentNode
regresanull
si no queda ningún padre ynull
se convierte afalse
, el ciclo while se detendrá correctamente cuando no haya más padres.El lado derecho (de
&&
) es:c!==p
.El
!==
operador de comparación ' no es exactamente igual a'. Entonces, si el padre del niño no es el padre (usted especificó) se evalúatrue
, pero si el padre del niño es el padre, entonces se evalúafalse
.Entonces, si se
c!==p
evalúa como falso, el&&
operador regresafalse
como la condición while y el ciclo while se detiene. (Tenga en cuenta que no es necesario un cuerpo de tiempo y;
se requiere el punto y coma de cierre )Entonces, cuando finaliza el ciclo while,
c
es un nodo (nonull
) cuando encuentra un padre O lo esnull
(cuando el ciclo se ejecuta hasta el final sin encontrar una coincidencia).Por lo tanto, simplemente
return
ese hecho (convertido como valor booleano, en lugar del nodo) conreturn !!c;
:: el!
(NOT
operador) invierte un valor booleano (setrue
conviertefalse
y viceversa).!c
conviertec
(nodo o nulo) a un valor booleano antes de que pueda invertir ese valor. Entonces, agregar un segundo!
(!!c
) convierte este falso de nuevo en verdadero (razón por la cual un doble!!
menudo se usa para 'convertir cualquier cosa a booleano').Extra:
El cuerpo / carga útil de la función es tan pequeña que, dependiendo del caso (como cuando no se usa con frecuencia y aparece solo una vez en el código), uno podría incluso se omitir la función (ajuste) y solo usar el ciclo while:
en vez de:
fuente
!==
) puede mejorar la velocidad al dejar en claro al compilador que puede omitir la verificación de tipo y los pasos opcionales de conversión implícita que ocurrirían en una comparación de igualdad suelta, mejorando así la velocidad (al describir con mayor precisión lo que querer suceder, lo que también es beneficioso para el programador). También recuerdo cuando escribí esto, que solo la comparación (!=
) era muy propensa a errores o no funcionaba en algunos navegadores más antiguos (sospecho que estaba en IE6, pero he olvidado )Otra solución que no se mencionó:
Ejemplo aquí
No importa si el elemento es un hijo directo, funcionará a cualquier profundidad.
Alternativamente, usando el
.contains()
método :Ejemplo aquí
fuente
Eche un vistazo al Nodo # compareDocumentPosition .
Otras relaciones incluyen
DOCUMENT_POSITION_DISCONNECTED
,DOCUMENT_POSITION_PRECEDING
yDOCUMENT_POSITION_FOLLOWING
.No es compatible con IE <= 8.
fuente
Puedes usar el método contiene
var result = parent.contains(child);
o puedes intentar usar compareDocumentPosition ()
var result = nodeA.compareDocumentPosition(nodeB);
El último es más poderoso: devuelve una máscara de bits como resultado.
fuente
Me encontré con un maravilloso código para verificar si un elemento es hijo de otro elemento. Tengo que usar esto porque IE no admite el
.contains
método del elemento. Espero que esto ayude a otros también.A continuación se muestra la función:
fuente
prueba este:
fuente
Recientemente me encontré con esta función que podría hacer:
Node.compareDocumentPosition ()
fuente