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

如何在JavaScript中交换DOM子节点?,javascript,dom,nodes,Javascript,Dom,Nodes,交换子节点顺序的最简单方法是什么 例如,我希望childNode[3]是childNode[4],反之亦然。不需要克隆。您可以使用以下方法将一个节点移动到另一个节点之前: childNode[4].parentNode.insertBefore(childNode[4], childNode[3]); 您将获得节点的父节点。然后在父节点上调用insertBefore方法,并将其传递给childNode[4]节点,并告诉它希望将其插入childNode[3]之前。这将为您提供交换订单的结果,因此

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


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

不需要克隆。您可以使用以下方法将一个节点移动到另一个节点之前:

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

参考资料


插入到DOM中已经存在于DOM中的任何节点都将首先自动删除,然后再重新插入,因此无需先手动删除它。

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=交换元素(e1,e2)

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

    <div id="d1">D1</div>
    <div id="d2">D2</div>
    <div id="d3">D3</div>
将产生:

<div id="d3">D3</div>
<div id="d1">D1</div>
<div id="d2">D2</div>
D3
D1
D2
尝试以下方法:

  • 获取父元素
  • 存储要交换的
    两个元素
  • 按顺序存储最后一个节点的
    .nextSibling
    例:[1,2,3,4]=>我们想交换3和2,然后存储下一个3和4的下标

  • .插入前(3,2)

  • .插入前(2,下一次插入)
    我需要一个函数来交换两个任意节点,使交换的元素保持在dom中的相同位置。例如,如果a相对于其父级处于位置2,b相对于其父级处于位置0,则b应替换a的前父级的位置2,a应替换b的前父级的子级0

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

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

    在之前或之后使用
    !
    这是香草JS

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

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

    function swap(node1, node2) {
        const afterNode2 = node2.nextElementSibling;
        const parent = node2.parentNode;
        node1.replaceWith(node2);
        parent.insertBefore(node1, afterNode2);
    }
    
    这应该行得通,即使父母不匹配


    -2020年8月94%

    代码说明

    • valval2是要交换的两个节点/元素
    • equiv(index)在作为参数传递的索引处获取DOM中当前的节点/元素
    注意:它将计算注释和文本元素,因此小心xD

    希望这有帮助:)

    函数等价(索引){
    返回Array.prototype.slice.call(document.queryselectoral(“*”))[index];
    }
    功能交换(val,val2){
    设_key=val.key;
    让key=val2.key;
    _键=\u键<\u键?\u键+1:\u键\u;
    让_parent_=val2.parentElement.valueOf();
    if(val.parentElement.children.length==1)
    val.parentElement.appendChild(val2);
    其他的
    val.parentElement.insertBefore(val2,val);
    if(_parent_u.children.length==0)
    _父子(val);
    否则{
    让_sibling uu=equiv(_key uu);
    _父项u.insertBefore(val,u同级u);}
    }
    
    考虑到要交换的两个元素的索引,该解决方案不需要克隆即可工作:
    +1我将其总结为“一个节点一次只能存在于DOM中的一个位置”:因此,将其插入其他位置会将其从当前位置移动。对于未知的节点id,如何实现同样的效果?假设不知道是否存在childNode[3]@armen-您必须有某种方法获得要交换的两个元素。通常有一种方法可以做到这一点,但具体方法取决于特定的HTML情况和结构。只适用于相邻的兄弟姐妹,这不是问题。@brannigan-如果您想通用地交换任意两个元素,您可以在此处看到代码:。这将丢失分配给节点的所有事件处理程序。当node1恰好是node2的后续节点时,该交换函数需要特殊情况:
    if(node1==afterNode2)parent.insertBefore(node1,node2);否则…
    请参见
    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);
    }
    
    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)
        }
    }