交换2个html元素并在其上保留事件侦听器

Ext*_*Ext 25 javascript jquery dom

有类似的问题,但所有的答案都只是针对内部的内容交换html元素.

我需要交换两个具有大量内容(表格,选择框,输入等)的div与元素上的事件监听器等.不破坏所有这些.

我可以访问jQuery 1.5.所以答案就可以了.

jfr*_*d00 53

要在不丢失事件处理程序或破坏DOM引用的情况下交换两个div,您只需在DOM中移动它们即可.关键是不要更改innerHTML,因为它会从头开始重新创建新的DOM节点,并且这些DOM对象上的所有先前事件处理程序都将丢失.

但是,如果您只是将DOM元素移动到DOM中的新位置,则所有事件都会保持连接,因为DOM元素仅在不更改DOM元素本身的情况下进行重新分配.

这是一个快速函数,可以交换DOM中的两个元素.它应该适用于任何两个元素,只要一个元素不是另一个元素的子元素:

function swapElements(obj1, obj2) {
    // create marker element and insert it where obj1 is
    var temp = document.createElement("div");
    obj1.parentNode.insertBefore(temp, obj1);

    // move obj1 to right before obj2
    obj2.parentNode.insertBefore(obj1, obj2);

    // move obj2 to right before where obj1 used to be
    temp.parentNode.insertBefore(obj2, temp);

    // remove temporary marker node
    temp.parentNode.removeChild(temp);
}
Run Code Online (Sandbox Code Playgroud)

你可以在这里看到它的工作:http://jsfiddle.net/jfriend00/NThjN/


这是一个没有插入临时元素的版本:

function swapElements(obj1, obj2) {
    // save the location of obj2
    var parent2 = obj2.parentNode;
    var next2 = obj2.nextSibling;
    // special case for obj1 is the next sibling of obj2
    if (next2 === obj1) {
        // just put obj1 before obj2
        parent2.insertBefore(obj1, obj2);
    } else {
        // insert obj2 right before obj1
        obj1.parentNode.insertBefore(obj2, obj1);

        // now insert obj1 where obj2 was
        if (next2) {
            // if there was an element after obj2, then insert obj1 right before that
            parent2.insertBefore(obj1, next2);
        } else {
            // otherwise, just append as last child
            parent2.appendChild(obj1);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

工作演示:http://jsfiddle.net/jfriend00/oq92jqrb/


Rob*_*ert 9

这是一个更简单的函数,用于交换两个元素而无需实际重新加载元素...

function swapElements(obj1, obj2) {
    obj2.nextSibling === obj1
    ? obj1.parentNode.insertBefore(obj2, obj1.nextSibling)
    : obj1.parentNode.insertBefore(obj2, obj1); 
}
Run Code Online (Sandbox Code Playgroud)

注意:如果obj1有像YouTube这样的嵌入式视频,则在交换时不会重新加载.这只是元素的位置发生了变化.

  • 非常优雅,没有在这里投票最多的标记div答案 (2认同)
  • 我相信这个答案,`obj2`必须在'obj1`之后.如果`obj1`在`obj2`之前,它们就不会交换.@jfriend00回答将交换两个元素,无论它们是在彼此之前还是之后. (2认同)
  • 只有元素与同一父元素彼此相邻时才能正常工作.将它们分开几个元素或给它们不同的父母,它不会交换它们.它只是一个接一个地移动.只需尝试[这个jsFiddle](http://jsfiddle.net/jfriend00/pp3op71k/)并按"交换A C"按钮. (2认同)