From 074785cea106179cb3305637055ab0a009ca74f2 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:42:52 -0500 Subject: initial commit --- files/ru/web/api/nodelist/index.html | 144 +++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 files/ru/web/api/nodelist/index.html (limited to 'files/ru/web/api/nodelist') diff --git a/files/ru/web/api/nodelist/index.html b/files/ru/web/api/nodelist/index.html new file mode 100644 index 0000000000..3deb328f99 --- /dev/null +++ b/files/ru/web/api/nodelist/index.html @@ -0,0 +1,144 @@ +--- +title: NodeList +slug: Web/API/NodeList +tags: + - API + - DOM + - Interface + - NodeList +translation_of: Web/API/NodeList +--- +
{{APIRef("DOM")}}
+ +

Объект NodeList — это коллекция узлов, возвращаемая такими методами, как {{domxref("Node.childNodes")}} и {{domxref("document.querySelectorAll")}}.

+ +
+

Несмотря на то, что NodeList не является массивом ( Array ), его вполне возможно перебрать при помощи метода forEach(). NodeList также можно конвертировать в Array при помощи {{jsxref("Array.from()")}}

+ +

Однако некоторые старые браузеры на данный момент все еще не поддерживают NodeList.forEach() или Array.from(). Данные ограничения можно обойти, используя {{jsxref("Array.forEach()", "Array.prototype.forEach()")}} ( больше информации на этой странице ).

+
+ +

Свойства

+ +
+
length
+
Количество элементов в NodeList.
+
+ +

Методы

+ +
+
item ( idx )
+
Возвращает элемент из списка по его индексу или null, если индекс выходит за границы допустимого диапазона. Может быть использован как альтернатива nodeList[idx], возвращающему undefined при недопустимом idx.
+
entries()
+
Возвращает {{jsxref("Iteration_protocols","iterator")}}, позволяя перебрать все пары ключ/значение, содержащиеся в обьекте.
+
forEach()
+
Выполняет указанную функцию один раз для каждого элемента NodeList
+
keys()
+
Возвращает {{jsxref("Iteration_protocols","iterator")}}, позволяя перебрать все ключи каждой пары ключ/значение, содержащейся в обьекте.
+
values()
+
Возвращает {{jsxref("Iteration_protocols","iterator")}}, позволяя перебрать все значения каждой пары ключ/значение, содержащейся в обьекте.
+
 
+
+ +

Описание

+ +

Динамическая коллекция

+ +

В определённых случаях NodeList может являться динамической коллекцией. Это означает, что любые изменения в DOM тут же отражаются на коллекции. Примером подобной коллекции является {{domxref("Node.childNodes")}}:

+ +
var parent = document.getElementById('parent');
+var child_nodes = parent.childNodes;
+console.log(child_nodes.length); // пусть равно "2"
+parent.appendChild(document.createElement('div'));
+console.log(child_nodes.length); // выведет "3"
+
+ +

В других случаях NodeList является статической коллекцией. Это означает, что любые изменения в DOM не отражаются на его содержании. К примеру, {{domxref("document.querySelectorAll")}} возвращает статический NodeList.

+ +

Данное деление необходимо иметь в виду при выборе способа обхода элементов NodeList, а также сохранении длины списка в переменную.

+ +

Отличия NodeList от Array

+ +

NodeList используется подобно массивам, и потому может возникнуть закономерное желание использовать в нём методы, предоставляемые Array.prototype. Однако NodeList не реализует методы, подобные таковым у Array.

+ +

В JavaScript существует механизм наследования, основанный на прототипах, применяемый как к встроенным («native») (таким как Array), так и «host»-объектам, предоставляемым средой исполнения (таким как NodeList) . Экземпляры класса Array получают свои методы (к примеру, forEach и map) из следующей цепочки наследования:

+ +

myArray --> Array.prototype --> Object.prototype --> null (Цепочка прототипов объекта может быть получена рекурсивным вызовом Object.getPrototypeOf)

+ +

forEach, map, ровно как и все остальные свойства принадлежат Array.prototype.

+ +

Цепочка же прототипов NodeList выглядит следующим образом:

+ +

myNodeList --> NodeList.prototype --> Object.prototype --> null

+ +

NodeList.prototype содержит метод item, но никак не остальные методы Array.prototype, поэтому они и не могут быть использованы с NodeLists.

+ +

Обходные пути

+ +

Один из способов решения данной проблемы — это копирование методов из Array.prototype в NodeList.prototype. Однако необходимо отдавать себе отчёт в том, что расширение объектов DOM опасно, особенно в старых версиях Internet Explorer (6, 7, 8).

+ +
var arrayMethods = Object.getOwnPropertyNames( Array.prototype );
+
+arrayMethods.forEach( attachArrayMethodsToNodeList );
+
+function attachArrayMethodsToNodeList(methodName)
+{
+  if(methodName !== "length") {
+    NodeList.prototype[methodName] = Array.prototype[methodName];
+  }
+};
+
+var divs = document.getElementsByTagName( 'div' );
+var firstDiv = divs[ 0 ];
+
+firstDiv.childNodes.forEach(function( divChild ){
+  divChild.parentNode.style.color = '#0F0';
+});
+ +

Другой подход — расширение непосредственно объектов DOM:

+ +
var forEach = Array.prototype.forEach;
+
+var divs = document.getElementsByTagName( 'div' );
+var firstDiv = divs[ 0 ];
+
+forEach.call(firstDiv.childNodes, function( divChild ){
+  divChild.parentNode.style.color = '#0F0';
+});
+
+ +
+

Стоит отметить, что передача объектов среды (такого как NodeList) через this native-методу (такому как forEach) гарантированно работает не во всех браузерах и точно не работает в некоторых.

+
+ +

Пример

+ +

Элементы в NodeList, можно обработать следующим образом:

+ +
for (var i = 0; i < myNodeList.length; ++i) {
+  var item = myNodeList[i];  // Вызов myNodeList.item(i) необязателен в JavaScript
+}
+
+ +

Не следует использовать конструкции for...in или for each...in для перечисления элементов списка. Эти способы также перечислят и свойства length и item, что приведёт к логическим ошибкам в случае, если скрипт ожидает  только объекты {{domxref("node")}}. Также for..in может перечислять свойства в любом порядке.

+ +

Циклы for...of корректно перечисляют все объекты внутри NodeList в браузерах, в которых поддерживается for...of (например, Firefox 13 или выше):

+ +
var list = document.querySelectorAll( 'input[type=checkbox]' );
+for (var item of list) {
+  item.checked = true;
+}
+ +

Конвертирование NodeList в Array

+ +

Иногда удобнее работать с содержимым NodeList, используя методы Array. Ниже приведена техника преобразования NodeList к Array:

+ +
var div_list = document.querySelectorAll('div'); // returns NodeList
+var div_array = Array.prototype.slice.call(div_list); // преобразует NodeList в Array
+ +

Спецификация

+ + -- cgit v1.2.3-54-g00ecf