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);
}
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);
}
}
}
8条答案
按热度按时间50pmv0ei1#
要在不丢失事件处理程序或破坏DOM引用的情况下交换两个div,只需在DOM中移动它们。关键是不要更改innerHTML,因为这会从头开始重新创建新的DOM节点,并且这些DOM对象上的所有先前事件处理程序都会丢失。
但是,如果您只是将DOM元素移动到DOM中的新位置,则所有事件都保持附加状态,因为DOM元素只是重新设置父级,而不会更改DOM元素本身。
这里有一个快速的函数,可以交换DOM中的两个元素。它应该与任何两个元素一起工作,只要其中一个不是另一个的子元素:
你可以在这里看到它的工作:http://jsfiddle.net/jfriend00/NThjN/
下面是一个没有插入临时元素的版本:
工作演示:http://jsfiddle.net/jfriend00/oq92jqrb/
r7s23pms2#
这是一个更简单的函数,用于交换两个元素,而无需实际重新加载元素。
注意:如果obj1有一个嵌入的视频,如YouTube,它将不会重新加载时交换。只是元素的位置改变了。
brc7rcf03#
如果跟踪两个元素的parentNode和其中一个元素的nextSibling,则可以将两个元素与其子元素交换,而无需任何临时占位符。
如果第二个元素是唯一的子元素,或者它的父元素的最后一个子元素,那么它的替换被(正确地)附加到父元素。
fnvucqvd4#
我的简单函数似乎是最短和最广泛兼容的。它不需要占位符或重新加载元素或任何类似的混乱:
uinbv5nw5#
由于jQuery在问题中被标记,这里有一个jQuery解决方案:
jQuery会将其剪切/粘贴到新位置。
这也可能有帮助:
https://api.jquery.com/detach/
3hvapo4f6#
这一切都是非常奇怪的考虑到这一事实,o1.swapNode(o2);在IE中工作了很长时间。在我的对象和文本节点混合的情况下,只适用于一个版本(已经显示在这里):
是的,我讨厌创建临时节点,但是如果你直接使用它(不调用函数),上面没有这个技巧的版本会失败。有时候你不想调用一个函数。
ltqd579y7#
如果你交换相邻的元素,这真的很容易:
$('.container .item:nth-child(2)').insertBefore('.container .item:nth-child(1)');
omjgkv6w8#
Internet Explorer已死
所有现代浏览器都有:
el2.after(el1);