我正在开发一个应用程序,该应用程序使用一些客户端模板来呈现数据,并且大多数 javascript 模板引擎返回一个带有标记的简单字符串,由开发人员将该字符串插入 DOM。
我四处搜索,看到一群人建议使用空 div,将其 innerHTML 设置为新字符串,然后像这样遍历该 div 的子节点
var parsedTemplate = 'something returned by template engine';
var tempDiv = document.createElement('div'), childNode;
var documentFragment = document.createDocumentFragment;
tempDiv.innerHTML = parsedTemplate;
while ( childNode = tempDiv.firstChild ) {
documentFragment.appendChild(childNode);
}
而 TADA,documentFragment
现在包含已解析的模板。但是,如果我的模板恰好是 tr
,则在其周围添加 div 不会实现预期的行为,因为它会将 td
的内容添加到行。
有人知道解决这个问题的好方法吗?现在我正在检查将插入已解析模板的节点,并根据其标签名称创建一个元素。我什至不确定还有其他方法可以做到这一点。
在搜索时我遇到了 this discussion在 w3 邮件列表上,但不幸的是没有有用的解决方案。
最佳答案
您可以将 DOMParser 用作 XHTML 来避免 HTML“自动更正”DOM 喜欢执行的操作:
var parser = new DOMParser(),
doc = parser.parseFromString('<tr><td>something returned </td><td>by template engine</td></tr>', "text/xml"),
documentFragment = document.createDocumentFragment() ;
documentFragment.appendChild( doc.documentElement );
//fragment populated, now view as HTML to verify fragment contains what's expected:
var temp=document.createElement('div');
temp.appendChild(documentFragment);
console.log(temp.outerHTML);
// shows: "<div><tr><td>something returned </td><td>by template engine</td></tr></div>"
这与使用带有临时 div 的朴素 innerHTML 形成对比:
var temp=document.createElement('div');
temp.innerHTML='<tr><td>something returned </td><td>by template engine</td></tr>';
console.log(temp.outerHTML);
// shows: '<div>something returned by template engine</div>' (bad)
通过将模板视为 XHTML/XML(确保其格式正确),我们可以改变 HTML 的常规规则。 DOMParser 的覆盖范围应该与对 documentFragment 的支持相关联,但是在 firefox 的一些旧副本(个位数版本)上,您可能需要使用 importNode()。
作为一个可重用的函数:
function strToFrag(strHTML){
var temp=document.createElement('template');
if( temp.content ){
temp.innerHTML=strHTML;
return temp.content;
}
var parser = new DOMParser(),
doc = parser.parseFromString(strHTML, "text/xml"),
documentFragment = document.createDocumentFragment() ;
documentFragment.appendChild( doc.documentElement );
return documentFragment;
}
关于javascript - 有什么方法可以从通用的 HTML 片段创建文档片段吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22620493/