Swap two html elements and preserve event listeners on them

前端 未结 8 1612
醉酒成梦
醉酒成梦 2020-12-05 17:55

There are similar questions, but all the answers are for swapping html elements only for the content inside.

I need to swap two divs, with lots of content in them (t

相关标签:
8条回答
  • 2020-12-05 18:05

    My simple function seems to be the shortest and most widely compatible. It doesn't need placeholders or reload elements or anything messy like that:

    function swapElements(el1, el2) {
        var p2 = el2.parentNode, n2 = el2.nextSibling
        if (n2 === el1) return p2.insertBefore(el1, el2)
        el1.parentNode.insertBefore(el2, el1);
        p2.insertBefore(el1, n2);
    }
    
    0 讨论(0)
  • 2020-12-05 18:08

    This all is very strange considering the fact that o1.swapNode(o2); works very well in IE for very long time. In my case of object and text nodes intermixed, works only one version (already shown here):

    let t = document.createElement("div");
    o1.parentNode.insertBefore(t, o1);
    o2.parentNode.insertBefore(o1, o2);
    t.parentNode.insertBefore(o2, t);
    t.parentNode.removeChild(t);
    

    Yes, I hate creating temporary node, but the above version without this trick fails if you use it straight (without calling function). Sometimes you don't want to call a function.

    0 讨论(0)
  • 2020-12-05 18:11

    If you keep track of the two elements' parentNodes and the nextSibling of one, you can swap two elements with their children without any temporary placeholders.

    If the second element is an only child, or the last child of its parent, its replacement is (properly) appended to the parent.

    function swap(a, b){
        var p1= a.parentNode, p2= b.parentNode, sib= b.nextSibling;
        if(sib=== a) sib= sib.nextSibling;
        p1.replaceChild(b, a);
        if(sib) p2.insertBefore(a, sib);
        else p2.appendChild(a);
        return true;
    }
    
    0 讨论(0)
  • 2020-12-05 18:14

    This somewhat depends on how your events are bound to the elements you're swapping. If you're using jQuery, then this answer is all you need, really.

    The main thing is not to delete or removeChildnode the elements, and just copy-paste the html elsewhere. In doing so, some browsers will clear all resources (event handlers included) so, bound events will be lost. Though IE is notorious for leaking memory when it comes to dynamically bound events. It's hard to predict how various browsers will behave, really.

    Basically, I'd say: swap elements in any way you like, except for copy/paste HTML strings, and bind your events using jQuery's .live() method. Since I don't think 1.5 has the .on method

    0 讨论(0)
  • 2020-12-05 18:15

    It's really easy if you're swapping elements next to each other:

    <div class="container">
       <div class="item">Item 1</div>
       <div class="item">Item 2</div>
    </div>
    

    $('.container .item:nth-child(2)').insertBefore('.container .item:nth-child(1)');

    0 讨论(0)
  • 2020-12-05 18:19

    This is a simpler function for swapping two elements without actually reloading the element...

    function swapElements(obj1, obj2) {
        obj2.nextSibling === obj1
        ? obj1.parentNode.insertBefore(obj2, obj1.nextSibling)
        : obj1.parentNode.insertBefore(obj2, obj1); 
    }
    

    Note: if the obj1 has an embedded video like YouTube, it will not reload when swapped. It's just the position of the elements that changed.

    0 讨论(0)
提交回复
热议问题