如何在JavaScript中交换DOM子节点?

时间:2012-03-16 05:57:39

标签: javascript dom nodes

交换子节点顺序的最简单方法是什么?

例如,我希望childNode [3]为childNode [4],反之亦然。

8 个答案:

答案 0 :(得分:55)

无需克隆。你可以用另一个节点移动一个节点:

childNode[4].parentNode.insertBefore(childNode[4], childNode[3]);

您获得节点的父节点。然后,在父节点上调用insertBefore方法,并将它传递给childNode [4]节点并告诉它您希望在childNode [3]之前插入它。这将为您提供交换订单的结果,因此4完成时将为4。

参考documentation on insertBefore

任何插入DOM中已经存在于DOM中的节点都会先自动删除,然后再插回,这样就无需先手动删除它。

答案 1 :(得分:8)

jfriend00的回答并没有真正交换元素(它只“交换”彼此相邻且仅在同一父节点下的元素)。这没关系,因为这是个问题。

此示例通过克隆元素来交换元素,但无论其位置和DOM级别如何:

// Note: Cloned copy of element1 will be returned to get a new reference back
function exchangeElements(element1, element2)
{
    var clonedElement1 = element1.cloneNode(true);
    var clonedElement2 = element2.cloneNode(true);

    element2.parentNode.replaceChild(clonedElement1, element2);
    element1.parentNode.replaceChild(clonedElement2, element1);

    return clonedElement1;
}

编辑:添加了新引用的返回(如果你想保留引用,例如访问属性“parentNode”(否则它会丢失))。示例:e1 = exchangeElements(e1,e2);

答案 2 :(得分:4)

使用.before.after

这是香草JS!

childNode[3].before(childNode[4]);

childNode[4].after(childNode[3]);

要获得更多耐久性交换,请尝试:

function swap(node1, node2) {
    const afterNode2 = node2.nextElementSibling;
    const parent = node2.parentNode;
    node1.replaceWith(node2);
    parent.insertBefore(node1, afterNode2);
}

这应该有效,即使父母不匹配

Can I Use - 86%2018年11月

答案 3 :(得分:1)

对于没有cloneNode的任何节点的实际交换:

    <div id="d1">D1</div>
    <div id="d2">D2</div>
    <div id="d3">D3</div>

使用SwapNode函数(使用PrototypeJS):

function SwapNode(N1, N2)  {
N1 = $(N1);
N2 = $(N2);

if (N1 && N2) {
    var P1 = N1.parentNode;
    var T1 = document.createElement("span");    
    P1.insertBefore(T1, N1);

    var P2 = N2.parentNode;
    var T2 = document.createElement("span");
    P2.insertBefore(T2, N2);

    P1.insertBefore(N2, T1);
    P2.insertBefore(N1, T2);

    P1.removeChild(T1);
    P2.removeChild(T2);
}
}
SwapNode('d1', 'd2');
SwapNode('d2', 'd3');

将产生:

<div id="d3">D3</div>
<div id="d1">D1</div>
<div id="d2">D2</div>

答案 4 :(得分:0)

试试这个方法:

  1. Get the parent element
  2. 存储two elements you want to swap
  3. 存储.nextSibling of the node that is last in order 例如:[1,2,3,4] =&gt;我们要换掉3&amp; 2然后存储nextSibling of 3,&#39; 4&#39;

  4. .insertBefore(3,2);

  5. .insertBefore(2,nextSibling);

答案 5 :(得分:0)

我需要一个函数来交换两个任意节点,保持交换元素在dom中的相同位置。例如,如果 a 相对于其父级位于第2位且 b 相对于其父级位于位置0,则 b 应替换位置2 a 的前父母和 a 应该替换 b 的前父母的孩子0。

这是我的解决方案,它允许交换在dom的完全不同的部分。请注意,交换不能是简单的三步交换。首先需要从dom中删除这两个元素中的每一个,因为它们可能有需要更新的兄弟姐妹等。

解决方案:我放入两个持有者div来保存每个节点的位置以保持相对兄弟顺序。然后我重新插入另一个占位符中的每个节点,保持交换之前交换节点的相对位置。 (我的解决方案类似于巴克的)。

function swapDom(a,b) 
{
     var aParent = a.parentNode;
     var bParent = b.parentNode;

     var aHolder = document.createElement("div");
     var bHolder = document.createElement("div");

     aParent.replaceChild(aHolder,a);
     bParent.replaceChild(bHolder,b);

     aParent.replaceChild(b,aHolder);
     bParent.replaceChild(a,bHolder);    
}

答案 6 :(得分:0)

代码说明

  • val val2 是要交换的2个节点/元素
  • equiv( index 获取作为参数传递的索引处DOM中的当前节点/元素

注意:它将计算注释和文本元素,因此请小心xD

希望这会有所帮助:)

{# This will call \Mynamespace\Mypackage\Myclass::getStuff('arg1', 'arg2'); #}
{% set result = callstatic('\\Mynamespace\\Mypackage\\Myclass', 'getStuff', 'arg1', 'arg2') %}

答案 7 :(得分:0)

给出两个要交换元素的索引后,无需克隆即可运行的解决方案:

function swapChildren(parentElement, index1, index2) {

    if (index1 === index2)
        return

    if (index1 > index2) {

        const temp = index1

        index1 = index2
        index2 = temp
    }

    const { [index1]: element1, [index2]: element2 } = parentElement.childNodes

    if (index2 === index1 + 1) {
        parentElement.insertBefore(element2, element1)
    } else {

        const reference = element2.nextSibling

        parentElement.replaceChild(element2, element1)
        parentElement.insertBefore(element1, reference)
    }
}