【问题标题】:for of loop querySelectorAllfor 循环 querySelectorAll
【发布时间】:2015-08-30 10:11:22
【问题描述】:

Mozilla 声明“for of 循环将正确地遍历 NodeList 对象”。 (来源:https://developer.mozilla.org/en-US/docs/Web/API/NodeList)但是,这在 Chrome 43 中不起作用。这是不正确的文档还是浏览器错误?

在带有复选框的页面上使用的复制示例代码:

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

【问题讨论】:

  • 我们可以再了解一些上下文吗?你能给我们举个例子吗?
  • 我想知道在 Chrome 中究竟有什么问题。它会引发语法错误吗?它不检查任何复选框吗?
  • for..of loops 仅支持 implemented as iterators 的对象,其中包含 Symbol.iterator 键/方法。目前,在 Chrome 中,console.log(Symbol.iterator in list); // false
  • @Xufox 它抛出“Uncaught TypeError: undefined is not a function”

标签: javascript google-chrome for-loop mozilla selectors-api


【解决方案1】:

编辑:This is shipping in Chrome 51

Jake Archibald posted a simple fix:

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

And for of 循环。

【讨论】:

  • 同样适用于HTMLCollection等其他人。
【解决方案2】:

文档是正确的,但我不会将此称为错误。相反,它是一个“尚未实现的功能”。

这方面没有标准,关于 DOM 应该如何与 ES6 集成的讨论仍然很活跃。请注意,很明显 querySelectorAll 应该返回可以在 for of 循环中使用的可迭代的东西(如常见的期望要求),但不清楚 如何这应该发生(让NodeList实现Iterable接口?让一些Elements collection子类Array?)。

【讨论】:

    【解决方案3】:

    你可以使用Array.from

    let _list = document.querySelectorAll('input[type=checkbox]');
    
    let list = Array.from(_list);
    
    for (let item of list) {
      //... just like an array
      item.checked = true
    }
    

    或更多时间

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

    重要提示 Array.from 是在 Chrome 45 中引入的 source

    【讨论】:

    • 这样更好吗?每次都需要调用 Array.from。
    • 是的,您确实必须每次都调用Array.from(并且可能为此包含一个polyfill),但是使用这种方法您并没有尝试扩展DOM。
    • 这与扩展 DOM 有什么关系?
    【解决方案4】:

    由于我在 Gecko 中成功使用 for..of 迭代 NodeLists,看来这是一个浏览器错误,或者至少是浏览器缺乏。

    我目前使用的用户脚本的实际工作代码:

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

    (这也使用let,但这是另一回事。)

    【讨论】:

      【解决方案5】:

      尝试使用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" />

      你也可以使用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" />

      【讨论】:

        【解决方案6】:

        这是现代的另一种解决方案:

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

        这利用了在 Google Chrome 46+、Firefox 16+ 和 Edge 中受支持的 spread operator,而 arrow function 只是为了好玩。

        【讨论】:

        • 重构数组的目的是什么?
        • querySelectorAll 的结果是一个 NodeList,而不是一个数组。通过转换它,我们可以轻松地对其进行迭代。
        • 现在有什么不同?它们都是可迭代的。
        • 正如其他答案所指出的,除非您将 Array 的迭代器分配给 NodeList,否则某些浏览器会给您带来问题(因此您的原始问题)。我只是提供了另一种干净的语法方式来进行forEach 迭代,而不是使用fromcall
        【解决方案7】:

        这就是我所做的,换一种方法

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

        IE9 及以上版本良好

        【讨论】:

          【解决方案8】:

          2014 年对 NodeList 的原生 Symbol.iterator 支持从 added 变为 WHATWG's DOM spec

          不幸的是,Chrome 51 是第一个支持它的 Chrome 版本,在撰写此答案时,它的 Beta 版才刚刚发布。此外,任何版本的 Internet Explorer 或 Edge 都不支持。

          要在所有浏览器中将Symbol.iteratorNodeList 的支持添加到您的代码中,只需使用以下polyfill:

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

          【讨论】:

            【解决方案9】:

            我遇到了这个问题。原来我是由使用参数而不是数组调用 Promise.all() 引起的。例如:

            之前:Promise.all(p1, p2)

            之后:Promise.all([p1, p2])

            希望这对某人有所帮助。

            【讨论】:

            • 这和NodeList有什么关系?
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-06-13
            • 1970-01-01
            • 2020-07-10
            • 2011-10-18
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多