2012-06-30 14 views
5

Bu kodu yaptık:getElementsByTagName ("*") her zaman güncellenir mi?

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? 

Bir keman: Beşinci ve childs.length güncellenir böylece altıncı hattı arasında childs=foo.getElementsByTagName("*"); yazmak zorunda değilsiniz http://jsfiddle.net/RL54Z/3/

.

Bu nasıl olabilir?

cevap

3

En listesini (ör getElementsBy*, querySelectorAll ve Node.childNodes döndü) basit Diziler değil NodeList nesneler değildir. NodeList nesneleri genellikle "canlı", belgede yapılan değişiklikler otomatik olarak Nodelist nesnesine yayılır. (Bir istisna yaşamayan olduğunu querySelectorAll gelen sonuç olduğunu!) Böylece

siz, örnekte gördüğünüz tüm a unsurların bir nodelist almak, sonra o, belgeye başka a unsur ekleyebilir olarak NodeList nesnesinde a görünecektir.

Bu nedenle, belgede aynı anda değişiklikler yaparken NodeList üzerinden yineleme yapmak güvensizdir. Ör bu kod şaşırtıcı şekilde davranır: ne olacak

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

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

elemanları atlayarak kadar sona erecek olan! NodeList'in sonundan geriye doğru yineleyin veya NodeList öğesini düz bir Diziye kopyalayın (güncelleştirmeyecek) ve sonra bununla çalışın.

Mozilla MDC site adresindeki NodeLists hakkında daha fazla bilgi edinin.

3

Eğer documentation okursanız

sürpriz olmaz verilen etiket adı ile unsurların bir listesini döndürür. Belirtilen öğenin altındaki alt öğe, elemanın kendisi hariç, aranır. Döndürülen liste canlıdır, yani kendisini otomatik olarak DOM ağacıyla günceller. Sonuç olarak, birkaç kez element.getElementsByTagName öğesini aynı öğe ve argümanlarla çağırmaya gerek yoktur. DOM düğümlerden