如何使用document.querySelectorAll遍历所选元素

Had*_*our 47 html javascript

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

例如,我使用:

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

输出:

<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()
Run Code Online (Sandbox Code Playgroud)

我的问题是,最后这个方法返回3个额外的项目.我该怎么做呢?

dur*_*uri 40

for in对于数组和类似数组的对象,不推荐使用循环 - 你明白为什么.可以有不仅仅是数字索引的项目,例如length属性或某些方法,但for in会循环遍历所有这些项目.使用其中之一

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

要么

for (var i = 0, element; element = checkboxes[i]; i++) {
    //work with element
}
Run Code Online (Sandbox Code Playgroud)

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

  • 现代更新:ES6 引入了额外的可能性(`for of`、`[...spread]`、...),并且 ES5 `[].forEach(...)` hack 确实继续有效,超越了现代浏览器(请参阅另一个在这里回答)**所有**支持`NodeList.forEach`。 (3认同)

Jak*_*k S 23

一个不错的选择是:

[].forEach.call(
    document.querySelectorAll('.check'),
    function (el) {
        console.log(el);
    }
);
Run Code Online (Sandbox Code Playgroud)

但正如所指出的,你应该使用for循环.

  • 关于这种方法的有趣帖子:http://toddmotto.com/ditch-the-array-foreach-call-nodelist-hack/ (4认同)
  • 如果采用这种方法,最好先执行`querySelectorAll`并将结果传递给`forEach`循环(例如``var elements = document.querySelectorAll('.check'); [].forEach.call(元素,...);`).否则,您最终会在循环的每次迭代中不必要地反复进行相同的DOM查询. (3认同)
  • 不幸的是,开销不仅仅是使用for循环,而是一个简洁的解决方案. (2认同)

Tho*_*ran 22

我最喜欢使用spread运算符将其转换为数组,然后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

});
Run Code Online (Sandbox Code Playgroud)

我在ES2015中编码并使用Babel.js,因此不应该存在浏览器支持问题.

  • 这是一个现代的答案。 (2认同)
  • 打字稿显示错误'Type'NodeListOf &lt;Element&gt;'不是数组类型' (2认同)

Abd*_*UMI 15

使用ES6,有一种静态方法Array.from可以利用Array非静态方法(forEach,map,filter,..):

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

     // handle "element"

});
Run Code Online (Sandbox Code Playgroud)

另外,使用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);
});
Run Code Online (Sandbox Code Playgroud)

  • @vsync,您不需要包装“.forEach”,但如果您想使用其他数组方法,如“.map”或“.filter”,则需要包装,因为“.querySelectorAll”返回“NodeList”,而不是“数组`. 如果我想确保我正在使用数组并希望保持数据/API 调用一致,我会选择这种方法。 (3认同)
  • 但是你可以只做`document.querySelectorAll('div').forEach(item =&gt; console.log(item))`......为什么你需要用`Array.from`包装它? (2认同)
  • @塞勒姆。是的,看起来“document.querySelectorAll”存储了一个nodeList,我们将其发送到“Array.forEach”方法。在一行中,我们获取了 nodeList,将其解构为一个数组,并将其发送到 forEach 方法。 (2认同)

abo*_*ron 14

看起来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));
Run Code Online (Sandbox Code Playgroud)
<p>paragraph 1</p>
<p>paragraph 2</p>
<p>paragraph 3</p>
<p>paragraph 4</p>
<p>paragraph 5</p>
Run Code Online (Sandbox Code Playgroud)

  • 到了 2023 年,我相信这是正确的做法。不需要展开、`Array.from` 或 `for in` (3认同)
  • 或 `[...document.querySelectorAll('p')].forEach(p =&gt; console.log(p));` (2认同)

jas*_*ard 6

主要要点:

类型很重要。

.map不会直接在 a 上工作NodeList,但会在Array.

比较这些: Array.prototype.map() NodeList.forEach()

选项:

ES6可用吗?

  1. [...element_list]那么展开算子Array.map()
  2. Array.from()在一个NodeList.forEach()

ES6 不可用?

  1. NodeList.forEach()
  2. 一个for循环”


小智 6

// for class
for (const elem of document.querySelectorAll('[class=".check"]')){
    //work as per usual
};

// for name
for (const elem of document.querySelectorAll('[name="check"]')){
    //work as per usual
};

// for id
for (const elem of document.querySelectorAll('[id="check-1"]')){
    //work as per usual
};
Run Code Online (Sandbox Code Playgroud)

这让我可以灵活地选择要使用的元素。

  • 你的第一个例子行不通。值“.check”不会匹配任何内容,只会匹配具有该确切值的类属性(不匹配其他类)。它应该只是“querySelectorAll('.check')”。 (2认同)