Safari中的Javascript ES6 TypeError& IE

时间:2017-08-30 23:27:43

标签: javascript safari ecmascript-6 typeerror polyfills

我正在使用在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甚至无法在控制台中记录有关此特定部分的任何错误,而且工作正常。我知道它应该是一些浏览器兼容性问题,但到目前为止还没有找到很多信息。

3 个答案:

答案 0 :(得分:2)

document.querySelectorAll返回NodeList个对象,而不是数组。由于can be seen on MDNNodeListforEach方法,但它不受支持,这就是为什么它适用于最近的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.forEachES5.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;
&#13;
&#13;

经过测试,发现它可以在Safari 5.1.7 for Windows和Internet下使用。 Explorer 9仿真。注释掉的行重现了Safarai 5.1.7中帖子中报告的错误。