将任意 HTML 插入 DocumentFragment
我知道最近将 innerHTML
添加到文档片段讨论过,并有望包含在 DOM 标准中。但是,您同时应该使用什么解决方法?
也就是说,
var html = '<div>x</div><span>y</span>';
var frag = document.createDocumentFragment();
我想要 frag
内部的 div
和 span
,并使用简单的一行代码。
无循环的奖励积分。允许使用 jQuery,但我已经尝试过 $(html).appendTo(frag)
;之后 frag
仍然是空的。
I know that adding innerHTML
to document fragments has been recently discussed, and will hopefully see inclusion in the DOM Standard. But, what is the workaround you're supposed to use in the meantime?
That is, take
var html = '<div>x</div><span>y</span>';
var frag = document.createDocumentFragment();
I want both the div
and the span
inside of frag
, with an easy one-liner.
Bonus points for no loops. jQuery is allowed, but I've already tried $(html).appendTo(frag)
; frag
is still empty afterward.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
这是现代浏览器中的一种无需循环的方法:
或者作为可重复使用的
更新:
我找到了一种更简单的方法来使用 Pete 的主要思想,它将 IE11 添加到混合中:
覆盖范围比
方法更好,并且在 IE11、Ch、FF 中测试正常。
提供实时测试/演示http://pagedemos.com/str2fragment/
Here is a way in modern browsers without looping:
or, as a re-usable
UPDATE:
I found a simpler way to use Pete's main idea, which adds IE11 to the mix:
The coverage is better than the
<template>
method and tested ok in IE11, Ch, FF.Live test/demo available http://pagedemos.com/str2fragment/
目前,仅使用字符串填充文档片段的唯一方法是创建一个临时对象,并循环遍历子对象以将它们附加到片段中。
如果您想创建整个文档,请使用 DOMParser。看看这个答案。
代码:
一行(两行以提高可读性)(输入:
String html
,输出:DocumentFragment frag
):Currently, the only way to fill a document fragment using only a string is to create a temporary object, and loop through the children to append them to the fragment.
If you want to create a whole document, use the DOMParser instead. Have a look at this answer.
Code:
A one-liner (two lines for readability) (input:
String html
, output:DocumentFragment frag
):使用 Range.createContextualFragment:
请注意,此方法与 < code>方法是:
Range.createContextualFragment 得到更广泛的支持(IE11 刚刚获得它,Safari、Chrome 和 FF 已经拥有它一段时间了) while)。
HTML 中的自定义元素将立即随范围升级,但前提是使用模板克隆到真实文档中。模板方法有点“惰性”,这可能是可取的。
Use Range.createContextualFragment:
Note that the primary differences between this approach and the
<template>
approach are:Range.createContextualFragment is a bit more widely supported (IE11 just got it, Safari, Chrome and FF have had it for a while).
Custom elements within the HTML will be upgraded immediately with the range, but only when cloned into the real doc with template. The template approach is a bit more 'inert', which may be desirable.
没有人提供所要求的“简单的一句话”。
给定变量…………
下面的行就可以解决问题(在 Firefox 67.0.4 中):
No one ever provided the requested "easy one-liner".
Given the variables…
… the following line will do the trick (in Firefox 67.0.4):
@PAEz 指出@RobW 的方法不包括元素之间的文本。这是因为
children
只获取元素,而不是节点。更可靠的方法可能如下:在较大的 HTML 块上性能可能会受到影响,但是它与许多旧版浏览器兼容并且简洁。
@PAEz pointed out that @RobW's approach does not include text between elements. That's because
children
only grabs Elements, and not Nodes. A more robust approach might be as follows:Performance may suffer on larger chunks of HTML, however, it is compatible with many older browsers, and concise.
createDocumentFragment 创建一个空的 DOM“容器”。 innerHtml 和其他方法仅适用于 DOM 节点(而不是容器),因此您必须首先创建节点,然后将它们添加到片段中。您可以使用一种痛苦的appendChild 方法来完成此操作,也可以创建一个节点并修改它的innerHtml 并将其添加到您的片段中。
使用 jquery,您只需将 html 保留并构建为字符串即可。如果你想将它转换为 jquery 对象以对其执行类似 jquery 的操作,只需执行 $(html) 即可在内存中创建一个 jquery 对象。准备好附加它后,您只需将其附加到页面上的现有元素即可
createDocumentFragment creates an empty DOM "container". innerHtml and other methods work only on DOM nodes (not the container) so you have to create your nodes first and then add them to the fragment. You can do it using a painful method of appendChild or you can create one node and modify it's innerHtml and add it to your fragment.
with jquery you simply keep and build your html as a string. If you want to convert it to a jquery object to perform jquery like operations on it simply do $(html) which creates a jquery object in memory. Once you are ready to append it you simply append it to an existing element on a page
就像 @dandavis 所说,有一个使用模板标签的标准方法。
但是如果你想支持IE11并且需要解析像'test'这样的表格元素,你可以使用这个函数:
Like @dandavis said, there is a standard way by using the template-tag.
But if you like to support IE11 and you need to parse table elements like '<td>test', you can use this function:
我会选择这样的东西..
通过这种方式,您可以将内容保存在 Range 对象内,并且可以免费获得所有需要的方法。
您可以在此处找到所有 Range 方法和属性的列表 https:// developer.mozilla.org/en-US/docs/Web/API/Range
注意:完成后记得使用
detatch()
方法以避免泄漏并提高性能。I would go with something like this..
This way you keep the content inside a Range object and you get all the needed methods for free.
You can find the list of all Range methods and properties here https://developer.mozilla.org/en-US/docs/Web/API/Range
Note: Remember to use
detatch()
method once you are done with it to avoid leaks and improve performance.这是一个 x 浏览器解决方案,在 IE10、IE11、Edge、Chrome 和 FF 上进行了测试。
Here is a x-browser solution, tested on IE10, IE11, Edge, Chrome and FF.
要使用尽可能少的行来完成此操作,您可以将上面的内容包装在另一个 div 中,这样您就不必多次循环或调用appendchild。使用 jQuery(正如您所提到的,是允许的)您可以非常快速地创建一个独立的 dom 节点并将其放置在片段中。
To do this with as little lines as possible, you could wrap your content above in another div so you do not have to loop or call appendchild more than once. Using jQuery (as you mentioned is allowed) you can very quickly create an unattached dom node and place it in the fragment.