当前位置: 首页 > 面试题库 >

querySelectorAll上的forEach在最新的Microsoft浏览器中不起作用

段干宜
2023-03-14
问题内容

我正在编写用于选择产品(颜色等)的脚本,该脚本可在除 Internet Explorer (11)和 Edge 之外的所有浏览器中使用。

我将每个参数的选择放入数组中,并使用方法将函数应用于它们array.forEach()

color参数的示例:

var color_btns = document.querySelectorAll('#color > p');
color_btns.forEach(function(color) {
    color.onclick = function () {
        color_btns.forEach(function(element) {
            if (element.classList.contains('selected')) {
                element.classList.remove('selected');
            }
        });
        color.classList.add('selected');
        document.querySelector('#f_color').value = color.dataset.id;
    };
});

我在 IEEdge 的控制台中都得到以下输出:

对象不支持属性或方法“ forEach”

搜索该问题后,我了解到IE9和更高版本应支持此功能。我尝试自己定义功能,但没有成功。当我登录该函数时,它被定义为一个函数([native code]内部带有“ ”)。

我用.forEacha 替换了每个,for效果很好,

  • 但是我如何使它工作呢?
  • 有没有的特定用途forEach()互联网浏览器边缘

我以为是Array.prototype.forEach这样,而IE的最新版本(以及Edge的所有版本)都拥有它…?


问题答案:

返回值[querySelectorAll不是数组,而是NodeList。直到最近才有了forEach(并且与JavaScript的迭代协议兼容,让您将它们用作for-of和表示法的目标)。

您可以forEach轻松地填充:

if (typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype.forEach) {
    // Yes, there's really no need for `Object.defineProperty` here
    NodeList.prototype.forEach = Array.prototype.forEach;
}

直接分配在这种情况下细,因为enumerableconfigurablewritable都应该true和它的价值属性。(enumerabletrue让我感到惊讶,但这是它是如何定义本身在Chrome,火狐,边缘和Safari)。

NodeListforEach,这也成了 迭代 ,这意味着你可以通过一个内容循环NodeList通过for- of回路,并使用NodeList(在数组初始化比如,在传播符号)在其他地方可迭代的预期。

在实践中,具有使用可迭代性的功能(例如for-of循环)的浏览器也可能已经提供的这些功能NodeList,但是要确保(也许您正在转码并包括的polyfillSymbol),我们需要再做一遍。事情:在其Symbol.iterator属性中添加一个函数以创建迭代器:

if (typeof Symbol !== "undefined" && Symbol.iterator && typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype[Symbol.iterator]) {
    Object.defineProperty(NodeList.prototype, Symbol.iterator, {
        value: Array.prototype[Symbol.itereator],
        writable: true,
        configurable: true
    });
}

一起做:

if (typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype.forEach) {
    // Yes, there's really no need for `Object.defineProperty` here
    NodeList.prototype.forEach = Array.prototype.forEach;
    if (typeof Symbol !== "undefined" && Symbol.iterator && !NodeList.prototype[Symbol.iterator]) {
        Object.defineProperty(NodeList.prototype, Symbol.iterator, {
            value: Array.prototype[Symbol.itereator],
            writable: true,
            configurable: true
        });
    }
}

这是一个同时使用两者的实时示例,请在IE11上尝试此操作(尽管它只会演示forEach),但它NodeList本身没有这些功能:

// Using only ES5 features so this runs on IE11

function log() {

    if (typeof console !== "undefined" && console.log) {

        console.log.apply(console, arguments);

    }

}

if (typeof NodeList !== "undefined" && NodeList.prototype) {

    // forEach

    if (!NodeList.prototype.forEach) {

        // Yes, there's really no need for `Object.defineProperty` here

        console.log("Added forEach");

        NodeList.prototype.forEach = Array.prototype.forEach;

    }

    // Iterability

    if (typeof Symbol !== "undefined" && Symbol.iterator && !NodeList.prototype[Symbol.iterator]) {

        console.log("Added Symbol.iterator");

        Object.defineProperty(NodeList.prototype, Symbol.iterator, {

            value: Array.prototype[Symbol.itereator],

            writable: true,

            configurable: true

        });

    }

}



log("Testing forEach");

document.querySelectorAll(".container div").forEach(function(div) {

    var html = div.innerHTML;

    div.innerHTML = html[0].toUpperCase() + html.substring(1).toLowerCase();

});



// Iterable

if (typeof Symbol !== "undefined" && Symbol.iterator) {

    // Using eval here to avoid causing syntax errors on IE11

    log("Testing iterability");

    eval(

        'for (const div of document.querySelectorAll(".container div")) { ' +

        '    div.style.color = "blue"; ' +

        '}'

    );

}


<div class="container">

  <div>one</div>

  <div>two</div>

  <div>three</div>

  <div>four</div>

</div>

HTMLCollection由归国getElementsByTagName(以及各种其他旧的API)没有被定义为可迭代的,但如果你喜欢,你也可以做到这一点的HTMLCollection为好。这是一个执行botyNodeList(如果需要)和HTMLCollection(如果需要)的循环:

for (const ctor of [typeof NodeList !== "undefined" && NodeList, typeof HTMLCollection !== "undefined" && HTMLCollection]) {
    if (ctor && ctor.prototype && !ctor.prototype.forEach) {
        // (Yes, there's really no need for `Object.defineProperty` here)
        ctor.prototype.forEach = Array.prototype.forEach;
        if (typeof Symbol !== "undefined" && Symbol.iterator && !ctor.prototype[Symbol.iterator]) {
            Object.defineProperty(ctor.prototype, Symbol.iterator, {
                value: Array.prototype[Symbol.itereator],
                writable: true,
                configurable: true
            });
        }
    }
}

请注意,这HTMLCollection是实时的,因此您对DOM进行的更改(影响集合中的内容)会立即反映在集合中,这可能会导致令人惊讶的行为。(NodeList是一个断开连接的集合,因此不会发生行为。)



 类似资料:
  • 我正在制作一个关于产品(颜色等)选择的脚本,它可以在除Internet Explorer(11)&Edge之外的所有浏览器中工作。 color参数的示例: 我在IE和Edge的控制台中得到以下输出: 对象不支持属性或方法“for each” null

  • 我正试图通过C#最小化Microsoft Edge浏览器。除了微软Edge之外,其他浏览器如Chrome、Firefox、Internet Explorer都运行良好。 有人能帮帮我吗。

  • 问题内容: 我在使用SWT浏览器组件时遇到了一些麻烦。我正在运行带有Sun的Java SE 1.6的Ubuntu 11.04 AMD64和Eclipse 3.7 我的问题是我的浏览器无法初始化。当我使用SWT.NONE标志实现时,出现错误 然后当我尝试使用SWT.MOZILLA标志时,我得到 我怀疑这部分是因为我正在使用XULRunner2,但是我更喜欢使用WebKit,在Eclipse 3.7中

  • 问题内容: 我的HTML文件中有这个: 这在CSS文件中: Firefox在Firebug中返回CSS错误。难道我做错了什么? 按照W3C规范的功能,它应该工作。 问题答案: 查看规范中给出的语法: 似乎需要删除属性名称和要使用的单位之间的逗号: 但是,即使您使用正确的语法,也不会起作用。事实证明,截至 3的级别3版本没有已知的实现 2012年 … 2020年。更糟糕的是,截至最新的规范编辑草案仍

  • 问题内容: 我尝试使用以下代码将必填字段告知必填字段,但在Safari浏览器中不起作用。码: 上面的代码在firefox中工作。 您可以让我知道JavaScript代码或任何workarround吗? 是javascript新功能 谢谢 问题答案: Safari(自2017年3月26日起最新版本10.1)不支持此属性,您需要使用JavaScript。 该页面包含一个hacky解决方案,该解决方案应

  • 问题内容: alert(myVar1); return false; var myVar1; 上面的代码在IE,FF和Opera中引发错误,表明return语句必须包含在函数中。但它可以在Safari和Chrome中运行(显示)。 以上代码已在全局范围内编写。以外的所有功能。 任何原因? 问题答案: 在javaScript中,将变量移到脚本顶部,然后运行。所以当你运行它会做 这是因为javascr