JavaScript: цикл через все элементы, возвращенные из getElementsByTagName

Я пытаюсь выполнить цикл через все элементы, возвращенные из getElementsByTagName("input") использование forEach. Любые идеи, почему это не работает в FF, Chrome или IE?

<html>
    <head>
    </head>
    <body>
        <input type="text" value="" />
        <input type="text" value="" />
        <script>
            function ShowResults(value, index, ar) {
                alert(index);
            }
            var input = document.getElementsByTagName("input");
            alert(input.length);
            input.forEach(ShowResults);
    </script>
    </body>
</html>

8 ответов


вам нужно преобразовать nodelist в массив с помощью этого:

<html>
    <head>
    </head>
    <body>
        <input type="text" value="" />
        <input type="text" value="" />
        <script>
            function ShowResults(value, index, ar) {
                alert(index);
            }
            var input = document.getElementsByTagName("input");
            var inputList = Array.prototype.slice.call(input);
            alert(inputList.length);
            inputList.forEach(ShowResults);
    </script>
    </body>
</html>

или использовать для петли.

for(i = 0;i < input.length; i++)
{
    ShowResults(input[i].value);
}

и измените функцию ShowResults на:

function ShowResults(value) {
   alert(value);
}

Yay, ES6:

const children = [...parent.getElementsByTagName('tag')];
children.forEach((child) => { /* Do something; */ });

MDN Doc для оператора распространения (...)


, потому что input - это не массив, это HTMLCollection Используйте for петля была бы лучше.

и с HTMLCollections являются такими, как объекты, которые можно call Array#forEach вот так

Array.prototype.forEach.call(input, ShowResults);

Это becauseinput коллекция в формате HTML. HTML-коллекция не имеет forEach.

вы можете легко передать его в массив массивом.прототип.ломтик

пример:

function ShowResults(value, index, ar) {
            alert(index);
        }
        var input = document.getElementsByTagName("input");
        alert(input.length);
input = Array.prototype.slice.call(input)
        input.forEach(ShowResults);

http://jsfiddle.net/fPuKt/1/


причина, это не работает, потому что 'getElementsByTagName ' возвращает объект, подобный массиву, а не фактический массив. Если вы не знаете, вот как они оба выглядят: -

var realArray = ['a', 'b', 'c'];
var arrayLike = {
  0: 'a',
  1: 'b',
  2: 'c',
  length: 3
};

таким образом, с массив-как объекты наследуют от '


HTMLCollections не имеет тех же методов, что и массивы. Вы можете проверить это, подсказав это в консоли javascript Вашего браузера.

var elements = document.getElementsByClassName('some-class');
'forEach' in elements;

и консоль вернется true если elements (в этом случае) имеет метод под названием forEach, чтобы позвонить.


в ES6 вы можете использовать spread оператор для преобразования HtmlCollection в массив. см. этот вопрос почему я не могу использовать Array.forEach на коллекции элементов Javascript?

input = [...input]
input.forEach(ShowResults)

Я сделал так:

HTMLCollection.prototype.map = Array.prototype.map;

Теперь вы можете использовать карту на каждый HTMLCollection.

document.getElementsByTagName("input").map(
    input => console.log(input)
);