【问题标题】:Advantages to DOMParser vs template & innerHTMLDOMParser 与模板和 innerHTML 的优势
【发布时间】:2016-09-11 23:06:15
【问题描述】:

我正在寻找处理解析 HTML 或 XHTML(XML 序列化)标记并将其插入网页的 DOM 的最佳方法,该网页可以是 text/html 或 application/xhtml+xml。不打算使用像 jQuery 这样的库,只关心与最新版本的 Chrome 的兼容性。

我看到了两种可能的解决方案。

  • 模板和内部HTML:

    let temp = document.createElement('template');
    temp.innerHTML = markuptext;
    document.body.appendChild(temp.content);
    
  • DOMParser:

    let parser = new DOMParser();
    let doc = parser.parseFromString('<div xmlns="http://www.w3.org/1999/xhtml">' + markuptext + '</div>', 'application/xhtml+xml');
    let frag = document.createDocumentFragment(), childNode;
    while (childNode = doc.documentElement.firstChild) {
        frag.appendChild(childNode);
    }
    document.body.appendChild(frag);
    

我希望有人能指出这两种方法的优缺点。

使用 Template & innerHTML 我假设 Chrome 会根据页面的内容类型选择解析为 HTML/XML,并且可能无法更改它。似乎 Template & innerHTML 允许像 &lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt; 这样的片段在 &lt;tbody&gt; 之外,无论它是解析为 HTML 还是 XML。 DOMParser 也允许这样做,但如果它被解析为 XML。

【问题讨论】:

  • DHTML 属性 innerHTML 是一个成熟的 HTML 解析器,在将 HTML 流序列立即转换为 DOM 树时高度优化且同样可靠(在所有浏览器引擎)。作为奖励,它还可以对不完整的流进行错误更正。
  • @BekimBacaj "it may also be able to make error corrections on an incomplete stream" 如果属实,我会认为这是负面的。
  • 我认为这是一个好处——因为存在任何类型的数据结构语言的唯一原因是实际数据。这就是你感兴趣的全部,你根本不在乎它的结构,只要你得到你正在寻找或等待的信息。无论如何,除此之外的任何行为都注定会像 xhtml 一样过早死亡。
  • @BekimBacaj 我完全不同意。我希望我的标记格式正确,如果不是,我希望它告诉我,而不是默默地尝试猜测它的实际含义。这些不是标记错误的借口。但我离题了。
  • stackoverflow.com/questions/37554623/… - DOMParser 更安全

标签: javascript html xml google-chrome dom


【解决方案1】:

这取决于你的目标是什么。如果您只想“按原样”附加已解析的 html/xhtml,则使用 .innerHTML,它更容易且通常更快。 但是,根据我的经验,通常,您必须进行某种转换,然后使用 dom 操作是最好的方法。但是您应该避免在循环中逐个节点附加到 document.body,因为它速度慢且效率低,只需创建一些“虚拟” dom 元素,在循环中添加节点,而不是附加整个对象:

let div = document.createElement('div');
let childNode;
while (childNode = doc.documentElement.firstChild) {
    div.appendChild(childNode);
}
document.body.appendChild(div);

一个重要的注意事项,关于尝试在 JS 中找到最有效的解决方案。 JS 性能高度依赖于 javascript 引擎,未来会优化 js 的哪些部分。因此,您应该始终编写某种性能测试(或使用准备好的测试套件),尤其是关于 DOM API 之类的缓慢“部分”。好消息是,引擎开发人员倾向于支持众所周知的解决方案和“良好实践”进行优化,他们通常会留下“不好的部分”。

以下是关于 innerHTML 与 DOM 附加的一些很好的测试: http://andrew.hedges.name/experiments/innerhtml/

在不创建“虚拟”div 的情况下附加到 DOm: https://coderwall.com/p/o9ws2g/why-you-should-always-append-dom-elements-using-documentfragments

以及更多关于 .innerHTML、.appendChild、.insertAdjacentHTML 的技术说明" "innerHTML += ..." vs "appendChild(txtNode)"

【讨论】:

  • 我使用DocumentFragment 更新了我的 DOMParser 代码,以避免多次附加到 document.body。
【解决方案2】:

也许是一种混合方法?

var dom = new DOMParser().parseFromString('<template>'+ markuptext +'</template>','text/html').head;
document.getElementById('my-div').appendChild(dom.firstElementChild.content);

【讨论】:

    【解决方案3】:

    在此页面上,他们建议第一个解决方案是:

    let tmpl = document.createElement('template');
    tmpl.innerHTML = text;
    shadowRoot.appendChild(tmpl.content.cloneNode(true));
    

    https://developers.google.com/web/fundamentals/web-components/customelements

    【讨论】:

      猜你喜欢
      • 2011-02-26
      • 2012-03-04
      • 1970-01-01
      • 2019-06-27
      • 2023-03-07
      • 1970-01-01
      相关资源
      最近更新 更多