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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 15:10:33  来源:igfitidea点击:

How to loop through all the elements returned from getElementsByTagName

javascriptarraysforeachgetelementsbytagname

提问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; */ });

MDN Doc for Spread Operator (...)

扩展运算符的 MDN 文档 ( ...)

回答by grape_mao

Because inputis not an array, it's HTMLCollectionUse a forloop would be better.

因为input不是数组,所以HTMLCollection使用for循环会更好。

And since HTMLCollections are array-like objects you can callArray#forEachon it like this

由于HTMLCollections 是类似数组的对象,因此您可以像这样callArray#forEach

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

回答by CertainPerformance

getElementsByTagNamereturns an HTMLCollection, which do not have a forEachmethod. But, there's a simple tweak that will allow you to iterate with forEachwithoutcreating an intermediate array: use querySelectorAllinstead. querySelectorAllreturns a NodeList, and modern browsers have a NodeList.prototype.forEachmethod:

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 querySelectorAllis 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 spans which are children of elements with a class of container1or 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.forEachon 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);

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

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

回答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 trueif elements(in this case) has a method called forEachto call.

true如果elements(在这种情况下)有一个被forEach调用的方法,控制台将返回。

回答by inostia

In ES6 you can use the spreadoperator 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 HTMLCollectionreturned 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"));