JQuery, добавляющий массив элементов
В целях этого вопроса скажем, нам нужно append()
1000 объектов элементу body
.
Вы можете сделать это следующим образом:
for(x = 0; x < 1000; x++) {
var element = $('<div>'+x+'</div>');
$('body').append(element);
}
Это работает, однако мне кажется неэффективным для меня, как AFAIK, это вызовет 1000 пересчетов документов. Лучшим решением будет:
var elements = [];
for(x = 0; x < 1000; x++) {
var element = $('<div>'+x+'</div>');
elements.push(element);
}
$('body').append(elements);
Однако это не идеальный мир, и это вызывает ошибку Could not convert JavaScript argument arg 0 [nsIDOMDocumentFragment.appendChild]
. Я понимаю, что append()
не может обрабатывать массивы.
Как я могу использовать jQuery
(я знаю о DocumentFragment node, но предполагаю, что мне нужно использовать другие функции jQuery для элемента, такого как .css()
) добавить кучу объектов в DOM сразу для повышения производительности?
Ответы
Ответ 1
Вы можете использовать пустой объект jQuery вместо массива:
var elements = $();
for(x = 0; x < 1000; x++) {
elements = elements.add('<div>'+x+'</div>');
// or
// var element = $('<div>'+x+'</div>');
// elements = elements.add(element);
}
$('body').append(elements);
Это может быть полезно, если вы хотите делать вещи с вновь созданным элементом внутри цикла. Но обратите внимание, что это создаст огромный внутренний стек элементов (внутри объекта jQuery).
Кажется, что ваш код отлично работает с jQuery 1.8.
Ответ 2
Вы можете просто позвонить
$('body').append(elements.join(''));
Или вы можете просто создать большую строку в первую очередь.
var elements = '';
for(x = 0; x < 1000; x++) {
elements = elements + '<div>'+x+'</div>';
}
$(document.body).append(elements);
Как вы уже упоминали, вероятно, самым "правильным" способом является использование DocFrag. Это может выглядеть как
var elements = document.createDocumentFragment(),
newDiv;
for(x = 0; x < 1000; x++) {
newDiv = document.createElement('div');
newDiv.textContent = x;
elements.append( newDiv );
}
$(document.body).append(elements);
.textContent
не поддерживается IE < 9 и требует условной проверки вместо .innerText
или .text
.
Ответ 3
Так как $.fn.append принимает переменное число элементов, мы можем использовать apply
для передачи массива в качестве аргументов:
el.append.apply(el, myArray);
Это работает, если у вас есть массив объектов jQuery. Согласно спецификации, вы можете добавить массив элементов, если у вас есть элементы DOM. Если у вас есть массив строк html, вы можете просто .join('') их и добавить их все сразу.
Ответ 4
Обновление до jQuery 1.8, это работает по назначению:
$('body').append([
'<b>1</b>',
'<i>2</i>'
]);
Ответ 5
Небольшое изменение вашего второго подхода:
var elements = [],
newDiv;
for (x = 0; x < 1000; x++) {
newDiv = $('<div/>').text(x);
elements.push(newDiv);
}
$('body').append(elements);
$. append(), безусловно, может добавить массив: http://api.jquery.com/append/
.append(content) | content: один или несколько дополнительных элементов DOM, массивы элементов, строки HTML или объекты jQuery для вставки в конце каждого элемента в наборе согласованных элементов.
Ответ 6
Иногда jQuery - не лучшее решение. Если у вас есть много элементов для добавления в DOM, documentFragment
является жизнеспособным решением:
var fragment = document.createDocumentFragment();
for(var i = 0; i < 1000; i++) {
fragment.appendChild(document.createElement('div'));
}
document.getElementsByTagName('body')[0].appendChild(fragment);
Ответ 7
Я знаю, вопрос старый, но, возможно, он помогает другим.
Или просто используйте оператор распространения ECMA6:
$('body').append(...elements);
Ответ 8
Если вы собираетесь работать с сырой производительностью, я бы предложил чистый JS, хотя некоторые утверждают, что ваша производительность разработки важнее производительности вашего сайта/программы.
Проверьте ссылку на тесты и демонстрацию различных методов вставки DOM.
изменить:
Как любопытство, documentFragment
оказывается одним из самых медленных методов.
Ответ 9
Я бы использовал собственный Javascript, обычно намного быстрее:
var el = document.getElementById('the_container_id');
var aux;
for(x = 0; x < 1000; x++) {
aux = document.createElement('div');
aux.innerHTML = x;
el.appendChild(aux);
}
EDIT:
Там вы найдете jsfiddle с различными вариантами. Решение @jackwander, безусловно, является наиболее эффективным.