如何在 JavaScript 中交换 DOM 子节点



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

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

不需要

克隆。 您只需将一个节点移动到另一个节点之前即可。 .insertBefore() 方法将它从当前位置获取并将其插入到其他地方(从而移动它(:

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

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

有关插入之前的文档的参考文档。

插入到

DOM 中已有的任何节点都会首先自动删除,然后重新插入,因此无需先手动删除它。

Use .before or .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);
}

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

我可以使用 - 95% 七月 '21

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(;

我需要一个函数来交换两个任意节点,将交换的元素保持在 dom 中的同一位置。 例如,如果 a 相对于其父级处于第 2 位, b 相对于其父级处于第 0 位,则 b 应替换 a 的前父级的位置 2,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);    
}

使用虚拟同级作为临时位置标记,然后.before(或.after(。
它适用于任何兄弟姐妹(不仅是相邻的(,并且还维护事件处理程序。

function swap(a, b) {
    let dummy = document.createElement("span")
    a.before(dummy)
    b.before(a)
    dummy.replaceWith(b)
}
<div id="div1">A</div>
<div id="div2">B</div>
<p> parent<div id="div3">C</div>
</p>
<button onclick="swap(div1, div3)">swap</button>

就像临时变量用于交换变量一样,如果缺少更诡辩的方法。

对于任何没有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>

执行此操作的最佳方法是创建一个临时节点

  function swapNodes(node1, node2) {
      const temp = document.createComment('')
      node2.replaceWith(temp)
      node1.replaceWith(node2)
      temp.replaceWith(node1)
  }

试试这个方法:

  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] => 我们要交换 3 和 2,然后存储 3 的 nextSibling,'4'。

  4. .insertBefore(3,2(;

  5. .insertBefore(2,nextSibling(;

代码说明

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

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

希望这对:)有所帮助

function equiv(index){
      return Array.prototype.slice.call( document.querySelectorAll("*"))[index];
}
function swap (val,val2){
    let _key = val.key;
    let _key_ = val2.key;
    _key_ = _key < _key_ ? _key_+1:_key_;
    let _parent_ = val2.parentElement.valueOf();
    if (val.parentElement.children.length ==1)
        val.parentElement.appendChild(val2);
    else
        val.parentElement.insertBefore(val2,val);
    if (_parent_.children.length ==0)
        _parent_.appendChild(val);
    else{
        let _sibling_ = equiv(_key_);
        _parent_.insertBefore(val,_sibling_);}
}

无需克隆即可工作的解决方案,给定要交换的两个元素的索引:

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)
    }
}

你可以像这样将 DOM 元素与其下一个同级元素交换:

el.parentNode.insertBefore(el, el.nextElementSibling)

或者像这样与以前的兄弟姐妹:

el.parentNode.insertBefore(el, el.previousElementSibling)

如果您的内容是动态的,您可能需要检查el.nextElementSiblingel.previousElementSibling是否为空。

最新更新