Me preguntaba, JavaScript ofrece una variedad de métodos para obtener el primer elemento hijo de cualquier elemento, pero ¿cuál es el mejor? Por mejor, quiero decir: la mayoría de los navegadores compatibles, más rápido, más completo y predecible cuando se trata de comportamiento. Una lista de métodos / propiedades que uso como alias:
var elem = document.getElementById('container');
var child = elem.children[0];
var child = elem.firstElementChild; // == children[0]
Esto funciona para ambos casos:
var child = elem.childNodes[0]; // or childNodes[1], see below
Eso es en caso de formas o <div>
iteración. Si pudiera encontrar elementos de texto:
var child = elem.childNodes; // treat as NodeList
var child = elem.firstChild;
Hasta donde puedo trabajar, firstChild
usa la NodeList de childNodes
, y firstElementChild
usa children
. Estoy basando esta suposición en la referencia de MDN:
childNode
es una referencia al primer elemento hijo del nodo del elemento, onull
si no hay uno.
Supongo que, en términos de velocidad, la diferencia, si la hay, será casi nula, ya firstElementChild
que efectivamente es una referencia children[0]
y el children
objeto ya está en la memoria de todos modos.
Lo que me arroja es el childNodes
objeto. Lo he usado para echar un vistazo a un formulario, en un elemento de tabla. Si bien children
enumera todos los elementos del formulario, childNodes
también parece incluir espacios en blanco del código HTML:
console.log(elem.childNodes[0]);
console.log(elem.firstChild);
Ambos log <TextNode textContent="\n ">
console.log(elem.childNodes[1]);
console.log(elem.children[0]);
console.log(elem.firstElementChild);
Todo registro <input type="text"
... >
. ¿Cómo? Entiendo que un objeto me permitiría trabajar con el código HTML "en bruto", mientras que el otro se adhiere al DOM, pero el childNodes
elemento parece funcionar en ambos niveles.
Para volver a mi pregunta inicial, mi suposición sería: si quiero el objeto más completo, childNodes
es el camino a seguir, pero debido a su exhaustividad, puede que no sea el más predecible en términos de que devuelva el elemento que quiero / esperar en cualquier momento dado. La compatibilidad entre navegadores también podría ser un desafío en ese caso, aunque podría estar equivocado.
¿Alguien podría aclarar la distinción entre los objetos en cuestión? Si hay una diferencia de velocidad, por insignificante que sea, también me gustaría saberlo. Si veo todo esto mal, no dudes en educarme.
PD: Por favor, por favor, me gusta JavaScript, así que sí, quiero lidiar con este tipo de cosas. Respuestas como "jQuery trata esto para usted" no son lo que estoy buscando, por lo tanto, nojquery etiqueta.
fuente
Respuestas:
Parece que lo estás pensando demasiado. Ha observado la diferencia entre
childNodes
ychildren
, que es quechildNodes
contiene todos los nodos, incluidos los nodos de texto que consisten completamente en espacios en blanco, mientras quechildren
es una colección de solo los nodos secundarios que son elementos. Eso es realmente todo lo que hay que hacer.No hay nada impredecible en ninguna de las colecciones, aunque hay algunos problemas a tener en cuenta:
childNodes
mientras que otros navegadores síchildren
mientras que otros navegadores solo tienen elementoschildren
,firstElementChild
y los amigos son solo conveniencias, ya que presentan una vista filtrada del DOM restringida a solo elementos.fuente
<td\n\t>content</td>
. Como puede hacer con XML, para evitar que se considere el exceso de espacio en blanco como parte de los datos (o DOM, en este caso). ¿Por qué se incluiría un espacio en blanco dentro de una etiqueta en el DOM?children
originó en IE 4 durante una década antes de convertirse en un estándar o ser adoptado por otros navegadores, podría argumentar que IE <= 8 es correcto y otros navegadores están equivocados.firstElementChild podría no estar disponible en IE <9 (solo firstChild)
en IE <9 firstChild es firstElementChild porque MS DOM (IE <9) no almacena nodos de texto vacíos. Pero si lo hace en otros navegadores, devolverán nodos de texto vacíos ...
mi solución
child=(elem.firstElementChild||elem.firstChild)
esto le dará al primer hijo incluso en IE <9
fuente
elem.firstChild
no es un nodo de elemento, los resultados serán diferentes en los IE antiguos, porqueelem.firstElementChild
siempre es un nodo de elemento.firstElementChild
tampoco es necesariamente seguro en navegadores que no sean IE: Firefox solo comenzó a admitirlo en la versión 3.5.La forma de hacerlo en el navegador cruzado es usar
childNodes
para obtenerNodeList
, luego hacer una matriz de todos los nodos connodeType
ELEMENT_NODE .http://jsfiddle.net/s4kxnahu/
Esto es especialmente fácil si está utilizando una biblioteca de utilidades como lodash :
Futuro:
Puede usar
querySelectorAll
en combinación con:scope
pseudo-clase (coincide con el elemento que es el punto de referencia del selector):Al momento de escribir esto,
:scope
es compatible con Chrome, Firefox y Safari.fuente
Solo para agregar a las otras respuestas, todavía hay diferencias notables aquí, específicamente cuando se trata de
<svg>
elementos.He usado ambos
.childNodes
y.children
he preferido trabajar con elHTMLCollection
entregado por el.children
getter.Hoy, sin embargo, me encontré con problemas con la falla de IE / Edge al usar
.children
en un<svg>
. Si bien.children
es compatible con IE en elementos HTML básicos, no es compatible con documentos / fragmentos de documentos o elementos SVG .Para mí, pude simplemente tomar los elementos necesarios a través de
.childNodes[n]
porque no tengo nodos de texto extraños de los que preocuparme. Es posible que pueda hacer lo mismo, pero como se mencionó anteriormente, no olvide que puede encontrarse con elementos inesperados.Espero que esto sea útil para alguien que se rasca la cabeza tratando de descubrir por qué
.children
funciona en otra parte de su js en IE moderno y falla en elementos de documento o SVG.fuente
Hola chicos, no dejen que el espacio en blanco los engañe. solo prueba esto en un navegador de consola. usa javascript nativo. Aquí hay un ejemplo con dos conjuntos 'ul' con la misma clase. No necesita tener su lista 'ul' en una sola línea para evitar espacios en blanco, solo use su recuento de matriz para saltar sobre el espacio en blanco.
Como llegar espacio alrededor blanco con
querySelector()
continuaciónchildNodes[]
js enlace violín: https://jsfiddle.net/aparadise/56njekdo/fuente
document.querySelector
no estaba bien respaldada en ese momento. b) La pregunta es básicamente preguntar cuáles son las diferencias internaschildren
ychildNodes
internas , lo cual es más confiable, cuándo elegir una sobre la otra. y c) Porque, como demonstraded en la pregunta: ¿childNodes
Qué incluye espacios en blanco nodos,children
no ...