Подтвердить что ты не робот

Как перебрать все элементы, возвращенные из 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>
4b9b3361

Ответ 1

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

<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);
}

Зачем нам это нужно?
Некоторые объекты в JavaScript выглядят как массивы, но это не так. Обычно это означает, что у них есть индексированный доступ и свойство длины, но ни один из методов массива. Примеры включают в себя аргументы специальных переменных, списки узлов DOM и строки. Подобные массиву объекты и общие методы дают советы по работе с массивоподобными объектами. [введите описание ссылки здесь] [источник]

ОБНОВЛЕНИЕ для 07.10.2019
Внастоящее время с ES6 вы можете использовать [...inputList].forEach или Array.from(inputList)

Ответ 3

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

А так как HTMLCollection - подобные массиву объекты, вы можете call Array#forEach на нем, как это

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

Ответ 4

Это потому, что это коллекция html. Коллекция html не имеет для Each.

вы можете легко преобразовать его в массив с помощью Array.prototype.slice

Пример:

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/

Ответ 5

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

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

Таким образом, поскольку объекты типа Array наследуют от Object.prototype 'вместо Array.prototype', это означает, что объекты, подобные Array, не могут получить доступ общие методы прототипа Array, такие как forEach(), push(), map(), filter() и slice().

Надеюсь, что это поможет!

Ответ 6

getElementsByTagName возвращает HTMLCollection, у которого нет метода forEach. Но есть простая настройка, которая позволит вам выполнять итерации с forEach без создания промежуточного массива: вместо этого используйте querySelectorAll. querySelectorAll возвращает NodeList, а современные браузеры имеют метод NodeList.prototype.forEach:

document.querySelectorAll('input')
  .forEach((input) => {
    console.log(input.value);
  });
<input type="text" value="foo">
<input type="text" value="bar">

Ответ 7

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

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

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

Ответ 9

Я сделал это:

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

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

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

Ответ 10

Если вы можете использовать ES2015, вы можете использовать Array.from() для преобразования HTMLCollection, возвращенного getElementsByTagName(), в реальный массив. Если вы измените строку 11 на следующую, остальная часть кода будет работать как есть:

var input = Array.from(document.getElementsByTagName("input"));