Я работал над коротким скриптом для изменения <abbr>
внутреннего текста элементов, но обнаружил, что у nodelist
него нет forEach
метода. Я знаю, что nodelist
это не наследуется Array
, но разве это не кажется forEach
полезным методом? Есть конкретная проблема реализации я не в курсе , что мешает добавляющих forEach
к nodelist
?
Примечание. Мне известно, что у Dojo и jQuery forEach
в той или иной форме есть нодлисты. Я не могу использовать ни то, ни другое из-за ограничений.
javascript
arrays
dom
foreach
Змеи и кофе
источник
источник
Ответы:
В NodeList теперь есть forEach () во всех основных браузерах.
См. NodeList forEach () в MDN .
Оригинальный ответ
Ни один из этих ответов не объясняет, почему NodeList не наследуется от Array, что позволяет ему иметь
forEach
и все остальное.Ответ можно найти в этой ветке обсуждения . Короче говоря, он ломает сеть:
То есть какой-то код делал что-то вроде
if (x instanceof Array) { otherArray.concat(x); } else { doSomethingElseWith(x); }
Однако
concat
"настоящие" массивы (не instanceof Array) будут обрабатываться иначе, чем другие объекты:[1, 2, 3].concat([4, 5, 6]) // [1, 2, 3, 4, 5, 6] [1, 2, 3].concat(4) // [1, 2, 3, 4]
это означает, что приведенный выше код сломался, когда
x
был NodeList, потому что до того, как он пошел поdoSomethingElseWith(x)
пути, тогда как после он пошел поotherArray.concat(x)
пути, что сделало что-то странное, посколькуx
не было настоящим массивом.Некоторое время предлагалось создать
Elements
класс, являющийся реальным подклассом Array, который будет использоваться как «новый NodeList». Однако это было удалено из стандарта DOM , по крайней мере, на данный момент, поскольку реализовать его еще не представлялось возможным по ряду технических и связанных со спецификациями причин.источник
NodeList now has forEach() in all major browsers
похоже, подразумевает, что IE не является основным браузером. Надеюсь, это правда для некоторых людей, но не для меня (пока).Ты можешь сделать
Array.prototype.forEach.call (nodeList, function (node) { // Your code here. } );
источник
Array.prototype.forEach.call
можно сократить до[].forEach.call
Array.prototype.forEach.call
, это создание пустого массива и использование егоforEach
метода.Вы можете рассмотреть возможность создания нового массива узлов.
var nodeList = document.getElementsByTagName('div'), nodes = Array.prototype.slice.call(nodeList,0); // nodes is an array now. nodes.forEach(function(node){ // do your stuff here. });
Примечание. Это просто список / массив ссылок на узлы, которые мы здесь создаем, без повторяющихся узлов.
nodes[0] === nodeList[0] // will be true
источник
Array.prototype.forEach.call(nodeList, fun)
.var forEach = Array.prototype.forEach.call(nodeList, callback);
. Теперь вы можете просто позвонитьforEach(nodeList, callback);
Никогда не говори никогда, сейчас 2016 год, и
NodeList
объект реализовалforEach
метод в последней версии Chrome (v52.0.2743.116).Слишком рано использовать его в производстве, поскольку другие браузеры еще не поддерживают это (проверено FF 49), но я предполагаю, что скоро это будет стандартизировано.
источник
Array.prototype.slice.call(nodelist).forEach(…)
что стандартно и работает в старых браузерах.Короче говоря, реализация этого метода - конфликт дизайна.
Из MDN:
Источник: https://developer.mozilla.org/en-US/docs/DOM/NodeList (прокрутите вниз до раздела «Почему я не могу использовать forEach или сопоставить в NodeList?» )
источник
myNodeList --> NodeList.prototype --> Array.prototype --> Object.prototype --> null
:?Если вы хотите использовать forEach в NodeList, просто скопируйте эту функцию из Array:
NodeList.prototype.forEach = Array.prototype.forEach;
Вот и все, теперь вы можете использовать его так же, как и для Array:
document.querySelectorAll('td').forEach(function(o){ o.innerHTML = 'text'; });
источник
В ES2015 теперь вы можете использовать
forEach
метод для nodeList.document.querySelectorAll('abbr').forEach( el => console.log(el));
См. Ссылку MDN
Однако, если вы хотите использовать коллекции HTML или другие объекты, подобные массиву, в es2015 вы можете использовать
Array.from()
метод. Этот метод принимает подобный массиву или повторяемый объект (включая nodeList, HTML-коллекции, строки и т. Д.) И возвращает новый экземпляр Array. Вы можете использовать это так:const elements = document.getElementsByTagName('abbr'); Array.from(elements).forEach( el => console.log(el));
В качестве
Array.from()
метод является изменяемым, вы можете использовать его в коде es5 следующим образомvar elements = document.getElementsByTagName('abbr'); Array.from(elements).forEach( function(el) { console.log(el); });
Подробнее см. странице MDN .
Проверить текущую поддержку браузера .
ИЛИ
Другой способ es2015 - использовать оператор спреда.
[...document.querySelectorAll('abbr')].forEach( el => console.log(el));
Оператор спреда MDN
Оператор распространения - Поддержка браузера
источник
Мое решение:
//foreach for nodeList NodeList.prototype.forEach = Array.prototype.forEach; //foreach for HTML collection(getElementsByClassName etc.) HTMLCollection.prototype.forEach = Array.prototype.forEach;
источник
NodeList является частью DOM API. Посмотрите на привязки ECMAScript, которые также применимы к JavaScript. http://www.w3.org/TR/DOM-Level-2-Core/ecma-script-binding.html . NodeList и свойство длины только для чтения и функция элемента (индекса) для возврата узла.
Ответ: вам нужно повторить. Альтернативы нет. Foreach работать не будет. Я работаю с привязками Java DOM API и имею ту же проблему.
источник
NodeList.forEach(function(item, index, nodeList) { // code block here });
В IE используйте ответ Akuhn :
[].forEach.call(NodeList, function(item, index, array) { // code block here });
источник