Добавление элементов в DOM в структуре цикла - PullRequest
3 голосов
/ 08 июля 2010

После загрузки страницы я хотел бы добавить дополнительный элемент для каждого существующего элемента на странице.

Я пробовал что-то вроде этого:

    var divs=document.getElementsByTagName('div');

    for(i=0;i<divs.length;i++){
        newDiv=document.createElement('div');
        divs[i].appendChild(newDiv);
    }

Просто предупреждение, это на самом деле замораживает браузер , потому что переменная divs является динамической и divs.length становится все больше и больше при каждом цикле

Есть ли способ определить количество тегов, когда DOM обычно загружается в первый раз и имеет возможность работать с элементами статически.

Пока что не могу найти другого решения.

Большое спасибо. Деннис!

Ответы [ 4 ]

11 голосов
/ 08 июля 2010

Проблема в том, что коллекции DOM live , и когда базовая структура документа изменяется, это автоматически отражается на коллекции, поэтому, когда свойство lengthдоступ к нему будет содержать новую длину, общий подход - кэш длина до начала цикла:

var divs=document.getElementsByTagName('div');

for(var i = 0, len = divs.length;i<len;i++){
    var newDiv = document.createElement('div');
    divs[i].appendChild(newDiv);
}

Также обратите внимание, что вы должны объявить все свои переменные с помощьюоператор var, в противном случае он может стать глобальным.

Редактировать: В этом случае, поскольку вы добавляете дочерние узлы с одним и тем же tagName, коллекция будет изменена,и индексы больше не будут совпадать с , после первой итерации индекс 1 будет ссылаться на объект newDiv из предыдущей итерации, поскольку @ Casey рекомендует, чтобы это былобезопаснее преобразовать коллекцию в простой массив перед ее обходом.

Я использую следующую функцию:

function toArray(obj) {
  var array = [];
  // iterate backwards ensuring that length is an UInt32
  for (var i = obj.length >>> 0; i--;) { 
    array[i] = obj[i];
  }
  return array;
}

//...
var divs = toArray(document.getElementsByTagName('div'));
//...
3 голосов
/ 08 июля 2010

Как вы сказали, переменная divs является динамической, поэтому вы должны преобразовать ее в массив (который является статическим), прежде чем использовать его.

var nodeList = document.getElementsByTagName('div');
var divs = [];
for (var i = 0; i < nodeList.length; i++)
    divs.push(nodeList[i]);
// loop again and append the other divs

Другой (более элегантный) способ сделать это:

var divs = Array.prototype.slice.call(document.getElementsByTagName('div'));

Но, увы, этот метод не работает в IE.

0 голосов
/ 08 июля 2010

document.getElementsByTagName() делает НЕ возвращает простой массив, но экземпляр HtmlCollection, который ведет себя как массив, но фактически представляет некоторый вид для всех элементов с данным именем элемента в документ.

Таким образом, всякий раз, когда вы вставляете что-то в DOM, свойство длины divs также будет обновляться - конечно.

Итак, помимо других ответов здесь, это поведение должно иметь смысл; -)

0 голосов
/ 08 июля 2010

Используя jQuery , это довольно просто. Вы можете получить ссылку на все существующие элементы div или любой другой элемент на странице, а затем очень легко добавить новый элемент без необходимости создания явного цикла. Надеюсь, что это поможет.

$('div').each(function(){
   var newDiv = document.createElement('div');
   $(this).append(newDiv);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...