Javascript 如何在javascript中交换HTML元素?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2943140/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to swap HTML elements in javascript?
提问by Harish Kurup
I am using classic Javascript for DOM scripting, i have a set of DIV's in a container DIV. On click event of child DIV's, i want that the child DIV which has caused event to be swaped with the DIV above it.. my code goes here..
我正在使用经典的 Javascript 进行 DOM 脚本编写,我在容器 DIV 中有一组 DIV。在子 DIV 的单击事件中,我希望导致事件的子 DIV 与其上方的 DIV 交换..我的代码放在这里..
<div id="container">
<div onclick="swapDiv(event);">1</div>
<div onclick="swapDiv(event);">2</div>
<div onclick="swapDiv(event);">3</div>
</div>
if DIV 2 has been clicked it should be swap with DIV 1
如果已单击 DIV 2,则应与 DIV 1 交换
采纳答案by Thariama
This code will do what you want (if you want to swap the selected with the first child element). In case you want something else you need to be more precise.
此代码将执行您想要的操作(如果您想将所选元素与第一个子元素交换)。如果你想要别的东西,你需要更精确。
<script type="text/javascript">
function swapDiv(event,elem){
elem.parentNode.insertBefore(elem,elem.parentNode.firstChild);
}
</script>
<div id="container">
<div onclick="swapDiv(event,this);">1</div>
<div onclick="swapDiv(event,this);">2</div>
<div onclick="swapDiv(event,this);">3</div>
</div>
回答by T.J. Crowder
An element's parentNodeproperty gives you its parent node. Elements have an insertBeforefunction that inserts an element before another reference element (moving it if it's already elsewhere in the tree). And nodes have a previousSiblingthat gives you the previous sibling node (which may or may not be an element). So:
元素的parentNode属性为您提供其父节点。元素有一个insertBefore函数,可以在另一个引用元素之前插入一个元素(如果它已经在树中的其他地方,则移动它)。并且节点有一个previousSibling,它为您提供前一个兄弟节点(可能是也可能不是元素)。所以:
function swapDiv(elm) {
var previous = findPrevious(elm);
if (previous) {
elm.parentNode.insertBefore(elm, previous);
}
}
...where findPreviouslooks like this:
...findPrevious看起来像这样:
function findPrevious(elm) {
do {
elm = elm.previousSibling;
} while (elm && elm.nodeType != 1);
return elm;
}
...where your onclickattributes should be:
...您的onclick属性应该在哪里:
onclick="swapDiv(this);"
...although you may want to look into DOM2 event hooking instead (addEventListener, or attachEventon IE).
...尽管您可能想要查看 DOM2 事件挂钩(addEventListener,或attachEvent在 IE 上)。
Slightly OT, but can I recommend using any of the several libraries available that make your life easier, such as Prototype, jQuery, Closure, or any of several others. In fact, there was an error in an earlier version of this because it had been thatlong since I'd dealt with the DOM directly. :-)
有点过时,但我可以推荐使用几个可用的库中的任何一个来让你的生活更轻松,比如Prototype、jQuery、Closure或其他几个库中的任何一个。事实上,在这方面的一个早期版本的错误,因为它一直是长久以来我会直接处理的DOM。:-)
回答by bobince
In principle you just insertBeforeyour clicked element before its previous element sibling. However, the presence of whitespace Text nodes makes that more annoying than it should be in traditional scripting. The Element Traversal APIwill make this easier, but until it is more widely supported in browsers, helper functions are necessary, eg.:
原则上,您只需insertBefore在其前一个元素兄弟之前单击元素即可。然而,空白文本节点的存在使得它比传统脚本中更烦人。该元素遍历API将会使这更容易,但直到它被更广泛支持的浏览器,辅助功能是必要的,例如:
<div id="container">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<script type="text/javascript">
// Bind event to each line div
//
var div= firstElementChild(document.getElementById('container'));
while (div!==null) {
div.onclick= swapWithPreviousElement;
div= nextElementSibling(div);
}
// Move element before its previous element sibling
//
function swapWithPreviousElement() {
var previous= previousElementSibling(this);
if (previous!==null)
this.parentNode.insertBefore(this, previous);
}
// We've used some Element Traversal API methods but some
// browsers don't support them yet. Provide wrapper functions
// for compatibility.
//
function previousElementSibling(element) {
if ('previousElementSibling' in element)
return element.previousElementSibling;
do
element= element.previousSibling;
while (element!==null && element.nodeType!==1);
return element;
}
function nextElementSibling(element) {
if ('nextElementSibling' in element)
return element.nextElementSibling;
do
element= element.nextSibling;
while (element!==null && element.nodeType!==1);
return element;
}
function firstElementChild(element) {
if ('firstElementChild' in element)
return element.firstElementChild;
var child= element.firstChild;
while (child!==null && child.nodeType!==1)
child= child.nextSibling;
return child;
}
</script>
回答by CharlesLeaf
From the sounds of it you basically just want to swap the div with the div before it, ergo with the previousSibling. You could maybe look at doing an insertBeforebut instead of creating a new element use the existing one. I'm not sure what happens to the attached events tho, if they will be copied over correctly.
从它的声音来看,您基本上只想将 div 与之前的 div 交换,因此与previousSibling. 您可能会考虑做一个,insertBefore但不要使用现有元素创建新元素。我不确定附加的事件会发生什么,如果它们被正确复制。
回答by seeker_of_bacon
This works for siblings, should work for any two nodes:
这适用于兄弟姐妹,应该适用于任何两个节点:
function swapElements(el1, el2) {
let prev1 = el1.previousSibling;
let prev2 = el2.previousSibling;
prev1.after(el2);
prev2.after(el1);
}
回答by br4nnigan
Swap any nodes, not siblings, not adjecent siblings, no temp nodes, no cloning, no jquery... IE9+
交换任何节点,不是兄弟姐妹,不是相邻兄弟姐妹,没有临时节点,没有克隆,没有 jquery... IE9+
function swapNodes(n1, n2) {
var p1 = n1.parentNode;
var p2 = n2.parentNode;
var i1, i2;
if ( !p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1) ) return;
for (var i = 0; i < p1.children.length; i++) {
if (p1.children[i].isEqualNode(n1)) {
i1 = i;
}
}
for (var i = 0; i < p2.children.length; i++) {
if (p2.children[i].isEqualNode(n2)) {
i2 = i;
}
}
if ( p1.isEqualNode(p2) && i1 < i2 ) {
i2++;
}
p1.insertBefore(n2, p1.children[i1]);
p2.insertBefore(n1, p2.children[i2]);
}

