使用纯Javascript将div内容移动到另一个div中

5

我有这个HTML设置:

<div class="one">
    <div class="text">One</div>
    <div class="text">One</div>
</div>

<div class="two">
    <div class="text">Two</div>
    <div class="text">Two</div>
</div>

我希望能使用纯JavaScript(不是jQuery)将

的内容移动到
中,以便我们得到:

<div class="one">
    <div class="text">One</div>
    <div class="text">One</div>
    <div class="text">Two</div>
    <div class="text">Two</div>
</div>

这个问题最快的解决方式是什么?要考虑毫秒级性能。

可能是 https://dev59.com/6Gw15IYBdhLWcg3w6f40 的重复问题。 - swetansh kumar
1
我也看到了那个问答,但我认为这个问题本身就很重要(并考虑了微性能)。 - Gary Woods
给div分配id 1和2,并使用JavaScript:document.getElementById('1').appendChild( document.getElementById('2') ); 你试过了吗? - Shifat
在它们被移动之前,这些元素是否已经附加了事件处理程序? - Yoshi
@Yoshi 是的,他们会。 - Henrik Petterson
3个回答

8

个人而言,我更倾向于使用 insertAdjacentElement ,因为它可以让你更好地控制元素的放置位置,但需要注意它的浏览器支持情况

const one = document.querySelector('.one');
const two = document.querySelector('.two');

[...two.children].forEach(element => {
  one.insertAdjacentElement('beforeEnd', element);
});
<div class="one">
    <div class="text">One</div>
    <div class="text">One</div>
</div>

<div class="two">
    <div class="text">Two</div>
    <div class="text">Two</div>
</div>

需要注意的是,我使用了ES2015语法。


1
可以进行一些性能比较吗?毕竟两种方法的实现方式是不同的,对比一下 James 的答案如何? - Henrik Petterson
此外,insertAdjacentElement() 的浏览器支持似乎很好:https://caniuse.com/#feat=insert-adjacent - Henrik Petterson
@HenrikPetterson 如果我有时间的话,我会帮你测试的,但是你可以在jsperf.com上自行测试。 - evolutionxbox
1
@HenrikPetterson 感谢这个解决方案还保留了事件监听器 http://jsbin.com/zuwonabuli/edit?html,js,console,output - evolutionxbox

4

可能的重复问题实际上有一个本地答案-使用.appendChild()将节点移动。

在您的情况下,代码应该如下所示:

var one = document.querySelector(".one");
var children = document.querySelector(".two").children;

Array.prototype.forEach.call(children, function (child) {
    one.appendChild(child);
});

你可以使用 while 循环遍历它,并且如果你想要性能提升,可以使用 DocumentFragment
var one = document.querySelector(".one");
var children = document.querySelector(".two").children;
var frag = document.createDocumentFragment();

while (children.length) {
    frag.appendChild(children[0]);
}

one.appendChild(frag);

更快的解决方案(来源):
var one = document.querySelector(".one");
var children = [...document.querySelector(".two").children];
var frag = document.createDocumentFragment();
var i = 0;
var il = children.length;

while (i < il) {
    frag.appendChild(children[i]);
    i += 1;
}

one.appendChild(frag);

1
太好了!有没有可能进行性能比较,看看与evolutionxbox的答案相比,两种方法都有哪些不同? - Henrik Petterson
2
这些元素确实已经附加了事件处理程序。 这个解决方案仍然有效吗?感谢您的测试。 - Henrik Petterson
1
@HenrikPetterson 是的 - appendChild 会保留事件监听器(我想 insertAdjacentElement 也会,但我没有测试过)。除非您委派事件,否则 innerHTML 不会保留事件监听器。 - James Long
1
@HenrikPetterson - 这两种解决方案差别不大,但是 evolutionbox 的似乎偶尔会更快一些。如果速度很重要,请使用真实数据测试这两种解决方案,但数字似乎暗示 evolutionbox 的解决方案将获胜。 - James Long
2
@JamesLong 我也不会猜到。 - evolutionxbox
显示剩余5条评论

0

使用纯JavaScript编写,兼容大多数浏览器和旧版本,使用querySelector获取第一个找到的类比使用getElementsByClassName更具性能优势,后者返回一个数组。

var one = document.querySelector('.one');
var two = document.querySelector('.two');

如果您想将其设置为最后一个子元素,则:
while(two.children.length>0)
    one.appendChild(two.children[0]);

如果您想将其作为第一个子元素,则将内容移动到“one”的第一个子元素之前
while(two.children.length>0)
    one.insertBefore(two.children[0], one.firstChild);

最后,对于类似情况有用的干净替代方法可以使用以下代码:one
one.innerHTML = two.innerHTML;

注意:这个最后的实现会删除所有“one”的内容,并将内容设置为“two”

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接