我正在寻找处理解析HTML或XHTML(XML序列化)标记并将其插入网页DOM的最佳方法,该网页可以是text/HTML或application/XHTML+XML。不想使用像jQuery这样的库,只关心与最新版本Chrome的兼容性。
我看到了两种可能的解决方案。
-
模板&innerHTML:
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);
我希望有人能指出这两种方法的优点/缺点。
使用模板&innerHTML我假设Chrome会根据页面的内容类型选择解析为HTML/XML,可能没有办法改变这一点。看起来模板&innerHTML允许像<tr><td></td></tr>
这样的片段在<tbody>
之外,而不管它是解析为HTML还是XML。DOMParser也允许这样做,但只有当它被解析为XML时才。
这取决于你的目标是什么。如果你只想按原样附加解析后的html/xhtml,那么就使用.ninnerHTML,它更容易而且通常更快。悬停,根据我的经验,通常,您必须进行某种转换,然后使用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 append的好测试:http://andrew.hedges.name/experiments/innerhtml/
附加到DOm而不创建"dummy"div:https://coderwall.com/p/o9ws2g/why-you-should-always-append-dom-elements-using-documentfragments
以及有关.innerHTML、.appendChild、.insertAdjacentHTML的更多技术说明"innerHTML+="vs";appendChild(txtNode)";
也许是一种混合方法?
var dom = new DOMParser().parseFromString('<template>'+ markuptext +'</template>','text/html').head;
document.getElementById('my-div').appendChild(dom.firstElementChild.content);
在这个页面上,他们建议第一个解决方案是:
let tmpl = document.createElement('template');
tmpl.innerHTML = text;
shadowRoot.appendChild(tmpl.content.cloneNode(true));
https://developers.google.com/web/fundamentals/web-components/customelements