javascript - queryselector - innerhtml
La mejor manera de conseguir nodos hijos (5)
Es posible que firstElementChild no esté disponible en IE <9 (solo firstChild)
en IE <9 firstChild es el 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
Me preguntaba si JavaScript ofrece una variedad de métodos para obtener el primer elemento secundario de cualquier elemento, pero ¿cuál es el mejor? Por mejor, quiero decir: más compatible con varios navegadores, más rápido, más completo y más 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 el caso de las formas, o iteración <div>
. Si pudiera encontrar elementos de texto:
var child = elem.childNodes; // treat as NodeList
var child = elem.firstChild;
Hasta donde puedo trabajar, firstChild
usa NodeList de childNodes
, y firstElementChild
usa children
. Estoy basando este supuesto en la referencia de MDN:
childNode
es una referencia al primer elemento secundario del nodo de elemento, onull
si no lo hay.
Supongo que, en términos de velocidad, la diferencia, si la hay, será casi firstElementChild
, ya que firstElementChild
es efectivamente una referencia a los children[0]
, y el objeto children
ya está en la memoria de todos modos.
Lo que sí me tira, es el objeto childNodes
. Lo he usado para echar un vistazo a un formulario, en un elemento de tabla. Mientras que los elementos childNodes
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);
Todos los registros <input type="text"
… >
. ¿Cómo? Comprendería que un objeto me permitiría trabajar con el código HTML "sin procesar", mientras que el otro se adhiere al DOM, pero el elemento childNodes
parece funcionar en ambos niveles.
Para volver a mi pregunta inicial, mi conjetura sería: si quiero el objeto más completo, childNodes
es el camino a seguir, pero debido a su amplitud, podría no ser el más predecible en términos de devolver el elemento que deseo. Espero en un momento dado. La compatibilidad con varios 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 a mano? Si hay una diferencia de velocidad, aunque sea insignificante, también me gustaría saberlo. Si estoy viendo todo esto mal, siéntete libre de educarme.
PD: Por favor, por favor, me gusta JavaScript, así que sí, quiero lidiar con este tipo de cosas. Respuestas como "jQuery se ocupa de esto por usted" no son lo que estoy buscando, por lo tanto, no hay etiqueta jquery .
Hola chicos, no dejéis que el espacio en blanco os engañe. solo prueba esto en un navegador de consola. utilizar 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 el espacio en blanco, solo use el conteo de su matriz para saltar sobre el espacio en blanco.
Cómo sortear el espacio en blanco con querySelector()
luego childNodes[]
js fiddle link: https://jsfiddle.net/aparadise/56njekdo/
var y = document.querySelector(''.list'');
var myNode = y.childNodes[11].style.backgroundColor=''red'';
<ul class="list">
<li>8</li>
<li>9</li>
<li>100</li>
</ul>
<ul class="list">
<li>ABC</li>
<li>DEF</li>
<li>XYZ</li>
</ul>
La forma de hacer un navegador cruzado es usar childNodes
para obtener NodeList
, luego hacer una matriz de todos los nodos con nodeType
ELEMENT_NODE .
/**
* Return direct children elements.
*
* @param {HTMLElement}
* @return {Array}
*/
function elementChildren (element) {
var childNodes = element.childNodes,
children = [],
i = childNodes.length;
while (i--) {
if (childNodes[i].nodeType == 1) {
children.unshift(childNodes[i]);
}
}
return children;
}
Esto es especialmente fácil si está utilizando una biblioteca de utilidades como lodash :
/**
* Return direct children elements.
*
* @param {HTMLElement}
* @return {Array}
*/
function elementChildren (element) {
return _.where(element.childNodes, {nodeType: 1});
}
Futuro:
Puede usar querySelectorAll
en combinación con :scope
querySelectorAll
:scope
(coincide con el elemento que es el punto de referencia del selector):
parentElement.querySelectorAll('':scope > *'');
En el momento de escribir esto :scope en Chrome, Firefox y Safari.
Parece que lo estás pensando demasiado. Ha observado la diferencia entre childNodes
y children
, que es que childNodes
contiene todos los nodos, incluidos los nodos de texto que consisten completamente en espacios en blanco, mientras que children
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 un par de problemas a tener en cuenta:
- IE <= 8 no incluye nodos de texto de espacio en blanco solamente en Nodos
childNodes
mientras que otros navegadores sí lo hacen - IE <= 8 incluye nodos de comentarios en
children
mientras que otros navegadores solo tienen elementos
children
, firstElementChild
y sus amigos son solo comodidades, presentando una vista filtrada del DOM restringida a solo elementos.
Solo para agregar a las otras respuestas, todavía hay diferencias notables aquí, específicamente cuando se trata de elementos <svg>
.
He utilizado ambos .childNodes
y .children
y he preferido trabajar con HTMLCollection
entregado por el .children
getter.
Sin embargo, hoy en día, tuve problemas con el fallo 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 fragmentos de documento / documento 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 averiguar por qué .children
trabaja en otros lugares en sus js en el IE moderno y falla en el documento o elementos SVG.