2

I need to append multiple nodes to a container. Rather than doing a slow DOM append inside each iteration, I want to queue up the nodes in a document fragment (open to other ideas) and append them all at one time. Here is my code:

var fragment = document.createDocumentFragment();
$.each( poFailureInfoMultiple, function(i,e){
    fragment.appendChild(
         $('<button/>', {
            'class': 'el-contents-center multiple-record'
         })
    );
});

$('#some-container').html( fragment );

My problem is I am getting an error message stating:

Could not convert JavaScript argument arg 0 [nsIDOMDocumentFragment.appendChild]

So how can I append multiple element nodes to my DOM at once? I don't HAVE to use the fragment method (I just found it and it seemed viable).

Note: I DO NOT WANT TO USE HTML SYNTAX FOR THE APPEND

i.e. $('#some-container').append('<button class="myclass"></button>');
2
  • Where does poFailureInfoMultiple come from? Commented Jun 14, 2012 at 16:31
  • Why are you mixing document fragments with jQuery. appendChild doesn't take a jQuery object and $.html does not take a DocumentFragment That's what your error is telling you. Commented Jun 14, 2012 at 16:34

4 Answers 4

9
var elemsToAppend=$()

$.each( poFailureInfoMultiple, function(i,e){
    elemsToAppend = elemsToAppend.add(
        $('<button/>', {
            'class': 'el-contents-center multiple-record'
        })
    )
}); 
$('#some-container').append(elemsToAppend)

The add method on a jQuery object doesn't alter the object itself but returns a new object, which is why you need elemsToAppend = elemsToAppend.add(...). I honestly cant say how fast this method is though. I actually think the html way is faster though.

Sign up to request clarification or add additional context in comments.

1 Comment

I like this solution a lot. You can sub .append for .html( elmsToAppend ) and it works just ask well. I'm not sure how much faster the fragment option is compared to this, but I do like the use of .add
3

You are mixing document fragments with jQuery, passing the wrong arguments. appendChild doesn't take a jQuery object and $.html does not take a DocumentFragment That's what your error is telling you.

Example http://jsfiddle.net/YNLzg/

var fragment = document.createDocumentFragment();
$.each( [1,2,3], function(i,e){
    fragment.appendChild(
         $('<button/>', {
            'class': 'el-contents-center multiple-record'
         })[0] // passing the HTMLElement to appendChild, not a jQuery object
    );
});
// Can't call $.html() and pass it a fragment, call appendChild.
document.getElementById('ct').appendChild(fragment);​

2 Comments

Thanks for the clarification. My big question is how much faster is utilizing fragment rather than jQuery's .add ? This seems like more work but is the return worth it?
@sadmicrowave Internally, jQuery creates document fragments, so performance it almost the same. See bennadel.com/blog/… Kranklin answer is nice because it doesn't mix standard DOM manipulation with jQuery manipulation. I didn't do that because I wanted to show you that you were passing illegal arguments to functions.
0

$('#some-container').append(fragment.childNodes); will do the job. For a fun example, run this in the console:

var f = document.createDocumentFragment();
var div = document.createElement('div');
div.innerHTML = "<h1>This heading was not here before :)</h1>";
f.appendChild(div);
$('body').append(f.childNodes);

The heading will appear at the bottom of the page. (Tested in Chrome, FF7, and IE8)

UPDATE: To clarify how this applies to the code in your OP:

var fragment = document.createDocumentFragment();
$.each(poFailureInfoMultiple, function (i, e) {
    var btn = document.createElement('button');
    btn.cssClass = 'el-contents-center multiple-record';
    fragment.appendChild(btn);
});
$('#some-container').append(fragment.childNodes);

4 Comments

this suggestion does not work. I get the same error as my OP
@sadmicrowave: Upon further review, a DocumentFragment does not have an innerHTML property to use. Updated answer with tested, functional code.
My OP stated I did not want to use HTML syntax for the element, I need it in object node notation.
@sadmicrowave: I'm confused. $('#some-container').append(fragment.childNodes); is object node notation and will work.
0

If you would choose html syntax for append (demo):

$(selector)
  .append(arrayOfContents.map(function(s){return "<span>"+s+"</span>";}).join(''));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.