2017-09-05 88 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

相關問題