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

Myf*_*wik 31 javascript dom nodes

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

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

jfr*_*d00 60

没有必要进行克隆.您可以使用以下方法将一个节点移到另一个节点之前:

childNode[4].parentNode.insertBefore(childNode[4], childNode[3]);
Run Code Online (Sandbox Code Playgroud)

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

关于insertBefore的参考文档.

插入DOM中已经存在于DOM中的任何节点首先会自动删除,然后再插回,因此无需先手动删除它.

  • +1我总结说"一个节点一次只能存在于DOM中的一个位置":因此将其插入其他位置会使其从当前位置移动. (7认同)
  • 仅适用于相邻的兄弟姐妹,这不是问题。 (3认同)
  • @brannigan-如果要通用交换任何两个元素,可以在此处查看该代码:[交换两个HTML元素](/sf/ask/750189051/ -event-listeners-them / 10717422#10717422)。 (2认同)

Gib*_*olt 16

使用.before.after

这是香草JS!

childNode[3].before(childNode[4]);
Run Code Online (Sandbox Code Playgroud)

或者

childNode[4].after(childNode[3]);
Run Code Online (Sandbox Code Playgroud)

如需更多耐用性交换,请尝试:

function swap(node1, node2) {
    const afterNode2 = node2.nextElementSibling;
    const parent = node2.parentNode;
    node1.replaceWith(node2);
    parent.insertBefore(node1, afterNode2);
}
Run Code Online (Sandbox Code Playgroud)

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

我可以使用- 95% 21 年 7 月

  • 当node1恰好是node2的后继者时,交换函数需要一个特殊情况:`if (node1 === afterNode2)parent.insertBefore(node1, node2); 否则...`请参阅http://jsfiddle.net/cayhorstmann/c9uqme45 (2认同)

Sta*_*anE 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;
}
Run Code Online (Sandbox Code Playgroud)

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

  • 这将丢失分配给节点的任何事件处理程序. (6认同)

Jac*_*ner 7

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

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

解决方案:我放入两个 Holder 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);    
}
Run Code Online (Sandbox Code Playgroud)