for of loop querySelectorAll

2019-01-19 14:57发布

Mozilla states that "for of loops will loop over NodeList objects correctly". (source: https://developer.mozilla.org/en-US/docs/Web/API/NodeList) However, this doesn't work in Chrome 43. Is this incorrect documentation or a browser bug?

The copied example code used on a page with checkboxes:

var list = document.querySelectorAll( 'input[type=checkbox]' );
for (var item of list) {
  item.checked = true;
}

9条回答
何必那么认真
2楼-- · 2019-01-19 15:03

Since I've successfully used for..of in Gecko to iterate NodeLists, it seems this is a browser bug, or at least a browser lack.

Actual working code from a userscript I currently use:

let llnk = document.querySelectorAll("div#threadlist a.threadtitle_unread");
for (let lnk of llnk) {
    //...
}

(This also uses let, but that's another story.)

查看更多
霸刀☆藐视天下
3楼-- · 2019-01-19 15:04

This is what I do, for a different approach

Array.prototype.forEach.call(document.querySelectorAll("input[type=checkbox]"),function(ele,idx)
{
    ele.checked = true;
}

good from IE9 and above

查看更多
姐就是有狂的资本
4楼-- · 2019-01-19 15:06

The docs are correct, but I wouldn't call this a bug. Rather it's a "not yet implemented feature".

There is no standard for this, and there is still active discussion on how the DOM should integrate with ES6. Notice that it is clear that querySelectorAll should return something iterable which can be used in a for of loop (as the common expectation demands), but it's not clear how that should happen (Let NodeList implement the Iterable interface? Let some Elements collection subclass Array?).

查看更多
何必那么认真
5楼-- · 2019-01-19 15:06

Try utilizing Array.prototype.entries()

var list = [].entries.call(document.querySelectorAll("input[type=checkbox]"));

for (item of list) {
  item[1].checked = true;
};
<input type="checkbox" /><input type="checkbox" />

You could also use Array.prototype.values()

var list = [].values.call(document.querySelectorAll("input[type=checkbox]"));

for (item of list) {
  item.checked = true;
};
<input type="checkbox" /><input type="checkbox" />

查看更多
\"骚年 ilove
6楼-- · 2019-01-19 15:07

Here's yet another solution for the modern age:

[...document.querySelectorAll("input[type=checkbox]")].forEach(node => {
     node.textContent = "foo";
});

This takes advantage of the spread operator which is supported in Google Chrome 46+, Firefox 16+, and Edge, and just for fun the arrow function.

查看更多
Emotional °昔
7楼-- · 2019-01-19 15:09

Edit: This is shipping in Chrome 51.

Jake Archibald posted a simple fix:

NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator]

And for of loops.

查看更多
登录 后发表回答