jQuery appending an array of elements

2019-01-22 10:44发布

For the purpose of this question lets say we need to append() 1000 objects to the body element.

You could go about it like this:

for(x = 0; x < 1000; x++) {
    var element = $('<div>'+x+'</div>');
    $('body').append(element);
}

This works, however it seems inefficient to me as AFAIK this will cause 1000 document reflows. A better solution would be:

var elements = [];
for(x = 0; x < 1000; x++) {
    var element = $('<div>'+x+'</div>');
    elements.push(element);
}
$('body').append(elements);

However this is not an ideal world and this throws an error Could not convert JavaScript argument arg 0 [nsIDOMDocumentFragment.appendChild]. I understand that append() can't handle arrays.

How would I using jQuery (I know about the DocumentFragment node, but assume I need to use other jQuery functions on the element such as .css()) add a bunch of objects to the DOM at once to improve performance?

8条回答
Juvenile、少年°
2楼-- · 2019-01-22 11:16

You could just call

$('body').append(elements.join(''));

Or you can just create a large string in the first place.

var elements = '';
for(x = 0; x < 1000; x++) {
    elements = elements + '<div>'+x+'</div>';
}
$(document.body).append(elements);

Like you mentioned, probably the most "correct" way is the usage of a DocFrag. This could look like

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 is not supported by IE<9 and would need an conditional check to use .innerText or .text instead.

查看更多
Luminary・发光体
3楼-- · 2019-01-22 11:23

If you're going for raw performance then I would suggest pure JS, though some would argue that your development performance is more important than your site's/program performance. Check this link for benchmarks and a showcase of different DOM insertion techniques.

edit:

As a curiosity, documentFragment proves to be one of the slowest methods.

查看更多
forever°为你锁心
4楼-- · 2019-01-22 11:33

Sometimes, jQuery isn't the best solution. If you have a lot of elements to append to the DOM, documentFragment is a viable solution:

var fragment = document.createDocumentFragment();
for(var i = 0; i < 1000; i++) {
    fragment.appendChild(document.createElement('div'));
}
document.getElementsByTagName('body')[0].appendChild(fragment);
查看更多
够拽才男人
5楼-- · 2019-01-22 11:37

I would use native Javascript, normally much faster:

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:

There you go a jsfiddle with different options implemented. The @jackwander's solution is, clearly, the most effective one.

查看更多
祖国的老花朵
6楼-- · 2019-01-22 11:40

A slight change to your second approach:

var elements = [],
newDiv;
for (x = 0; x < 1000; x++) {
    newDiv = $('<div/>').text(x);
    elements.push(newDiv);
}
$('body').append(elements);

$.append() certainly can append an array: http://api.jquery.com/append/

.append(content) | content: One or more additional DOM elements, arrays of elements, HTML strings, or jQuery objects to insert at the end of each element in the set of matched elements.

查看更多
聊天终结者
7楼-- · 2019-01-22 11:41

You could use an empty jQuery object instead of an array:

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);

This might be useful if you want to do stuff with newly generated element inside the loop. But note that this will create a huge internal stack of elements (inside the jQuery object).


It seems though that your code works perfectly fine with jQuery 1.8.

查看更多
登录 后发表回答