Как перебрать все элементы, возвращенные из 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>
Ответы
Ответ 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)
Ответ 2
Yay, ES6:
const children = [...parent.getElementsByTagName('tag')];
children.forEach((child) => { /* Do something; */ });
MDN Doc для оператора спреда (...
)
Ответ 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
для вызова.
Ответ 8
В ES6 вы можете использовать оператор spread
для преобразования HtmlCollection в массив. см. этот вопрос Почему я не могу использовать Array.forEach в коллекции элементов Javascript?
input = [...input]
input.forEach(ShowResults)
Ответ 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"));