queryselector javascript dom elements children

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, o null 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; }

http://jsfiddle.net/s4kxnahu/

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.