2012-06-30 4 views
5

Я сделал этот код:getElementsByTagName ("*") всегда обновляется?

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? 

скрипка: http://jsfiddle.net/RL54Z/3/

Я не должен писать childs=foo.getElementsByTagName("*"); между пятой и шестой строкой, так что childs.length обновляются.

Как это может быть?

ответ

3

Большинство списков узлов в DOM (например, вернулся из getElementsBy*, querySelectorAll и Node.childNodes) не являются простыми Массивы, а скорее NodeList объекты. NodeList объекты обычно «живые», при этом изменения в документе автоматически распространяются на объект Nodelist. (Исключением является результатом querySelectorAll, который не жить!)

Так как вы можете видеть в вашем примере, если вы извлечь NodeList всех a элементов, а затем добавить еще один a элемент в документе, который a появится в вашем объекте NodeList.

Вот почему небезопасно выполнять итерацию через NodeList при одновременном внесении изменений в документ. Например, этот код будет вести себя удивительными способами:

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

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

Что произойдет, вы закончите пропуски элементов! Или итерацию назад с конца NodeList, либо скопируйте NodeList в простой массив (который не будет обновляться), а затем сработает с этим.

Подробнее о NodeLists на странице Mozilla MDC site.

3

Если вы читали documentation вы не удивитесь

Возвращает список элементов с указанным именем тега. Выполняется поиск поддерева под указанным элементом, исключая сам элемент. Возвращенный список является живым, что означает, что он автоматически обновляется с помощью дерева DOM. Следовательно, нет необходимости вызывать несколько раз element.getElementsByTagName с тем же элементом и аргументами.

 Смежные вопросы

  • Нет связанных вопросов^_^