Javascript 如何以最小的性能开销将DOM元素的内容包装到另一个元素中?

Javascript 如何以最小的性能开销将DOM元素的内容包装到另一个元素中?,javascript,html,dom,element,Javascript,Html,Dom,Element,我希望将DOM元素的实时内容包装到另一个元素中,保持所有结构和所有附加的事件侦听器不变 例如,我想要这个 <div id="original"> Some text <i class="icon></i> </div> 成为 <div id="original"> <div id="wrapper"> Some text <i class="icon></i> </div&

我希望将DOM元素的实时内容包装到另一个元素中,保持所有结构和所有附加的事件侦听器不变

例如,我想要这个

<div id="original">
  Some text <i class="icon></i>
</div>
成为

<div id="original">
  <div id="wrapper">
    Some text <i class="icon></i>
  </div>
</div>
最好不使用jQuery。

更新答案:

这应该比我以前的答案更好,代码更少

var content = document.getElementById("myList").innerHTML;
document.getElementById("myList").innerHTML = "<div id='wrapper'></div>"
document.getElementById("wrapper").innerHTML = content;
创建包装器元素。 获取我的列表内容。 将包装器元素添加到myList。 将myList内容添加为包装器元素的子元素。 如果除了ID之外没有其他东西可以区分节点,并且假设原始节点有多个子节点,那么创建一个新的父节点并插入以下内容可能会更简单:

var original = document.getElementById('original');
var parent = original.parentNode;

var wrapper = document.createElement('DIV');
parent.replaceChild(wrapper, original);
wrapper.appendChild(original);
然后将ID移动到正确的位置:

wrapper.id = original.id;
original.id = 'wrapper';
当然要注意,变量original和wrapper现在指向“错误”元素

编辑哦,你想让听众保持联系。。。从技术上讲,它们仍然是,但它们现在连接到内部元素,而不是外部元素

编辑2个修改后的答案,将事件侦听器附加到现在是外部div的原始元素:

var original = document.getElementById('original');
var wrapper = document.createElement('DIV');
wrapper.id = 'wrapper';
while (original.firstChild) {
    wrapper.appendChild(original.firstChild);
}
original.appendChild(wrapper);
这只需依次将每个子节点从原始div移动到新父节点,然后将新父节点移回子节点最初所在的位置即可

与此答案的前一版本相比,其缺点是您必须逐个迭代所有子级


请参见演示

或者,也可以这样做。它还将在相邻的结果div中显示结果

一些文本 做吧

函数myFunction{ var org=document.getElementByIdoriginal; var i=org.innerHTML;//获取i标记内容 var wrap=document.createElementdiv;//create div wrap.id=wrapper;//设置包装的id wrap.innerHTML=i//将其设置为i标记的内容 org.innerHTML=;//首先清除原始文件 org.appendChildwrap;//追加包装器及其内容 var result=org.outerHTML; document.getElementByIdresult.innerText=结果; }
这是不够的-Wrapper有多个子节点,这将完全销毁任何附加的事件侦听器。使用serialization.innerHTML操作DOM元素几乎总是错误的。它应该只用于创建全新的元素。与Gerard的答案相同的问题是——永远不要使用序列化来移动DOM元素。它会销毁那些元素拥有的所有事件处理程序。谢谢!因此不可能保留侦听器,但可以避免在循环中应用多个DOM更改?@DmitriZaitsev我不这么认为-您可以在单个子节点周围放置一个新的父节点,但我不相信有任何方法可以在没有循环的情况下将多个子节点从一个父节点移动到另一个父节点。也许是文档片段?@DmitriZaitsev如果你可以摆脱内部元素上的事件处理程序,那么删除的答案应该可以工作。我需要它作为一个通用库,它应该没有副作用,所以我需要保留两侧的侦听器。我已经查看了文档片段,但似乎您仍然需要逐个删除子文档;
var original = document.getElementById('original');
var wrapper = document.createElement('DIV');
wrapper.id = 'wrapper';
while (original.firstChild) {
    wrapper.appendChild(original.firstChild);
}
original.appendChild(wrapper);