Объекты HTMLCollection возвращаются из методов document.getElementsByTagName
document.getElementsByName
document.getElementsByClassName
(поддерживается не во всех браузерах) . Внешне они похожи на массивы, поскольку обладают свойством длины и к элементам можно получить доступ [index]. Однако они не являются массивами; такие методы, как push (), slice () и sort (), не поддерживаются.
Рассмотрим следующий HTML-документ:
<body>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
<p>Paragraph 3</p>
</body>
Давайте возьмем каждый узел абзаца, используя getElementsByTagName и селектор jQuery:
var pCollection = document.getElementsByTagName("p");
var pQuery = $("p");
console.log("pCollection.length: ", pCollection.length);
console.log("pQuery.length: ", pQuery.length);
Оба возвращают одинаковые узлы, поэтому длина коллекции равна 3:
pCollection.length: 3
pQuery.length: 3
Теперь мы добавим еще один элемент абзаца в документ и снова посмотрим на коллекции:
// add new paragraph
var newp = document.createElement("p");
newp.appendChild(document.createTextNode("Paragraph 4"));
document.body.appendChild(newp);
//
// display length
console.log("pCollection.length: ", pCollection.length);
console.log("pQuery.length: ", pQuery.length);
Результат:
pCollection.length: 4
pQuery.length: 3
HTMLCollection объекты являются живыми . Они автоматически обновляются при изменении базового документа. jQuery и большинство других библиотек JavaScript используют такие методы, как document.getElementsByTagName (), но копируют полученные узлы в реальный массив. Следовательно, это запрос о состоянии документа в то время: он никогда не обновляется.
У обоих методов есть свои преимущества и недостатки. Например, следующий код вызывает бесконечный цикл, поскольку длина HTMLCollection увеличивается при добавлении элементов <p>:
var pCollection = document.getElementsByTagName("p");
for (var i = 0; i < pCollection.length; i++) {
document.body.appendChild(pCollection[i].cloneNode(true));
}
Тем не менее, могут быть ситуации, когда более быстрая, естественная живая коллекция HTMLCollection более полезна, чем статическая коллекция узлов jQuery или многократный выбор одного и того же выбора. К счастью, мы можем передать любую коллекцию в jQuery, когда хотим манипулировать ею, например
var pCollection = document.getElementsByTagName("p");
// ... add nodes, do work, etc ...
$(pCollection).addClass("myclass");
jQuery и другие библиотеки могут сократить усилия по разработке, но всегда проверяют, возможно ли написать более эффективный код на простом старом JavaScript без дополнительных запросов к файлам и накладных расходов на обработку.