我正在尝试使用forEach遍历从getElementsByTagName("input")
返回的所有元素。任何想法为什么这在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>
答案 0 :(得分:64)
您需要将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);
}
答案 1 :(得分:32)
答案 2 :(得分:8)
因为input
不是数组,所以HTMLCollection
使用for
循环会更好。
由于HTMLCollection
是类似于数组的对象,因此您可以像call
Array#forEach
一样
Array.prototype.forEach.call(input, ShowResults);
答案 3 :(得分:5)
因为输入是html集合。 html集合没有forEach。
您可以通过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);
答案 4 :(得分:4)
原因是,这不起作用是因为&#39; getElementsByTagName &#39;返回一个数组 - 比如Object而不是实际的数组。如果您不知道,请参阅以下两者: -
var realArray = ['a', 'b', 'c'];
var arrayLike = {
0: 'a',
1: 'b',
2: 'c',
length: 3
};
因此,由于类似数组的对象继承自&#39; Object.prototype &#39;而不是&#39; Array.prototype &#39;,这意味着类似数组的对象无法访问常见的数组原型方法,如forEach(),push(),map() ,filter()和slice()。
希望有所帮助!
答案 5 :(得分:2)
HTMLCollections与数组的方法不同。您可以在浏览器的javascript控制台中查看此内容来检查此内容。
var elements = document.getElementsByClassName('some-class');
'forEach' in elements;
如果true
(在本例中)有一个名为elements
的方法,则控制台将返回forEach
。
答案 6 :(得分:2)
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">
使用querySelectorAll
的另一个好处是,它接受逗号分隔的查询字符串,它比标记名更灵活,更精确。例如,查询字符串
.container1 > span, .container2 > span
将仅匹配span
类元素的子类container1
或container2
:
document.querySelectorAll('.container1 > span, .container2 > span')
.forEach((span) => {
span.classList.add('highlight');
});
.highlight {
background-color: yellow;
}
<div class="container1">
<span>foo</span>
<span>bar</span>
</div>
<div class="container2">
<span>baz</span>
</div>
<div class="container3">
<span>buzz</span>
</div>
如果您想在没有内置方法的古老浏览器上使用NodeList.prototype.forEach
,只需添加一个polyfill。以下代码段适用于IE11:
// Polyfill:
if (window.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = function(callback, thisArg) {
thisArg = thisArg || window;
for (var i = 0; i < this.length; i++) {
callback.call(thisArg, this[i], i, this);
}
};
}
// Main code:
document.querySelectorAll('.container1 > span, .container2 > span')
.forEach(function(span) {
span.classList.add('highlight');
});
.highlight {
background-color: yellow;
}
<div class="container1">
<span>foo</span>
<span>bar</span>
</div>
<div class="container2">
<span>baz</span>
</div>
<div class="container3">
<span>buzz</span>
</div>
答案 7 :(得分:1)
在ES6中,您可以使用spread
运算符将HtmlCollection转换为数组。看到这个问题Why can't I use Array.forEach on a collection of Javascript elements?
input = [...input]
input.forEach(ShowResults)
答案 8 :(得分:1)
我这样做了:
HTMLCollection.prototype.map = Array.prototype.map;
现在,您可以在每个HTMLCollection
上使用地图。
document.getElementsByTagName("input").map(
input => console.log(input)
);
答案 9 :(得分:0)
如果可以使用ES2015,则可以使用<ul>
<li><a href="/pic2_elephant"><img id="pic2" src="pic2.jpg" /> <h2>Elephant</h2></a></li>
<li><a href="/pic1_dog"><<img id="pic1" src="pic1.jpg" /> <h2>Dog</h2></li>
<li><a href="/pic3_cat"><<img id="pic3" src="pic3.jpg" /> <h2>Cat</h2></li>
</ul>
将Array.from()
返回的HTMLCollection
转换为实数组。如果将第11行更改为以下内容,其余代码将按原样工作:
getElementsByTagName()