views:

77

answers:

2

I use the following code to append a big dom on a mobile browser (webkit):

1. while(i--)  // 'i' ranges from 10 to possibly 1000
2. {
3.   var html01 = ['<div class="test">', someVal[i],'</div>',
4.                 '<div><p>', someTxt.txt1, anotherVal.val[i], '</p></div>',
5.   // lots of html snippets interspersed with variables that differ in each loop iteration
6.                  // on average ~40 to 50 elements in this array
7.                ].join('');
8.   var fragment = document.createDocumentFragment(),
9.   div = fragment.appendChild(document.createElement('div'));
10.  div.appendChild(jQuery(html01)[0]);
11.  someArray[someArray.length] = fragment;
12. } //end while loop
13. jQuery('#screen1').append(someArray);
14. // similarly i create 'html02' till 'html15' to append in other screen divs

Is there a better or faster way to do the above? Do you see any problems with the code? I am a little worried about line 10 where i wrap in jquery and then take it out.

+1  A: 

Why wrap in jQuery at all? I see no gain from this as you could drop it with no additional code needed.

Line 10
From

div.appendChild(jQuery(html01)[0]);

To

div.innerHTML = html01;

Line 13
From

jQuery('#screen1').append(fragment);

To

document.getElementById("screen1").appendChild(fragment);

The gain might not be big, but it will be there. Other than that (and based on the code shown) I don't see any way to make things faster.

Sean Kinsey
+1  A: 

UPDATE: Addresses the need to append unique values


I'm no DOM API expert, but this will create the elements you need, clone them in the loop, update their textNode values, append them to the fragment, then append the fragment to the DOM.

It will work as long as the variables you offered for the text nodes are correct.

    // Form a single fragment outside the loop
       var fragment = document.createDocumentFragment();

    // Create the first div and append a textNode
        var div1 = document.createElement('div');
        div1.appendChild( document.createTextNode('content') );
        div1.setAttribute('class','test');

    // Create the second div, its inner p element, and its textNode
        var div2 = document.createElement('div');
        var p = document.createElement('p');
        p.appendChild( document.createTextNode('content') );
        div2.appendChild( p );

    // Variables to store the clones of above
        var clone1, clone2;

    // Counter for while loop
        var i = 1000;

     while(i--)  // someIndex ranges from 10 to possibly 1000
     {
        // Clone the elements we created
        clone1 = div1.cloneNode(true);
        clone2 = div2.cloneNode(true);

        // Update the nodeValue of the first textNode in div1
        clone1.firstChild.nodeValue = 'someVal[i]';

        // Get the p element in div2 and update its nodeValue
        clone2.firstChild.firstChild.nodeValue = 'someTxt.txt1 + anotherVal.val[i]';

        // Append the elements we created, cloned and updated to the fragment
        fragment.appendChild(clone1).
        fragment.appendChild(clone2);
     }

        // Append the populated fragment to #screen1
     document.getElementById('screen1').appendChild(fragment);

EDIT:

If you want to manipulate the completed fragment using jQuery before you append it, you need to do:

$(fragment.childNodes);  // Create a jQuery object of the content of the fragment

as this will not work properly:

$(fragment);   // Doesn't work. jQuery methods will be ineffective.    
patrick dw
interesting..you're using all DOM api (compared to array+innerhtml technique what others suggested). I'll test this and let you know. Thanks!
fenderplayer
Well, the only reason I'm doing that is that it seemed like your concern was performance. Since jQuery is a convenience/compatibility layer on top of the DOM API, it only slows it down. If performance isn't such a concern, then jQuery is a nice way to go.
patrick dw
Also, I added an update at the bottom to show how to properly convert your fragment into a jQuery object if needed.
patrick dw
Thanks, makes sense. Using ppk's timer method, i could see no appreciable difference between your method and array+innerhtml method
fenderplayer