如何使用 document.querySelectorAll 循环选择元素

IT技术 javascript html
2021-02-07 02:53:30

我正在尝试对使用 document.querySelectorAll 查询的选定元素进行循环,但是如何进行?

例如我使用:

var checkboxes = document.querySelectorAll('.check');
for( i in checkboxes) {
  console.log(checkboxes[i]);
}

输出:

<input id="check-1" class="check" type="checkbox" name="check">
<input id="check-2" class="check" type="checkbox" name="check">
<input id="check-3" class="check" type="checkbox" name="check">
<input id="check-4" class="check" type="checkbox" name="check">
<input id="check-5" class="check" type="checkbox" name="check">
<input id="check-6" class="check" type="checkbox" name="check">
<input id="check-7" class="check" type="checkbox" name="check">
<input id="check-8" class="check" type="checkbox" name="check">
<input id="check-9" class="check" type="checkbox" name="check">
<input id="check-10" class="check" type="checkbox" name="check" checked="">

10
item()
namedItem()

我的问题是最后这个方法返回 3 个额外的项目。我怎样才能正确地做到这一点?

6个回答

for in不建议将循环用于数组和类似数组的对象——你明白为什么了。可以有不仅仅是数字索引的项目,例如length属性或某些方法,但for in会循环遍历所有这些项目。使用任一

for (var i = 0, len = checkboxes.length; i < len; i++) {
    //work with checkboxes[i]
}

或者

for (var i = 0, element; element = checkboxes[i]; i++) {
    //work with element
}

如果数组中的某些元素可能是错误的(不是你的情况),则不能使用第二种方法,但可以更易读,因为你不需要在[]任何地方使用符号。

现代更新:ES6 引入了额外的可能性(for of、、[...spread]……),并且 ES5 [].forEach(…)hack 确实继续工作,超越现代浏览器(在此处查看另一个答案)所有支持NodeList.forEach.
2021-03-24 02:53:30

我最喜欢的是使用扩展运算符将其转换为数组,然后forEach用于循环。

var div_list = document.querySelectorAll('div'); // returns NodeList
var div_array = [...div_list]; // converts NodeList to Array
div_array.forEach(div => {

// do something awesome with each div

});

我在 ES2015 中编码并使用 Babel.js,所以不应该有浏览器支持问题。

typescript显示错误 Type 'NodeListOf<Element>' is not an array type
2021-03-25 02:53:30
这是一个现代的答案。
2021-03-27 02:53:30

看起来Firefox 50+、Chrome 51+ 和Safari 10+ 现在都支持对象.forEach功能NodeList注意— .forEachInternet Explorer 不支持,因此请考虑上述方法之一,或者如果需要 IE 支持,请使用 polyfill。

https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach

const paragraphs = document.querySelectorAll('p');
paragraphs.forEach(p => console.log(p));
<p>paragraph 1</p>
<p>paragraph 2</p>
<p>paragraph 3</p>
<p>paragraph 4</p>
<p>paragraph 5</p>

一个不错的选择是:

[].forEach.call(
    document.querySelectorAll('.check'),
    function (el) {
        console.log(el);
    }
);

但正如所指出的,您应该使用 for 循环。

2021-03-13 02:53:30
如果采用这种方法,最好执行querySelectorAll之前并将结果传递到forEach循环中(例如var elements = document.querySelectorAll('.check'); [].forEach.call(elements, ...);)。否则,您最终会在循环的每次迭代中一遍又一遍地重复进行相同的 DOM 查询。
2021-03-13 02:53:30
不幸的是,开销不仅仅是使用 for 循环,但它是一个巧妙的解决方案。
2021-04-10 02:53:30

ES6 中,有一个静态方法Array.from可以利用Array非静态方法(map、filter、...):

Array.from(document.querySelectorAll('div')).forEach((element,index) =>
{

     // handle "element"

});

另一个使用Array.fromquerySelector提供item方法:

var all = document.querySelectorAll('div');
// create range [0,1,2,....,all.length-1]
Array.from({length: all.length}, (v, k) => k).forEach((index) => {
     let element = all.item(index);
});
然后[...document.querySelectorAll('div')].forEach((element,index) => { // handle "element" });可以做到
2021-03-29 02:53:30
@vsync 你不需要包装 for .forEach,但是如果你想使用另一个 Array 方法,比如.mapor.filter因为.querySelectorAll返回 a NodeList,而不是Array如果我想确保使用数组并保持数据/API 调用的一致性,我会选择这种方法。
2021-04-06 02:53:30
但是你可以做document.querySelectorAll('div').forEach(item => console.log(item))......为什么你需要用它来包装它Array.from
2021-04-08 02:53:30