Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript autocloses HTML tags?

Why do these two functions give different results?

var table1 = document.getElementById("table1");
var table2 = document.getElementById("table2");

var register = [
  {att1: 1, att2: 2, att3: 3},
  {att1: 4, att2: 5, att3: 6},
  {att1: 7, att2: 8, att3: 9}
];

//table1.innerHTML = "";
//table2.innerHTML = "";

function drawTable1() {
  for (var i = 0; i < register.length; i++) {
    table1.innerHTML += "<tr><td>" + register[i].att1 + "</td><td>" + register[i].att2 + "</td><td>" + register[i].att3 + "</td></tr>";
  }
}

function drawTable2() {
	for (var i = 0; i < register.length; i++) {
  	table2.innerHTML += "<tr>";
    table2.innerHTML += "<td>" + register[i].att1 + "</td>";
    table2.innerHTML += "<td>" + register[i].att2 + "</td>";
    table2.innerHTML += "<td>" + register[i].att3 + "</td>";
    table2.innerHTML += "</tr>";
  }
}

drawTable1();
drawTable2();
table {
  display: inline;
}
<body>
  <table>
    <thead>
      <tr>
        <th>Att1</th>
        <th>Att2</th>
        <th>Att3</th>
      </tr>
    </thead>
    <tbody id="table1">

    </tbody>
  </table>
  <table>
    <thead>
      <tr>
        <th>Att1</th>
        <th>Att2</th>
        <th>Att3</th>
      </tr>
    </thead>
    <tbody id="table2">

    </tbody>
  </table>
</body>

I'm just beginning with js, and I've noticed this thing. From a logical point of view i see no differences between the two functions, the second has just been broken up to make the code easier to read. It should simply be adding strings to a string, but it seems like at every operation the opened tags get closed by the program, resulting in a multitude of rows.

Why is this? How is this useful?

like image 843
itsmeciao Avatar asked Aug 03 '26 09:08

itsmeciao


2 Answers

innerHTML isn't actually a string. It's an interface to the DOM (the elements on the page); reading from it generates a string version of what's currently there, and assigning a value to it modifies the tree.

It's impossible to have an unclosed <tr> element in the DOM -- when you perform an operation like table1.innerHTML += "<tr>", the browser sees the unclosed <tr> tag as invalid HTML and has to repair it by inserting a closing </tr>. When you later access innerHTML to perform another modification, you see the "repaired" version, not the value you initially assigned.

The easiest fix will be to build the entire table as a string, then assign to innerHTML all at once, e.g.

var html = "";
for (...) {
   html += "<tr>";
   html += "<td>example</td>";
   html += "</tr>";
}
table1.innerHTML = html;

You may also want to investigate Javascript DOM methods to create HTML elements (like document.createElement()) as an alternative -- innerHTML is a clumsy interface.

Well the innerHTML content is — as the name implies — HTML and HTML is not just a string. I assume you know that browsers build a DOM out of it. Basically a tree out of nodes that know their tag, attributes, children etc.

Now you need this DOM to render anything. Sure, it is nearly impossible to get invalid html as non-html can just be interpreted as a mere string (which is valid html). However, the browser tries to fullfill the html standard as much as possible. Therefore it also generates missing end tags in order to produce well-formed html. (even when it is not in the html, he will implicitely generate them for the DOM and in some browsers you can see that in the HTML provided in the dev console).

So now you add a random <tr> attribute to your html like this table2.innerHTML += "<tr>". This would produce not-well-formed html. Therefore it should generate the missing end tag. Whether that is done while running the js-code or afterwards when refreshing the DOM, I don't know, but generally it helps generate well-formed HTML.


I'm sure you know how to circumvent that problem, but anyways: Instead of using an temporary string, you might want to look at document.createElement(). This is generally used to generate well-formed html in a non-confusing and safe (as in "something unexpected like above doesn't happen safe") way.

like image 37
SourceOverflow Avatar answered Aug 05 '26 22:08

SourceOverflow



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!