【问题标题】:Javascript autocloses HTML tags?Javascript自动关闭HTML标签?
【发布时间】:2018-05-17 05:50:20
【问题描述】:

为什么这两个函数会给出不同的结果?

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>

我刚开始接触js,我已经注意到了这个东西。从逻辑的角度来看,我认为这两个函数之间没有区别,第二个函数刚刚被分解以使代码更易于阅读。它应该只是将字符串添加到字符串中,但似乎在每次操作中打开的标签都会被程序关闭,从而产生大量行。

这是为什么?这有什么用?

【问题讨论】:

  • 标题错了——“Javascript”(JS 引擎)不做这样的事情,它只知道字符串,而不知道“HTML 标签”。那是浏览器的 HTML => DOM 解析器在工作,它不是“Javascript”的一部分,而是浏览器的一部分。 Javascript 允许在那里发送字符串并操作和查询 DOM,但所有这些的方法都是“浏览器”。
  • 谢谢大家!现在说得通了。我将浏览器视为 html 代码的简单解释器,我的想法是代码中的任何错误都会导致渲染错误,我没有意识到它正在积极寻找错误并修复它们,所以我链接了图示的问题在 JS 的问题中。

标签: javascript html arrays for-loop innerhtml


【解决方案1】:

innerHTML 实际上不是一个字符串。它是 DOM(页面上的元素)的接口;从中读取会生成当前存在的字符串版本,并为其分配值会修改树。

在 DOM 中不可能有未关闭的 &lt;tr&gt; 元素 - 当您执行类似 table1.innerHTML += "&lt;tr&gt;" 的操作时,浏览器会将未关闭的 &lt;tr&gt; 标记视为无效 HTML,并且必须通过插入关闭 @ 来修复它987654326@。当您稍后访问innerHTML 进行另一次修改时,您会看到“修复”版本,而不是您最初分配的值。

最简单的解决方法是将整个表构建为字符串,然后一次性分配给innerHTML,例如

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

您可能还想研究 Javascript DOM 方法来创建 HTML 元素(如 document.createElement())作为替代方案 - innerHTML 是一个笨拙的界面。

【讨论】:

  • 具体来说innerHTML是一种对DOM进行序列化和解析的方式。在设置innerHTML的情况下是parsed with this algorithm
【解决方案2】:

innerHTML 的内容是——顾名思义——HTML 和 HTML 不仅仅是一个字符串。我假设你知道浏览器会用它构建一个 DOM。基本上是一棵由节点组成的树,这些节点知道它们的标签、属性、子节点等。

现在你需要这个 DOM 来渲染任何东西。当然,获得无效的 html 几乎是不可能的,因为非 html 可以仅仅被解释为一个字符串(这是有效的 html)。但是,浏览器会尽可能地满足 html 标准。因此,它还会生成缺少的结束标记,以生成格式良好的 html。 (即使它不在 html 中,他也会为 DOM 隐式生成它们,在某些浏览器中,您可以在开发控制台中提供的 HTML 中看到)。

所以现在你添加一个随机的&lt;tr&gt; 属性到你的 html 像这样table2.innerHTML += "&lt;tr&gt;"。这会产生格式不正确的 html。因此它应该生成缺少的结束标记。无论是在运行 js 代码时还是之后刷新 DOM 时完成,我不知道,但通常它有助于生成格式良好的 HTML。


我确定您知道如何规避该问题,但无论如何:您可能希望查看document.createElement(),而不是使用临时字符串。这通常用于以不混淆和安全的方式生成格式良好的 html(如“像上面那样意外的事情不会安全地发生”)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-02
    • 1970-01-01
    • 1970-01-01
    • 2018-03-05
    • 2015-07-14
    相关资源
    最近更新 更多