Search code examples
javascripthtmlfor-loopdocumentfragment

Using createDocumentFragment to replace an existing column in a table


I've read that createDocumentFragment is way more faster than appending elements one by one to the DOM in a for-loop, e.g. see here.

What I want to do:

  1. Create a table column in a document fragment. This column should contain numbers from an array (for example "ratings").
  2. After that I want to replace an existing column with the new one (the "fragment" one). So I can put the whole column to the DOM all at once.

My problem:

I can't really figure out how to replace an existing column if there already is one. Appending on the other hand is no problem.

My JSfiddle: http://jsfiddle.net/LEqG9/2/

Helpful links, here and here

HTML

<table id = "table">
    <tr>
        <th>Name</th>
        <th>Rating</th>
    </tr>
    <tr>
        <td>A.H.Hattray </td>
        <td id = "row0"></td>
    </tr>
    <tr>
        <td>Icke_eben </td>
        <td id = "row1"></td>
    </tr>
    <tr>
        <td>John_Doe123 </td>
        <td id = "row2"></td>
    </tr>
</table>

Javascript

var rating = [1, 10, 3];
var fragment = document.createDocumentFragment();


for (var i = 0, len = rating.length; i < len; i++){ 
    var element = document.createElement('tr');
    element.innerHTML = rating[i];
    fragment.appendChild(element);
}
document.getElementById('table').appendChild(fragment); //I know here should be the code to replace the second column!

Solution

  • The following code demonstrates that it is possible to manipulate an existing table in a DocumentFragment.

    var rating = [1, 10, 3];
    var theTable = document.getElementById('table');
    var frag = document.createDocumentFragment();
    frag.appendChild(theTable);
    var col2 = frag.querySelectorAll('tr td:nth-of-type(2)');
    for (var i=0; i < col2.length; i++) {
        col2[i].innerHTML = rating[i];
    }
    // it is also possible to use insertCell and deleteCell
    var theRows = frag.querySelectorAll('tr');
    for (var i=0; i < theRows.length; i++) {
        var x = theRows[i].insertCell(1);
        if (i > 0) 
            x.innerHTML = 'new one';
        else
            x.innerHTML = 'The Header';
    }
    document.body.appendChild(frag);
    

    (Making the new cell in the first row a TH element, rather than TD requires a little more work, using createElement and appendChild or insertBefore.)

    If you step through this the table is removed from the DOM when appended to the fragment, then reappears when the fragment is appended to the body.