JavaScript:循环遍历从getElementsByTagName返回的所有元素

sla*_*oah 52 javascript arrays foreach 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>
Run Code Online (Sandbox Code Playgroud)

Dvi*_*vir 74

您需要将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>
Run Code Online (Sandbox Code Playgroud)

或用于循环.

for(i = 0;i < input.length; i++)
{
    ShowResults(input[i].value);
}
Run Code Online (Sandbox Code Playgroud)

并将ShowResults函数更改为:

function ShowResults(value) {
   alert(value);
}
Run Code Online (Sandbox Code Playgroud)


jth*_*ter 42

是的,ES6:

const children = [...parent.getElementsByTagName('tag')];
children.forEach((child) => { /* Do something; */ });
Run Code Online (Sandbox Code Playgroud)

传播运营商的MDN Doc(...)

  • 现在在ES6中,您可以将`forEach`用于NodeList,但不能用于HTMLCollection。getElementsByTagName返回HTMLCollection,而querySelectorAll返回NodeList。 (4认同)

gra*_*mao 8

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

因为HTMLCollections是类似于数组的对象,所以你可以像这样call Array#forEach

Array.prototype.forEach.call(input, ShowResults);
Run Code Online (Sandbox Code Playgroud)


Nam*_*eti 6

原因,这不起作用是因为“ getElementsByTagName ”返回一个数组 - 像 Object 而不是实际的数组。如果您不知道,以下是它们的外观:-

var realArray = ['a', 'b', 'c'];
var arrayLike = {
  0: 'a',
  1: 'b',
  2: 'c',
  length: 3
};
Run Code Online (Sandbox Code Playgroud)

因此,由于类数组对象继承自“ Object.prototype ”而不是“ Array.prototype ”,这意味着类数组对象无法访问常见的数组原型方法,如 forEach()、push()、map()、过滤器()和切片()。

希望有帮助!


tha*_*kis 6

如果你会使用ES2015,你可以使用将返回的值Array.from()转换为真正的数组。如果将第 11 行更改为以下内容,则其余代码将按原样运行:HTMLCollectiongetElementsByTagName()

var input = Array.from(document.getElementsByTagName("input"));
Run Code Online (Sandbox Code Playgroud)


Dan*_*zak 5

这是因为input是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);
Run Code Online (Sandbox Code Playgroud)

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


ino*_*tia 5

在 ES6 中,您可以使用spread运算符将​​ HtmlCollection 转换为数组。请参阅这个问题为什么我不能在 Javascript 元素集合上使用 Array.forEach?

input = [...input]
input.forEach(ShowResults)
Run Code Online (Sandbox Code Playgroud)


Cer*_*nce 5

getElementsByTagName返回HTMLCollection没有forEach方法的。但是,有一个简单的调整,可让您进行迭代而forEach 无需创建中间数组:请querySelectorAll改为使用。querySelectorAll返回NodeList,而现代浏览器具有以下NodeList.prototype.forEach方法:

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

使用的另一个好处querySelectorAll是它接受逗号分隔的查询字符串,这比仅标记名更灵活,更精确。例如,查询字符串

.container1 > span, .container2 > span
Run Code Online (Sandbox Code Playgroud)

将仅与span属于container1或类的元素的子元素的匹配container2

.container1 > span, .container2 > span
Run Code Online (Sandbox Code Playgroud)
document.querySelectorAll('.container1 > span, .container2 > span')
  .forEach((span) => {
    span.classList.add('highlight');
  });
Run Code Online (Sandbox Code Playgroud)
.highlight {
  background-color: yellow;
}
Run Code Online (Sandbox Code Playgroud)

如果要NodeList.prototype.forEach在没有内置方法的古老浏览器上使用,只需添加一个polyfill即可。以下代码段适用于IE11:

<div class="container1">
  <span>foo</span>
  <span>bar</span>
</div>
<div class="container2">
  <span>baz</span>
</div>
<div class="container3">
  <span>buzz</span>
</div>
Run Code Online (Sandbox Code Playgroud)
// 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');
  });
Run Code Online (Sandbox Code Playgroud)
.highlight {
  background-color: yellow;
}
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

64798 次

最近记录:

6 年,1 月 前