Лучший способ получить дочерние узлы
мне было интересно, JavaScript предлагает множество методов для получения первого дочернего элемента из любого элемента, но какой из них лучше? Лучше всего, я имею в виду: наиболее кросс-браузер совместим, быстрый, наиболее полный и предсказуемый, когда речь заходит о поведении. Список методов / свойств, которые я использую в качестве псевдонимов:
var elem = document.getElementById('container');
var child = elem.children[0];
var child = elem.firstElementChild; // == children[0]
это работает в обоих случаях:
var child = elem.childNodes[0]; // or childNodes[1], see below
это в случае форм, или <div>
итерации. Если я могу столкнуться с текстом элементы:
var child = elem.childNodes; // treat as NodeList
var child = elem.firstChild;
насколько я могу понять,firstChild
использует список узлов из childNodes
и firstElementChild
использует children
. Я основываю это предположение на ссылке MDN:
childNode
ссылка на первый дочерний элемент элемента, илиnull
если нет.
я предполагаю, что с точки зрения скорости разница, если таковая имеется, будет почти нулевой, так как firstElementChild
фактически является ссылкой на children[0]
, и элемент children
объект уже в памяти в любом случае.
что меня бросает, так это
5 ответов:
Похоже, ты слишком много думаешь. Вы заметили разницу между
childNodes
иchildren
, чтоchildNodes
содержит все узлы, включая текстовые узлы, состоящие целиком из пробелов, в то время какchildren
представляет собой набор только дочерних узлов, которые являются элементами. Это действительно все, что нужно.в любой коллекции нет ничего непредсказуемого, хотя есть несколько проблем, о которых нужно знать:
- IE childNodes в то время как другие браузеры делают
- IE children в то время как другие браузеры имеют только элементы
children
,firstElementChild
и друзья-это просто удобства, представляющие отфильтрованный вид DOM, ограниченный только элементами.
firstElementChild может быть недоступен в IE
на IE
мое решение
child=(elem.firstElementChild||elem.firstChild)
это даст первенца даже на IE
кросс-браузер способ сделать это использовать
childNodes
иNodeList
, потом сделать массив всех узлов с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; }
это особенно легко, если вы используете служебную библиотеку, такую как лодашь:
/** * Return direct children elements. * * @param {HTMLElement} * @return {Array} */ function elementChildren (element) { return _.where(element.childNodes, {nodeType: 1}); }
будущее:
можно использовать
querySelectorAll
в сочетании с:scope
псевдо-класса (соответствует элементу, который является опорной точкой селектора):parentElement.querySelectorAll(':scope > *');
на момент написания этого
:scope
поддерживает в Chrome, Firefox и Safari.
- Эй, ребята, не позволяйте обмануть белого пространства. просто проверьте это в браузере консоли. используйте собственный javascript. Вот и пример с двумя наборами ' ul ' с одним и тем же классом. Вам не нужно иметь свой список " ul " в одной строке, чтобы избежать пробелов, просто используйте свой счетчик массивов, чтобы перепрыгнуть через пробел.
как обойти пробел, с
querySelector()
затемchildNodes[]
JS скрипка Ссылка: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>
просто чтобы добавить к другим ответам, здесь все еще есть примечательные различия, особенно при работе с
<svg>
элементы.я использовал как
.childNodes
и.children
и предпочли работать сHTMLCollection
выступил.children
геттер.однако сегодня я столкнулся с проблемами с IE / Edge при использовании
.children
на<svg>
. В то время как.children
поддерживается в IE на основных элементах HTML,он не поддерживается в документе / документе фрагменты, или SVG elements.для меня, я был в состоянии просто взять нужные элементы через
.childNodes[n]
потому что у меня нет внешних текстовых узлов для беспокойства. Вы можете быть в состоянии сделать то же самое, но как уже упоминалось выше, не забывайте, что вы можете столкнуться с неожиданными элементами.надеюсь, что это полезно для кого-то ломают головы, пытаясь выяснить, почему
.children
работает в другом месте в их js на современном IE и терпит неудачу на документе или SVG элементов.