Using createDocumentFragment to replace an existing column in a table

2k Views Asked by At

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!
2

There are 2 best solutions below

1
On BEST ANSWER

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.

1
On

Columns can't be put into the table all at once (and thus won't work as a fragment) because a column is a bunch of different cells in each of a whole bunch of rows - it's not an entity by itself.

One thing you could do for good performance is to temporarily hide the table with display: none, add all your rows/cells and then show the table again. This should allow the browser to avoid intermediate layout issues every time you add a new cell and you should only get one repaint with the final content.