我正在使用在Wordpress网站中使用ES6的其他人编写的Javascript代码。它进行Ajax调用以显示DOM中的数据,该数据适用于Chrome和Firefox但由于某种原因,Safari在控制台中出现以下错误:
TypeError: document.querySelectorAll(".js_zip-lookup__submit").forEach is not a function. (In 'document.querySelectorAll(".js_zip-lookup__submit").forEach(function(e){e.addEventListener("click",function(){displayResults(e.parentNode.querySelector(".zip-lookup__input").value)})})', 'document.querySelectorAll(".js_zip-lookup__submit").forEach' is undefined)
这是功能:
function finderInit(){
document.querySelectorAll('.js_zip-lookup__submit').forEach(function(button){
button.addEventListener('click', function(){
const zip = button.parentNode.querySelector('.zip-lookup__input').value;
displayResults(zip);
});
});
document.querySelectorAll('.zip-lookup').forEach(function(form){
form.addEventListener('submit', function(e){
e.preventDefault();
const zip = form.querySelector('.zip-lookup__input').value;
displayResults(zip);
})
});
}
而且我无法解释为什么Safari会遇到这个问题,而Chrome / FF甚至无法在控制台中记录有关此特定部分的任何错误,而且工作正常。我知道它应该是一些浏览器兼容性问题,但到目前为止还没有找到很多信息。
答案 0 :(得分:2)
document.querySelectorAll
返回NodeList
个对象,而不是数组。由于can be seen on MDN,NodeList
有forEach
方法,但它不受支持,这就是为什么它适用于最近的Firefox和Chrome而不是其他浏览器(Safari):
虽然NodeList不是数组,但可以使用forEach()对其进行迭代。几个较旧的浏览器尚未实现此方法。
要以兼容的方式迭代节点列表和其他迭代器,应使用Array.from
(可以在旧浏览器中进行填充):
Array.from(document.querySelectorAll(".js_zip-lookup__submit")).forEach(...);
答案 1 :(得分:2)
我尝试了很多Array.prototype的变种,但唯一解决了IE& Safari兼容性问题是下面包含此polypill片段,解决方案位于this blog:
(function () {
if ( typeof NodeList.prototype.forEach === "function" ) return false;
NodeList.prototype.forEach = Array.prototype.forEach;
})();
答案 2 :(得分:0)
如@Estus所述,旧版本的Safari不会在nodelist对象上实现.forEach
。但是,Array.prototype.forEach
在ES5.1具体说明中定义为通用:
forEach函数是故意通用的;它不要求它的这个值是一个Array对象。因此,它可以转移到其他类型的对象以用作方法。 forEach函数是否可以成功应用于宿主对象是依赖于实现的。
因此,一个可行的解决方案是在节点列表上调用Array.prototype.forEach
并将其传递给您想要执行的函数。作为一个减少(和便宜)测试案例:
var col = document.getElementsByTagName("p");
//col.forEach( function (el) {document.write(el.id)});
Array.prototype.forEach.call(col, function (el) {document.write(el.id)});

<p id="p1"></p>
<p id="p2"></p>
<p id="p3"></p>
<p id="p4"></p>
&#13;
经过测试,发现它可以在Safari 5.1.7 for Windows和Internet下使用。 Explorer 9仿真。注释掉的行重现了Safarai 5.1.7中帖子中报告的错误。