javascript 如何遍历从 getElementsByTagName 返回的所有元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19324700/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to loop through all the elements returned from getElementsByTagName
提问by slayernoah
I am trying to loop through all the elements retruned from getElementsByTagName("input")
using forEach. Any ideas why this does not work in FF, Chrome or IE?
我正在尝试遍历从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>
回答by Dvir
You need to convert the nodelist to array with this:
您需要使用以下命令将节点列表转换为数组:
<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>
or use for loop.
或使用 for 循环。
for(i = 0;i < input.length; i++)
{
ShowResults(input[i].value);
}
and change ShowResults function to:
并将 ShowResults 函数更改为:
function ShowResults(value) {
alert(value);
}
Why do we need to do that?
Some objects in JavaScript look like an array, but they aren't one. That usually means that they have indexed access and a length property, but none of the array methods. Examples include the special variable arguments, DOM node lists, and strings. Array-Like Objects and Generic Methods gives tips for working with array-like objects.
source
为什么我们需要这样做?
JavaScript 中的一些对象看起来像一个数组,但它们不是一个。这通常意味着它们具有索引访问和长度属性,但没有任何数组方法。示例包括特殊变量参数、DOM 节点列表和字符串。类数组对象和通用方法提供了使用类数组对象的技巧。
来源
UPDATE for 07.10.2019
Nowdays with ES6 you can use [...inputList].forEach
, or Array.from(inputList)
2019 年 10 月 7 日更新,
现在可以使用 ES6 [...inputList].forEach
,或者Array.from(inputList)
回答by 2540625
Yay, ES6:
是的,ES6:
const children = [...parent.getElementsByTagName('tag')];
children.forEach((child) => { /* Do something; */ });
回答by grape_mao
Because input
is not an array, it's HTMLCollection
Use a for
loop would be better.
因为input
不是数组,所以HTMLCollection
使用for
循环会更好。
And since HTMLCollection
s are array-like objects you can call
Array#forEach
on it like this
由于HTMLCollection
s 是类似数组的对象,因此您可以像这样call
Array#forEach
Array.prototype.forEach.call(input, ShowResults);
回答by CertainPerformance
getElementsByTagName
returns an HTMLCollection
, which do not have a forEach
method. But, there's a simple tweak that will allow you to iterate with forEach
withoutcreating an intermediate array: use querySelectorAll
instead. querySelectorAll
returns a NodeList
, and modern browsers have a NodeList.prototype.forEach
method:
getElementsByTagName
返回一个HTMLCollection
,它没有forEach
方法。但是,有一个简单的调整可以让您在forEach
不创建中间数组的情况下进行迭代:querySelectorAll
改为使用。querySelectorAll
返回 a NodeList
,现代浏览器有一个NodeList.prototype.forEach
方法:
document.querySelectorAll('input')
.forEach((input) => {
console.log(input.value);
});
<input type="text" value="foo">
<input type="text" value="bar">
Another benefit to using querySelectorAll
is that it accepts comma-separated query strings, which are far more flexible and precise than just tag names. For example, the query string
使用的另一个好处querySelectorAll
是它接受逗号分隔的查询字符串,这比仅标记名称灵活和精确得多。例如,查询字符串
.container1 > span, .container2 > span
will only match span
s which are children of elements with a class of container1
or container2
:
将只匹配span
属于container1
或类元素的子元素的 s 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>
If you want to use NodeList.prototype.forEach
on ancient browsers that do not have the method built-in, simply add a polyfill. The following snippet will work on IE11:
如果你想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>
回答by Daniel Dykszak
It's becauseinput is html collection. html collection don't have forEach.
这是因为input是html集合。html 集合没有 forEach。
you can easily conver it to array by Array.prototype.slice
您可以通过 Array.prototype.slice 轻松将其转换为数组
example:
例子:
function ShowResults(value, index, ar) {
alert(index);
}
var input = document.getElementsByTagName("input");
alert(input.length);
input = Array.prototype.slice.call(input)
input.forEach(ShowResults);
回答by Naman Sancheti
The reason, this does not work is because 'getElementsByTagName' returns an array - like Object rather than an actual array. In case you are not aware, here's how both of them look like :-
原因,这不起作用是因为“ getElementsByTagName”返回一个数组 - 像 Object 而不是实际的数组。如果您不知道,以下是它们的外观:-
var realArray = ['a', 'b', 'c'];
var arrayLike = {
0: 'a',
1: 'b',
2: 'c',
length: 3
};
Thus, since Array-like objects inherit from 'Object.prototype' instead of 'Array.prototype', this means that Array-like Objects can't access common Array prototype methods like forEach(), push(), map(), filter(), and slice().
因此,由于类数组对象继承自“ Object.prototype”而不是“ Array.prototype”,这意味着类数组对象无法访问常见的数组原型方法,如 forEach()、push()、map()、过滤器()和切片()。
Hope that helps!
希望有帮助!
回答by Andrés Torres
HTMLCollections doesn't have the same methods as arrays. You can check this thing by tiping this in the javascript console of your browser.
HTMLCollections 没有与数组相同的方法。您可以通过在浏览器的 javascript 控制台中提示此内容来检查此内容。
var elements = document.getElementsByClassName('some-class');
'forEach' in elements;
And the console will return true
if elements
(in this case) has a method called forEach
to call.
true
如果elements
(在这种情况下)有一个被forEach
调用的方法,控制台将返回。
回答by inostia
In ES6 you can use the spread
operator to convert an HtmlCollection to an Array. see this question Why can't I use Array.forEach on a collection of Javascript elements?
在 ES6 中,您可以使用spread
运算符将 HtmlCollection 转换为数组。看到这个问题为什么我不能在 Javascript 元素集合上使用 Array.forEach?
input = [...input]
input.forEach(ShowResults)
回答by António Almeida
I did this:
我这样做了:
HTMLCollection.prototype.map = Array.prototype.map;
You can now use map on every HTMLCollection
.
您现在可以在每个HTMLCollection
.
document.getElementsByTagName("input").map(
input => console.log(input)
);
回答by thakis
If you can use ES2015, you can use Array.from()
to convert the HTMLCollection
returned by getElementsByTagName()
into a real array. If you change line 11 to the following, the rest of the code works as-is:
如果可以使用 ES2015,则可以使用Array.from()
将HTMLCollection
返回的 bygetElementsByTagName()
转换为真正的数组。如果将第 11 行更改为以下内容,则其余代码按原样运行:
var input = Array.from(document.getElementsByTagName("input"));