使用innerHTML加载html片段的奇怪问题

时间:2013-01-24 14:20:18

标签: javascript html dom opera innerhtml

我有一个opera的userjs脚本,它显示自己的界面,目前使用DOM方法创建元素。这很好用,但由于接口与代码绑定,因此难以维护。所以我正在寻找一种将布局与代码分开的方法。此外,我想保持简单,真的不想依赖于框架(jquery ...)。我不关心跨浏览器功能,这个东西无论如何都只适用于歌剧。

我把所有风格的东西都变成了css,这有帮助。现在我正在寻找一种抽象布局的方法。 UI的一个很好的部分是非常动态的,所以我不能只使用一个大的静态HTML。提出的想法是让一段html包含不同UI部分的布局,从中提取片段并根据需要将所有内容放在一起。

这在某种程度上非常有效:

  • 创建一个div,永远不会让它成为父母。
  • 使用.innerHTML将html加载到其中
  • 使用此getElementsByClassName()在其中查找小部件
  • 使用widget.cloneNode(true)
  • 克隆它们
  • 父母等......

我知道cloneNode()的一些问题(重复ID的风险,克隆中缺少事件处理程序)但我可以解决它们。

问题是,加载.innerHTML后,我得到的结果与当前的DOM代码不同,即使我使用DOM代码版本中的捕获布局!我以桌子为例看到了这一点。对于一个简单的

<table><tr><td></td></tr></table>

innerHTML版本在蜻蜓中显示<tbody>个标签,而这样的css规则不再适用于此:

table > tr > td { ... }

我对这一切有一种感觉......

  • DOM和HTML布局之间是否存在其他重大差异?
  • 也许我应该在DOM中使用<tbody>
  • 你会怎么做?

奖金问题:

  • createDocumentFragment()存在背后的原因是什么?你能用它做什么,否则无法做到?

1 个答案:

答案 0 :(得分:1)

你是对的,它看起来像一个标记没有定义<tbody>的表格,在阅读<tbody>标题时,会转换为带有innerHTML标记的标记表。

但是这不应该给你带来太多麻烦:至于CSS问题,请从你的选择器中删除>(限制为直接后代)。

DocumentFragment的一个可能的好处是,当你需要进行大量的DOM操作时,如果只操作一个文档片段,它可能会带来一些性能提升,并且一旦完成所有转换,它就会附加到DOM。