2017-09-05 446 views
0

随着ES6采取保留,我渴望放弃jQuery和使用本地JS为我的网站建设,保持他们的快速和轻量级。也是为了提高我的JS技能,因为我是jQuery中的一员。“对象不支持这个属性或方法”IE6/11

我正在构建一个小小的图书馆,以便在一个函数中使用更常见的JavaScript来保持文件的小。

function $(elm) { 
    var elm = document.querySelectorAll(elm); 

    this.forEach = function(f) { 
     [].forEach.call(elm, f); 
    } 

    return elm; 
} 

function slider() { 
    $(".slider").forEach(function() { 
     alert("Hello"); 
    }); 
} 
slider(); 

此作品在Chrome等伟大的..但在IE10/11,我发现了错误

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

指的是$(“。slider”)。for each

任何想法?

+0

*“...并使用原生JS”*不是原生JS。您正在使用JavaScript。原生** DOM **。 –

+0

可能的重复: https://stackoverflow.com/questions/412447/for-each-javascript-support-in-ie –

+0

[对于IE中每个JavaScript支持的可能的重复?](https://stackoverflow.com/questions/412447/for-each-javascript-support-in-ie) – jmargolisvt

回答

4

您正在将forEach添加到window对象,而不是您返回的对象;您将$作为函数调用,而不是构造函数。由于您使用宽松模式(显然),函数调用中的this是对全局对象的引用(在浏览器上也可以使用window访问)。您将从querySelectorAll收集的产品保持不变。

它在Chrome上工作的原因是由querySelectorAll返回的集合有它自己的forEach

对于这项工作,四个选项:

  1. 返回一个对象,并添加forEach它,复制从QSA集合到该对象的元素。例如: -

    function $(selector) { 
        const result = Array.from(document.querySelectorAll(selector)); 
        result.forEach = Array.prototype.forEach; 
        // Perhaps map, filter, etc.; add in a loop? 
        return result; 
    } 
    

    或者在ES5:

    var $ = (function() { 
        var methods = Array.prototype; 
        function $(selector) { 
         var result = methods.slice.call(document.querySelectorAll(selector)); 
         result.forEach = methods.forEach; 
         // Perhaps map, filter, etc.; add in a loop? 
         return result; 
        } 
        return $; 
    })(); 
    
  2. 添加forEachNodeList原型,如果它不是已经存在,并直接在收集使用forEachquerySelectorAll。例如:

    if (typeof NodeList !== "undefined" && 
        NodeList.prototype && 
        !NodeList.prototype.forEach) { 
        Object.defineProperty(NodeList.prototype, "forEach", { 
         value: Array.prototype.forEach 
        }); 
    } 
    

    ...然后当然你$变得无非

    function $(selector) { 
        return document.querySelectorAll(selector); 
    } 
    

    (首先如果你想添加更多的功能,你可能会想要去的。 #1的方式。)

  3. 返回数组:

    function $(selector) { 
        return Array.from(document.querySelectorAll(selector)); 
    } 
    

    或者在ES5:

    function $(selector) { 
        return Array.prototype.slice.call(document.querySelectorAll(selector)); 
    } 
    
  4. 子类Array(不能在预ES2015 JavaScript引擎完美polyfilled),这样你可以添加自己的Array的功能:

    class MyThingy extends Array { 
        // Perhaps further methods here 
    } 
    function $(selector) { 
        return MyThingy.from(document.querySelectorAll(selector)); 
    } 
    

    这里没有ES5选项,您至少需要进行transpile和polyfill。

如果您要添加超出Array提供这些功能,我很喜欢#4比仅是“如此”好polyfilling等。你的目的可能就足够了。

+0

1.看起来很不错,但是它在IE10中不起作用,使用const给出语法错误,使用var给对象不支持方法“from” – Tom

+0

@Tom:如果您要为IE10编写代码,则需要将自己转换或限制为ES5语法。我从你的开头句子中假定你正在使用ES2015 +(必要时采用转运和填充)。 –

+0

我想我最少要支持IE11。我应该看哪个polyfill? – Tom

相关问题