How to swap DOM child nodes in JavaScript?

前端 未结 8 1426
时光说笑
时光说笑 2020-12-03 04:29

What is the easiest way to swap the order of child nodes?

For example I want childNode[3] to be childNode[4] and vice-versa.

相关标签:
8条回答
  • 2020-12-03 04:48

    Use .before or .after!

    This is vanilla JS!

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

    or

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

    For more durability swapping, try:

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

    This should work, even if the parents don't match

    Can I Use - 94% Aug 2020

    0 讨论(0)
  • 2020-12-03 04:50

    There is no need for cloning. You can just move one node before the other with this:

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

    You get the parent of the node. You then call the insertBefore method on the parent and you pass it the childNode[4] node and tell it you want it inserted before childNode[3]. That will give you the result of swapping their order so 4 will be before 3 when it's done.

    Reference documentation on insertBefore.

    Any node that is inserted into the DOM that is already in the DOM is first removed automatically and then inserted back so there is no need to manually remove it first.

    0 讨论(0)
  • 2020-12-03 04:51

    I needed a function to swap two arbitrary nodes keeping the swapped elements in the same place in the dom. For example, if a was in position 2 relative to its parent and b was in position 0 relative to its parent, b should replace position 2 of a's former parent and a should replace child 0 of b's former parent.

    This is my solution which allows the swap to be in completely different parts of the dom. Note that the swap cannot be a simple three step swap. Each of the two elements need to be removed from the dom first because they may have siblings that would need updating, etc.

    Solution: I put in two holder div's to hold the place of each node to keep relative sibling order. I then reinsert each of the nodes in the other's placeholder, keeping the relative position that the swapped node had before the swap. (My solution is similar to Buck's).

    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);    
    }
    
    0 讨论(0)
  • 2020-12-03 04:54

    Code Explanation

    • val & val2 are the 2 nodes/elements to be swapped
    • equiv(index) gets the present node/element in DOM at index passed as the paramter

    NOTE: It will count comment & text elements so take care xD

    Hopes this helps :)

    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_);}
    }
    
    0 讨论(0)
  • 2020-12-03 04:58

    Try this method:

    1. Get the parent element
    2. Store the two elements you want to swap
    3. Store the .nextSibling of the node that is last in order eg: [1,2,3,4] => we want to swap 3 & 2 then store nextSibling of 3, '4'.

    4. .insertBefore(3,2);

    5. .insertBefore(2,nextSibling);
    0 讨论(0)
  • 2020-12-03 05:03

    A solution that works without cloning, given the indices of the two elements to swap:

    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)
        }
    }
    
    0 讨论(0)
提交回复
热议问题