2010-12-29 25 views
7

Estoy teniendo dificultades para convertir un NodeList a un array en IE 8. Los siguientes funciona perfectamente en Chrome, pero en IE 8 toArray() no es reconocida como válida:Convertir NodeList a la matriz

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 intenté agregar una función prototipo a una matriz solo para verificar mi cordura y funciona correctamente. Eso me hace pensar que IE 8 en realidad no devuelve un NodeList? Aquí está un ejemplo completo:

http://jsfiddle.net/e4RbH/

¿Qué estoy haciendo mal?

+1

no existe una norma actual que dice que 'NodeList' tiene que ser una función constructora visible y modificable, o que si hay una función de constructor visible como 'NodeList' que se usará como el tipo de retorno de todos los métodos de devolución de NodeList. (Después de todo, una NodeList 'childNodes' y una NodeList' getElementsByTagName' hacen cosas muy diferentes.) La norma ECMAScript especifica el prototipado en los objetos JS nativos y es confiable; la creación de prototipos en los Nodos DOM y otros objetos no definidos por el estándar de lenguaje no es confiable y debe evitarse. – bobince

Respuesta

3

En primer lugar, no use document.all - no es estándar y está en desuso. Use document.getElementsByTagName para obtener los elementos DIV en su caja.

En segundo lugar, no extienda los objetos DOM como NodeList - los objetos incorporados son una raza muy extraña y no se requiere que se comporten como cualquier otro objeto con el que generalmente trabaja. Vea este artículo para una explicación detallada de esto: What's wrong with extending the DOM.

+0

Estaba usando 'getElementByTagName', pero cambié a' document.all' durante la prueba. Esto era parte de un problema mayor y traté de simplificarlo. El problema real terminó siendo un método de extensión para 'Array' que se implementó incorrectamente y afectó a otro código. –

1

IE no es compatible con NodeList de la manera estándar. Esta es la razón por la que debe desplegar su propio espacio de nombres y NO extender los objetos principales del navegador.

Puedes hacer alert(typeof window.NodeList) y ver si es indefinido o no.

+0

En Chrome es 'function', en IE 8 es' object', no 'undefined'. De cualquier manera, esto estaba depurando un código viejo que ahora he refactorizado en un espacio de nombres que ya tenía. –

+0

Debe tener una versión más nueva de IE8 porque la mía no está definida. –

3

vieja pregunta, pero aquí es un tratado & verdadero método:

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

Explicación

  • document.querySelectorAll utiliza un selector de estilo CSS para encontrar elementos y devuelve una lista de nodos. Funciona a partir de IE 8.
  • El método slice copia una parte de una colección similar a una matriz (en este caso, todo) en una nueva matriz.
  • call le permite tomar prestado un método de un objeto a utilizar en otro

Para encontrar la lista de nodos también se podría haber utilizado `document.getElementsByTagName(), pero éste es más flexible.