2011-10-13 28 views
7

我想墊片Element.prototype.children它應該會返回一個HTMLCollection創建的HTMLCollection

有一個window.HTMLCollection

然而

var h = new HTMLCollection(); 
//TypeErrror: HTMLCollection is not a constructor 

var h = Object.create(HTMLCollection.prototype); 
h[0] = div; 
h.item(0); 
// Could not convert JavaScript argument 

測試火狐7 Chrome

除了墊片HTMLCollection有什麼方法可以與它進行交互?

還提供this github issue反饋,如果你能提出一個解決方案

+0

我相信這樣做的正確方法是定義自己的自定義'MyHTMLCollection'構造函數,然後用它來代替主機構造函數'HTMLCollection'(這是不可靠的) –

+0

雖然我無法回答你的具體問題HTMLCollection,擴展原生DOM(託管)對象通常被認爲是不好的做法。看到這篇文章的詳細解釋爲什麼:http://perfectionkills.com/whats-wrong-with-extending-the-dom/ – skyline3000

+0

@ skyline3000我完全知道後果。我們需要這樣做來生成DOM墊片。我們沒有使用自定義方法(邪惡)來擴展DOM,而是使用應該按照DOM4規範存在的方法 – Raynos

回答

4

這是我會怎麼做:

function MyHTMLCollection(arr) { 
    for (var i = 0; i < arr.length; i += 1) { 
     this[i] = arr[i]; 
    } 

    // length is readonly 
    Object.defineProperty(this, 'length', { 
     get: function() { 
      return arr.length; 
     } 
    }); 

    // a HTMLCollection is immutable 
    Object.freeze(this); 
} 

MyHTMLCollection.prototype = { 
    item: function (i) { 
     return this[i] != null ? this[i] : null; 
    }, 
    namedItem: function (name) { 
     for (var i = 0; i < this.length; i += 1) { 
      if (this[i].id === name || this[i].name === name) { 
       return this[i]; 
      } 
     } 
     return null; 
    } 
}; 

其中arr是包含所有這應該是的HTMLCollection內的DOM元素的規則陣列。

待辦事項:

  • 參數arr提前確認:它是一個數組?該數組DOM元素的所有元素?
+0

'instance [4] = newEl'怎麼樣? '長度'會失敗。我認爲你需要計算每次打電話時的長度。 – Raynos

+0

@Raynos我剛剛更新了我的答案。 'Object.freeze(this)'在構造函數中,但我不確定規範中關於HTML集合的不變性。我會檢查... –

+0

也'Object.defineProperty'只適用於IE8中的DOM,所以我的dom-shim剛剛在IE8中破解。我想我可以在IE8中將'length'屬性設置爲一個靜態值,然後忘掉它。 – Raynos

4

不要指望主機對象表現得像(ECMAScript的)原生對象,它們是完全不同的事情。一些瀏覽器確實實現了像ECMAScript對象一樣的DOM對象,但這不是必需的,也不應該依賴它。請注意,大多數HTML集合都是實時的,在本地對象中模擬它非常困難。

+1

。它們確實非常難以在沒有代理的情況下模擬。 – Raynos

0

我知道這是一個老問題,但我碰到類似的需要創建一個空的HTMLCollection來了,我簡單地創建一個元素,然後使用一個類不存在運行getElementsByClassName方法()反對做到了在元素中。

document.createElement("div").getElementsByClassName('noClassHere'); 

這將返回一個空的HTMLCollection對象。

相關問題