2010-12-29 16 views
7

Mam twardy czas konwersji NodeList do tablicy w IE 8. Następujące prace doskonale w Chrome, ale w IE 8 toArray() nie jest uznany za ważny:Konwersja NodeList do tablicy

NodeList.prototype.toArray = function() { 
    var a = []; 

    for (var i = 0, len = this.length; i < len; i++) { 
     a[i] = this[i]; 
    } 

    return a; 
} 

document.all.tags("div").toArray(); 

I próbowałem dodać funkcję prototypu do tablicy tylko po to, aby sprawdzić moje zdrowie psychiczne i działa poprawnie. To sprawia, że ​​myślę, że IE 8 faktycznie nie zwraca NodeList? Oto pełny przykład:

http://jsfiddle.net/e4RbH/

Co robię źle?

+1

Nie ma obecnie standardem, który mówi, że 'NodeList' musi być widoczny i dowolnie zmieniana funkcja konstruktor, lub że jeśli istnieje funkcja konstruktora widoczna jako 'NodeList', która będzie używana jako typ zwracany przez wszystkie metody zwracania węzła. (W końcu, węzeł 'childNodes' NodeList i' getElementsByTagName' NodeList robią bardzo różne rzeczy.) Prototypowanie do natywnych obiektów JS jest określone przez standard ECMAScript i jest niezawodne; prototypowanie do węzłów DOM i innych obiektów nie zdefiniowanych przez standard językowy jest niewiarygodne i powinno się ich unikać. – bobince

Odpowiedz

3

Po pierwsze, nie używaj document.all - jest to niestandardowe i przestarzałe. Użyj document.getElementsByTagName, aby uzyskać elementy DIV w twoim przypadku.

Po drugie, nie rozszerzaj obiektów DOM, takich jak NodeList - obiekty wbudowane są bardzo dziwną rasą i nie muszą zachowywać się tak, jak inne obiekty, z którymi zazwyczaj pracujesz. W tym artykule znajdziesz szczegółowe wyjaśnienie tego: What's wrong with extending the DOM.

+0

Używałem 'getElementByTagName', ale przełączałem się na' document.all' podczas testowania. Było to częścią większego problemu i starałem się go uprościć. Prawdziwy problem stał się metodą rozszerzenia na 'Array', która została nieprawidłowo zaimplementowana i wpłynęła na inny kod. –

1

IE nie obsługuje standardu NodeList. Dlatego powinieneś przetasować swój własny obszar nazw i NIE rozszerzać obiektów rdzenia przeglądarki.

Możesz zrobić alert(typeof window.NodeList) i sprawdzić, czy jest niezdefiniowany, czy nie.

+0

W Chrome jest to 'funkcja', w IE 8 jest to' object', a nie 'undefined'. Tak czy inaczej, to było debugowanie starego kodu, który teraz refaktoryzowałem do przestrzeni nazw, którą już miałem. –

+0

Musisz mieć nowszą wersję IE8, ponieważ moja jest niezdefiniowana. –

3

Stare pytanie, ale o to starał & prawda metoda:

var nodes=document.querySelectorAll("div"); // returns a node list 
nodes=Array.prototype.slice.call(nodes); // copies to an array 

Wyjaśnienie

  • document.querySelectorAll używa selektora CSS stylu znaleźć elementy i zwraca listę węzłów. Działa od IE 8.
  • Metoda slice kopiuje część kolekcji przypominającej tablicę (w tym przypadku całość) do nowej tablicy.
  • call pozwala pożyczyć metodę z jednego obiektu do wykorzystania na innym

Aby znaleźć listę węzłów można również używany `document.getElementsByTagName(), ale ten jest bardziej elastyczny.