2012-06-30 16 views
5

he hecho este código:getElementsByTagName ("*") siempre actualizado?

var foo=document.createElement("div"); 

var childs=foo.getElementsByTagName("*"); 

console.log(childs.length);//0 OK 

var a=document.createElement("a"); 

foo.appendChild(a); 

console.log(childs.length);//1 WTF? 

un violín: http://jsfiddle.net/RL54Z/3/

no tengo para escribir childs=foo.getElementsByTagName("*"); entre la quinta y la sexta línea de manera que childs.length se actualiza.

¿Cómo puede ser?

Respuesta

3

mayoría de las listas de nodos en el DOM (por ejemplo de regresar de getElementsBy*, querySelectorAll, y Node.childNodes) no son matrices simples sino más bien NodeList objetos. NodeList los objetos suelen estar "vivos", en el sentido de que los cambios en el documento se propagan automáticamente al objeto Nodelist. (Una excepción es el resultado de querySelectorAll, que es no live!)

Así como se puede ver en su ejemplo, si recupera un NodeList de todos los a elementos, a continuación, añadir otro elemento a al documento, que a aparecerá en su objeto NodeList.

Es por eso que no es seguro repetir un NodeList mientras se realizan cambios en el documento al mismo tiempo. Por ejemplo, este código se comportará de forma sorprendente:

var NodeListA = document.getElementsByTagName('a'); 

for (var i=0; i<NodeListA.length; ++i) { 
    // UNSAFE: don't do this! 
    NodeListA[i].parentNode.removeChild(NodeListA[i]); 
} 

¡Lo que sucederá es que terminará salteando elementos! Realice una iteración hacia atrás desde el final de NodeList, o copie NodeList en una matriz simple (que no se actualizará) y luego trabaje con eso.

Más información acerca de NodeLists en el Mozilla MDC site.

3

Si usted lee la documentation no se sorprenderá

devuelve una lista de elementos con el nombre de etiqueta dado. El subárbol debajo del elemento especificado se busca, excluyendo el elemento en sí. La lista devuelta es en vivo, lo que significa que se actualiza automáticamente con el árbol DOM. En consecuencia, no es necesario llamar varias veces element.getElementsByTagName con el mismo elemento y argumentos.

Cuestiones relacionadas