My original post featured DOMParser
, a JavaScript API for converting HTML strings into DOM nodes. While DOMParser
works well in most cases, that API does have some rough edges and isn't as performant as another API: ContextualFragment
. I've rewritten this post to highlight ContextualFragment
, but if you still care to learn about DOMParser
, please see the original text at the bottom of this post.
我的原始文章介绍了DOMParser
,这是一个JavaScript API,用于将HTML字符串转换为DOM节点。 尽管DOMParser
在大多数情况下都能很好地工作,但该API确实有一些粗糙之处,并且不如另一个API: ContextualFragment
性能强。 我将这篇文章改写为突出显示ContextualFragment
,但是如果您仍然想了解DOMParser
,请参阅本文底部的原始文本。
It wasn't too long ago that browsers were mostly stagnant when it came to implementing new APIs and features, leading to the rise of MooTools (FTW), jQuery, Dojo Toolkit, Prototype, and likewise JavaScript toolkits. Then we started doing more client side rendering and were forced to use a variety of tricks to handle templates, including massive HTML strings in our JavaScript and even abusing <script>
tags to hold our templates.
不久之前,浏览器在实现新的API和功能时大多停滞不前,从而导致MooTools(FTW),jQuery,Dojo Toolkit,Prototype和JavaScript工具包的兴起。 然后,我们开始做更多的客户端渲染,并被迫使用各种技巧来处理模板,包括JavaScript中的大量HTML字符串,甚至滥用<script>
标签来保存模板。
Of course after you've placed your content into the template, you then need to turn that string into DOM nodes, and that process had a few of its own tricks, like creating an offscreen, dummy <div>
, setting its innerHTML
to the string value, grabbing the firstChild
, and moving the node to its desired node. Each JavaScript toolkit would use its own strategy for converting string to DOM, highlighting the need for a standard method to accomplish this task.
当然,在将内容放入模板后,您需要将该字符串转换为DOM节点,并且该过程有一些自己的技巧,例如创建屏幕外的虚拟<div>
,将其innerHTML
设置为字符串值,获取firstChild
,然后将节点移动到所需的节点。 每个JavaScript工具箱都将使用其自己的策略将字符串转换为DOM,从而强调需要一种标准方法来完成此任务。
Today there's a little known (but standard) way for converting string to DOM with JavaScript: ContextualFragment
.
今天,有一种鲜为人知(但标准)的方法,可以使用JavaScript将字符串转换为DOM: ContextualFragment
。
I've touched on DocumentFragment
to create and store DOM nodes for performance in the past, but that post illustrated element creation via document.createElement
:
我过去曾接触过DocumentFragment
创建和存储DOM节点以提高性能,但是该文章通过document.createElement
说明了元素创建:
// Use a DocumentFragment to store and then mass inject a list of DOM nodes
var frag = document.createDocumentFragment();
for(var x = 0; x < 10; x++) {
var li = document.createElement("li");
li.innerHTML = "List item " + x;
frag.appendChild(li);
}
To create DOM nodes from a string of HTML we'll use document.createRange().createContextualFragment
:
为了从HTML字符串创建DOM节点,我们将使用document.createRange().createContextualFragment
:
let frag = document.createRange().createContextualFragment('
One
Two
');
console.log(frag);
/*
#document-fragment
One
Two
*/
DocumentFragment
objects share most of the methods that NodeList
objects have, so you can use typical DOM methods like querySelector
and querySelectorAll
as well DOM traversal properties like firstChild
with the resulting DocumentFragment
:
DocumentFragment
对象共享NodeList
对象拥有的大多数方法,因此您可以使用典型的DOM方法(例如querySelector
和querySelectorAll
)以及DOM遍历属性(例如firstChild
与生成的DocumentFragment
:
let firstChild = frag.firstChild;
let firstDiv = frag.querySelector('div');
let allDivs = frag.querySelectorAll('div');
When you're ready to inject all of the created DOM nodes, you can simply execute:
当准备注入所有创建的DOM节点时,只需执行以下命令即可:
// "placementNode" will be the parent of the nodes within the DocumentFragment
placementNode.appendChild(frag);
You can also inject nodes one at a time:
您也可以一次注入一个节点:
placementNode.appendChild(frag.firstChild);
The document.createRange().createContextualFragment
function is an awesome, sane method for converting strings to DOM nodes within JavaScript. Ditch your old shims and switch to this performant, simple API!
document.createRange().createContextualFragment
函数是一种很棒的,明智的方法,用于将字符串转换为JavaScript中的DOM节点。 抛弃旧的垫片,并切换到该高性能,简单的API!
原始帖子: DOMParser
(The Original Post: DOMParser
)
Today we have a standard way for converting string to DOM with JavaScript:
DOMParser
.今天,我们有了使用JavaScript将字符串转换为DOM的标准方法:
DOMParser
。JavaScript (The JavaScript)
All you need to do is create a
DOMParser
instance and use itsparseFromString
method:您需要做的就是创建一个
DOMParser
实例并使用其parseFromString
方法:let doc = new DOMParser().parseFromString('<div><b>Hello!</b></div>', 'text/html');
let doc = new DOMParser().parseFromString('<div><b>Hello!</b></div>', 'text/html');
Returned is a
document
containing the nodes generated from your string. With saiddocument
you can use standard node traversal methods to retrieve the nodes we specified in our string:返回的是包含从字符串生成的节点的
document
。 通过上述document
您可以使用标准节点遍历方法来检索我们在字符串中指定的节点:let doc = new DOMParser().parseFromString('<div><b>Hello!</b></div>', 'text/html'); let div = doc.body.firstChild; let divs = doc.body.querySelectorAll('div');
You don't need a single wrapping element like JSX components -- you can have sibling elements:
您不需要像JSX组件那样的单个包装元素-您可以拥有同级元素:
let doc = new DOMParser().parseFromString('<div>1</div><div>2</div>', 'text/html'); let firstDiv = doc.body.firstChild; let secondDiv = firstDiv.nextSibling;
let doc = new DOMParser().parseFromString('<div>1</div><div>2</div>', 'text/html'); let firstDiv = doc.body.firstChild; let secondDiv = firstDiv.nextSibling;
Here's a simple wrapping function for
DOMParser
to retrieve the nodes:这是
DOMParser
检索节点的简单包装函数:let getNodes = str => new DOMParser().parseFromString(str, 'text/html').body.childNodes; let nodes = getNodes('<div>1</div><div>2</div>'); // [div, div]
The
DOMParser
object is an awesome, sane method for converting strings to DOM nodes within JavaScript. Ditch your old shims and switch to this efficient, simple API!
DOMParser
对象是一种很棒的,理智的方法,用于将字符串转换为JavaScript中的DOM节点。 抛弃旧的垫片,并切换到此高效,简单的API!