我在控制台上运行此代码段。在IE中,它按预期产生输出。在Cr和FF中运行相同的参考确认了行为的一致性。
["a", "b"].forEach(function(element) {
console.log(element);
});
然而,当运行以下脚本时,我收到错误,告诉我该对象没有在其上声明 forEach(...)。问题发生在IE中,但不是在Cr和FF中。
var menus = document.querySelectorAll("ul.application>li>a");
menus.forEach(function(element) { ... }
我已经检查过变量 menus 已经被声明,并且选择它的元素会产生我所期望的,即 menus [0] 存在并且是一个标记。与其他人相比,它在IE中看起来有点不同,但它可能只是不同的再现。
我很幸运能与Cr和FF合作,所以我处理IE的经验有限。谷歌搜索并没有给我太多智慧。
如何进一步排查?
答案 0 :(得分:6)
基本上document.querySelectorAll
会返回一个nodeList
数组,就像对象而不是数组一样。在调用数组函数之前,必须将其转换为数组。
var menus = document.querySelectorAll("ul.application>li>a");
menus = [].slice.call(menus);
menus.forEach(function(element) { ... });
如果您的环境支持ES6,则可以使用Array.from()
var menus = document.querySelectorAll("ul.application>li>a");
menus = Array.from(menus);
menus.forEach(function(element) { ... });
答案 1 :(得分:3)
这不是浏览器的问题,更像是使用querySelectorAll
获得类似对象的数组。它返回一个NodeList
,它是可迭代的,但不是直接使用数组方法。
但你可以从Array.prototype
借用这个方法,就像这个
Array.prototype.forEach.call(menu, function(element) { /* ... */ });
如果您想获得第一个真正的数组,可以使用
进行转换array = Array.apply(null, menu);
答案 2 :(得分:1)
来晚了,但是如果有人遇到相同的问题并且不想/不能用[].forEach.call(elements, fn(el))
替换所有的forEach方法,这可能会很有用。这是适用于ie11的polyfill
if (! Object.getOwnPropertyDescriptor(NodeList.prototype, 'forEach')) {
Object.defineProperty(NodeList.prototype, 'forEach', Object.getOwnPropertyDescriptor(Array.prototype, 'forEach'));
}
答案 3 :(得分:1)
最好的解决方案是在开头添加一行:
window.NodeList && !NodeList.prototype.forEach && (NodeList.prototype.forEach = Array.prototype.forEach) // make IE support forEach
之后,您就可以像在其他普通浏览器中一样在 IE 中使用 forEach。