Je me demandais, JavaScript propose une variété de méthodes pour obtenir le premier élément enfant de n'importe quel élément, mais quelle est la meilleure? Au mieux, je veux dire: le plus compatible avec tous les navigateurs, le plus rapide, le plus complet et le plus prévisible en matière de comportement. Une liste de méthodes / propriétés que j'utilise comme alias:
var elem = document.getElementById('container');
var child = elem.children[0];
var child = elem.firstElementChild; // == children[0]
Cela fonctionne pour les deux cas:
var child = elem.childNodes[0]; // or childNodes[1], see below
C'est en cas de formes, ou d' <div>
itération. Si je pouvais rencontrer des éléments de texte:
var child = elem.childNodes; // treat as NodeList
var child = elem.firstChild;
Pour autant que je puisse travailler, firstChild
utilise la NodeList de childNodes
, et firstElementChild
utilise children
. Je fonde cette hypothèse sur la référence MDN:
childNode
est une référence au premier élément enfant du nœud d'élément, ounull
s'il n'y en a pas.
Je suppose que, en termes de vitesse, la différence, le cas échéant, ne sera presque rien, car il firstElementChild
s'agit effectivement d'une référence à children[0]
, et l' children
objet est déjà en mémoire de toute façon.
Ce qui me jette, c'est l' childNodes
objet. Je l'ai utilisé pour jeter un œil à un formulaire, dans un élément de table. Bien qu'il children
répertorie tous les éléments du formulaire, childNodes
il semble également inclure des espaces dans le code HTML:
console.log(elem.childNodes[0]);
console.log(elem.firstChild);
Les deux journaux <TextNode textContent="\n ">
console.log(elem.childNodes[1]);
console.log(elem.children[0]);
console.log(elem.firstElementChild);
Tous les journaux <input type="text"
… >
. Comment venir? Je comprendrais qu'un objet me permettrait de travailler avec le code HTML «brut», tandis que l'autre reste fidèle au DOM, mais l' childNodes
élément semble fonctionner aux deux niveaux.
Pour revenir à ma question initiale, je suppose que si je veux l'objet le plus complet, childNodes
c'est le chemin à parcourir, mais en raison de son exhaustivité, ce n'est peut-être pas le plus prévisible en termes de retour de l'élément que je veux / attendre à tout moment. La prise en charge de plusieurs navigateurs pourrait également s'avérer être un défi dans ce cas, bien que je puisse me tromper.
Quelqu'un pourrait-il clarifier la distinction entre les objets à portée de main? S'il y a une différence de vitesse, même négligeable, j'aimerais aussi le savoir. Si je vois tout cela de travers, n'hésitez pas à me renseigner.
PS: S'il vous plaît, s'il vous plaît, j'aime JavaScript, alors oui, je veux m'occuper de ce genre de choses. Les réponses comme «jQuery s'occupe de cela pour vous» ne sont pas ce que je recherche, donc nonjquery marque.
la source
Réponses:
On dirait que vous y pensez trop. Vous avez observé la différence entre
childNodes
etchildren
, quichildNodes
contient tous les nœuds, y compris les nœuds de texte entièrement constitués d'espaces, tandischildren
qu'une collection se compose uniquement des nœuds enfants qui sont des éléments. C'est vraiment tout ce qu'il y a à faire.Il n'y a rien d'imprévisible dans l'une ou l'autre collection, bien qu'il y ait quelques problèmes à prendre en compte:
childNodes
tandis que les autres navigateurs le fontchildren
tandis que les autres navigateurs n'ont que des élémentschildren
,firstElementChild
et les amis ne sont que des commodités, présentant une vue filtrée du DOM restreinte aux seuls éléments.la source
<td\n\t>content</td>
. Comme vous pouvez le faire avec XML, pour éviter que les espaces blancs excédentaires ne soient considérés comme faisant partie des données (ou DOM, dans ce cas). Pourquoi les espaces à l'intérieur d'une balise seraient-ils inclus dans le DOM?children
origine dans IE 4 sur une décennie avant de devenir une norme ou d'être adoptée par d'autres navigateurs, vous pourriez affirmer que IE <= 8 est correct et que d'autres navigateurs ont tort.firstElementChild peut ne pas être disponible dans IE <9 (uniquement firstChild)
sur IE <9 firstChild est le firstElementChild car MS DOM (IE <9) ne stocke pas de nœuds de texte vides. Mais si vous le faites sur d'autres navigateurs, ils renverront des nœuds de texte vides ...
ma solution
child=(elem.firstElementChild||elem.firstChild)
cela donnera le premier enfant même sur IE <9
la source
elem.firstChild
ne s'agit pas d'un nœud d'élément, les résultats seront différents dans les anciens IE, car ilelem.firstElementChild
s'agit toujours d'un nœud d'élément.firstElementChild
n'est pas nécessairement sûr non plus dans les navigateurs non IE: Firefox n'a commencé à le prendre en charge que dans la version 3.5.La façon de naviguer entre les navigateurs consiste à utiliser
childNodes
pour obtenirNodeList
, puis à créer un tableau de tous les nœuds avecnodeType
ELEMENT_NODE .http://jsfiddle.net/s4kxnahu/
C'est particulièrement facile si vous utilisez une bibliothèque d'utilitaires telle que lodash :
Futur:
Vous pouvez utiliser
querySelectorAll
en combinaison avec une:scope
pseudo-classe (correspond à l'élément qui est le point de référence du sélecteur):Au moment de la rédaction, cela
:scope
est pris en charge dans Chrome, Firefox et Safari.la source
Pour ajouter aux autres réponses, il y a encore des différences notables ici, en particulier en ce qui concerne les
<svg>
éléments.J'ai utilisé les deux
.childNodes
et.children
j'ai préféré travailler avec leHTMLCollection
livré par le.children
getter.Aujourd'hui cependant, j'ai rencontré des problèmes avec IE / Edge échouant lors de l'utilisation
.children
sur un<svg>
. Bien qu'il.children
soit pris en charge dans IE sur les éléments HTML de base, il n'est pas pris en charge sur les fragments de document / document ou les éléments SVG .Pour moi, j'ai pu simplement saisir les éléments nécessaires via
.childNodes[n]
car je n'ai pas de nœuds de texte superflus à craindre. Vous pouvez peut-être faire de même, mais comme mentionné ci-dessus, n'oubliez pas que vous pouvez rencontrer des éléments inattendus.J'espère que cela est utile à quelqu'un qui se gratte la tête en essayant de comprendre pourquoi
.children
fonctionne ailleurs dans son js sur IE moderne et échoue sur les éléments de document ou SVG.la source
Hé les gars, ne laissez pas les espaces blancs vous tromper. il suffit de tester cela dans un navigateur de console. utilisez le javascript natif. Voici et exemple avec deux ensembles 'ul' avec la même classe. Vous n'avez pas besoin d'avoir votre liste «ul» sur une seule ligne pour éviter les espaces blancs, utilisez simplement le nombre de tableaux pour sauter par-dessus l'espace blanc.
Comment obtenir de l' espace autour de blanc
querySelector()
puischildNodes[]
js lien violon: https://jsfiddle.net/aparadise/56njekdo/la source
document.querySelector
n'était pas bien soutenue à l'époque. b) La question est essentiellement de savoir quelles sont les différences entrechildren
et enchildNodes
interne , ce qui est plus fiable, quand choisir l'un plutôt que l'autre. et c) Parce que, comme demonstraded dans la question:childNodes
ne comprend les espaces nœuds, quichildren
ne fonctionne pas ...