2

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!
Community
  • 1
  • 1
OhDaeSu
  • 515
  • 1
  • 7
  • 21
  • no, you can only changes rows with one chunk, not columns. you would need to append the whole table or modify the existing column in-place via the dom. – dandavis May 29 '14 at 20:52
  • 1
    Columns can't be put into the table all at once 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. – jfriend00 May 29 '14 at 20:55
  • Can't you just replace the content of the cells, rather than the entire cell? – RobG May 29 '14 at 20:58
  • @jfriend00: Thanks, hiding and showing the table after it has been completely loaded is a good idea! My problem was that in my table the contents (of the ratings) were showing up a little bit later than the names). – OhDaeSu May 29 '14 at 21:07

2 Answers2

2

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.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • thanks, "display:none" in the CSS and showing the table again with jQuery worked. $('table').show(); [link](http://jsfiddle.net/LEqG9/3/) – OhDaeSu May 29 '14 at 21:42
2

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.

Andy G
  • 19,232
  • 5
  • 47
  • 69
  • Ah, great, thank you. I've tried it in jsfiddle and it worked: http://jsfiddle.net/LEqG9/7/ and http://jsfiddle.net/LEqG9/6/ (without a new column). – OhDaeSu May 29 '14 at 22:11