forEach 函数在最近的 Microsoft 浏览器中不起作用
在尝试为 Web 应用程序中的产品选择创建脚本时,开发人员遇到了Internet Explorer 11 和 Microsoft Edge 中出现错误。错误消息表明 forEach 函数不受支持,尽管据报道该函数在 IE9 及更高版本中可用。
探索问题
forEach 方法通常是用于迭代数组元素并对每个元素应用函数。在这种情况下,开发人员利用了从产品配置中选择颜色选项的方法。然而,经过调查,发现以下代码片段:
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; }; });
在 Internet Explorer 和 Microsoft Edge 中没有按预期运行,抛出错误,表明 forEach 函数不是 NodeList 的属性
问题原因
进一步研究发现,querySelectorAll 及类似方法返回的对象类型 NodeList 和 HTMLCollection 是不是真正的数组,而是可迭代的。在 JavaScript 中,可迭代对象是可以使用 for-of 循环、扩展运算符或解构赋值进行迭代的对象。
NodeList 对象最近获得了对 forEach 方法的支持,但 HTMLCollection 对象没有,也不期望支持它。这是由于向后兼容性问题,因为将 forEach 方法添加到 HTMLCollection 可能会破坏现有代码。
Polyfilling forEach
要解决此问题,建议polyfill NodeList 对象的 forEach 方法。 Polyfilling 涉及向本机不支持的对象添加方法。下面的代码片段可以为 NodeList 填充 forEach:
if (typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype.forEach) { NodeList.prototype.forEach = Array.prototype.forEach; }
直接赋值,如上面的代码所示,是可能的,因为 enumerable、configurable 和 writable 都应该为 true,并且它是一个 value 属性。
Polyfilling Iterability
此外,NodeList 对象也可以变得可迭代,以支持使用 for-of 循环和展开运算符对其进行迭代。这可以通过以下polyfill来实现:
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.iterator], writable: true, configurable: true }); }
使用Polyfill的示例
通过合并这些polyfill,可以修改原始代码以在所有支持的环境中无缝运行浏览器:
// Polyfilling forEach for NodeList if (typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype.forEach) { NodeList.prototype.forEach = Array.prototype.forEach; } // Polyfilling iterability for NodeList 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.iterator], writable: true, configurable: true }); } 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; }; });
此更新的代码片段应在所有浏览器中按预期运行,包括 Internet Explorer 和 Microsoft Edge。
以上是为什么 forEach 函数在 Internet Explorer 和 Microsoft Edge 中不起作用?的详细内容。更多信息请关注PHP中文网其他相关文章!