有类似的问题,但所有答案都是为了仅交换其中的内容的html元素。
我需要交换两个 div,其中有很多内容(表格、选择框、输入等)。 这些元素上有事件侦听器,因此我需要在交换主 div 后保留它们。
我可以访问 jQuery 1.5。所以用它回答就可以了。
要交换两个 div 而不会丢失事件处理程序或破坏 DOM 引用,您只需在 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);
}
您可以在这里看到它的工作原理: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);
}
}
}
这是一个更简单的函数,用于交换两个元素而无需实际重新加载元素...
function swapElements(obj1, obj2) {
obj2.nextSibling === obj1
? obj1.parentNode.insertBefore(obj2, obj1.nextSibling)
: obj1.parentNode.insertBefore(obj2, obj1);
}
注意:如果 obj1 有嵌入的视频(如 YouTube),则交换时不会重新加载。 只是元素的位置发生了变化。
如果您跟踪两个元素的父节点和其中一个元素的下一个兄弟节点,则可以将两个元素与其子元素交换,而无需任何临时占位符。
如果第二个元素是唯一的子元素,或其父元素的最后一个子元素,则其替换将(正确)附加到父元素。
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;
}
我的简单函数似乎是最短且兼容最广泛的。它不需要占位符或重新加载元素或任何类似的混乱:
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);
}
由于 jQuery 在问题中被标记,这里是一个 jQuery 解决方案:
$('#el_to_move').appendTo('#target_parent_el');
就是这样。 jQuery 会将其剪切/粘贴到新位置。
这也可能有帮助:
考虑到 o1.swapNode(o2); ,这一切都非常奇怪在 IE 中工作很长时间都很好。在我的对象和文本节点混合的情况下,仅适用于一个版本(已在此处显示):
let t = document.createElement("div");
o1.parentNode.insertBefore(t, o1);
o2.parentNode.insertBefore(o1, o2);
t.parentNode.insertBefore(o2, t);
t.parentNode.removeChild(t);
是的,我讨厌创建临时节点,但是如果直接使用它(不调用函数),没有这个技巧的上面版本会失败。有时您不想调用函数。
如果您要交换彼此相邻的元素,这真的很容易:
<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)');
https://developer.mozilla.org/en-US/docs/Web/API/Element/before
https://developer.mozilla.org/en-US/docs/Web/API/Element/after