2

I'd like to append multiple table rows with multiple columns to my table. What's the recommended way of doing is? I figured out three options. Advantages and disadvantages?

1:

$('table').append('<tr>...</tr>);

2:

html.push('<tr>');

elements.each(function() {
    html.push('<td>...</td>');
});

html.push('</tr>');
$('table').append(html);

3:

html = '<tr>' +
       ... +
       '</tr>';

$('table').append(html);

PS: The appended data is from my database using $.getJSON (stored in elements) and no all tds contains the same. Some of them have a span and some an input field.

3
  • you can use template literals using backticks `mystring ${variable}` you can also have newlines between the backticks Commented May 22, 2020 at 7:17
  • @user120242 so you would recommend option 1 using $('table').append('<tr><td>${var}</td>...</tr>)? Commented May 22, 2020 at 7:22
  • I'm just throwing out there an option that will make it easier to deal with html string building. I wouldn't recommend that as a base for any kind of complex web app. But it'd make your examples easier to do: $('table').append(`<tr><td>${var}</td></tr>`). Commented May 22, 2020 at 7:27

2 Answers 2

4

The best way to update dom is by using createDocumentFragment.

It creates a new empty DocumentFragment into which DOM nodes can be added to build an offscreen DOM tree.

DocumentFragments are DOM Node objects which are never part of the main DOM tree. The usual use case is to create the document fragment, append elements to the document fragment and then append the document fragment to the DOM tree.

Since the document fragment is in memory and not part of the main DOM tree, appending children to it does not cause page reflow which results in better performance.

For your case:

const dataToFill = [[1,2,3], [4,5,6], [7,8,9]]
const fragment = document.createDocumentFragment()
for (const row of dataToFill){
  const tr = document.createElement('tr')
  for (const column of row) {
    const td = document.createElement('td')
    td.textContent = column
    tr.appendChild(td)
  }
  fragment.appendChild(tr)
}
document.getElementById('my-table').appendChild(fragment)
<table id="my-table">
  <tr>
    <th>Column 1</th>
    <th>Column 2</th>
    <th>Column 3</th>
  </tr>

</table>

If you will remove document.getElementById('my-table').appendChild(fragment) You won't see the table contains, which means it is getting rendered only once outside the loop. All other operations are only done in memory.

This makes it equivalent to $('table').append('<tr>...</tr>') but in a much readable way which is easy to debug.

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

3 Comments

Does this work if not all tds have the same data? Some have input fields and some spans? (e.q. 1 = span, 2 = span, 3 = input, 4 = span, 5 = input etc.)
Yes. It will definitely work. The approach here is to append your node only once on the screen, because every appendChild on fragment is done in memory.
alright, I'll will save your code for further projects. Thanks! :)
1

Based on your needs I think your best option is the first one but as 'user120242' said it would be better to do it this way

$('table').append(`<tr><td>${var}</td></tr>`)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.