有没有一个原生的jQueryfunction切换元素?

我可以轻松地交换两个元素与jQuery?

如果可能的话,我正在寻找一行。

我有一个select元素,我有两个button来向上或向下移动选项,我已经有了select和目标select器,我做了一个if,但我想知道是否有一个更简单的方法。

我发现了一个有趣的方式来解决这个只使用jQuery:

$("#element1").before($("#element2")); 

要么

 $("#element1").after($("#element2")); 

🙂

保罗的权利,但我不知道他为什么克隆有关的元素。 这并不是真正必要的,并且将失去与元素及其后代相关的任何引用或事件监听器。

这是一个使用普通DOM方法的非克隆版本(因为jQuery并没有任何特殊的function来简化这个特定的操作):

 function swapNodes(a, b) { var aparent = a.parentNode; var asibling = a.nextSibling === b ? a : a.nextSibling; b.parentNode.insertBefore(a, b); aparent.insertBefore(b, asibling); } 

不,没有,但你可以鞭打一个:

 jQuery.fn.swapWith = function(to) { return this.each(function() { var copy_to = $(to).clone(true); var copy_from = $(this).clone(true); $(to).replaceWith(copy_from); $(this).replaceWith(copy_to); }); }; 

用法:

 $(selector1).swapWith(selector2); 

请注意,这只适用于select器只匹配1个元素,否则可能会给出奇怪的结果。

这个问题有很多边缘案例,这些问题不是被接受的答案或者bobince的回答处理的。 涉及克隆的其他解决scheme是正确的,但是克隆是昂贵的和不必要的。 我们很想克隆,因为如何交换两个variables这个古老的问题,其中一个步骤是将一个variables分配给一个临时variables。 在这种情况下,分配(克隆)是不需要的。 这是一个基于jQuery的解决scheme:

 function swap(a, b) { a = $(a); b = $(b); var tmp = $('<span>').hide(); a.before(tmp); b.before(a); tmp.replaceWith(b); }; 

你不应该需要两个克隆,一个会做。 拿Paolo Bergantino回答我们有:

 jQuery.fn.swapWith = function(to) { return this.each(function() { var copy_to = $(to).clone(true); $(to).replaceWith(this); $(this).replaceWith(copy_to); }); }; 

应该更快。 传递这两个要素中较小的一个也应该加快速度。

其中许多答案在一般情况下是完全错误的,其他答案如果实际上甚至是有效的,则不必要的复杂。 jQuery .before.before方法完成了大部分你想要做的事情,但是你需要第三个元素来处理许多交换algorithm。 这很简单 – 在你移动东西的时候,创build一个临时的DOM元素作为占位符。 没有必要看父母或兄弟姐妹,当然不需要克隆…

 $.fn.swapWith = function(that) { var $this = this; var $that = $(that); // create temporary placeholder var $temp = $("<div>"); // 3-step swap $this.before($temp); $that.before($this); $temp.after($that).remove(); return $this; } 

1)在this之前放置临时div temp

2)在this之前移动this

3)在temp之后移动

3b)去除temp

然后干脆

 $(selectorA).swapWith(selectorB); 

DEMO: http : //codepen.io/anon/pen/akYajE

我之前使用过这样的技术。 我使用它在http://mybackupbox.com上的连接器列表;

 // clone element1 and put the clone before element2 $('element1').clone().before('element2').end(); // replace the original element1 with element2 // leaving the element1 clone in it's place $('element1').replaceWith('element2'); 

我已经做了一个function,允许您向上或向下移动多个选定的选项

 $('#your_select_box').move_selected_options('down'); $('#your_select_boxt').move_selected_options('up'); 

依赖关系:

 $.fn.reverse = [].reverse; function swapWith() (Paolo Bergantino) 

首先检查第一个/最后一个select的选项是否可以向上/向下移动。 然后它遍历所有元素和调用

swapWith(element.next()或element.prev())

 jQuery.fn.move_selected_options = function(up_or_down) { if(up_or_down == 'up'){ var first_can_move_up = $("#" + this.attr('id') + ' option:selected:first').prev().size(); if(first_can_move_up){ $.each($("#" + this.attr('id') + ' option:selected'), function(index, option){ $(option).swapWith($(option).prev()); }); } } else { var last_can_move_down = $("#" + this.attr('id') + ' option:selected:last').next().size(); if(last_can_move_down){ $.each($("#" + this.attr('id') + ' option:selected').reverse(), function(index, option){ $(option).swapWith($(option).next()); }); } } return $(this); } 

另一个没有克隆:

我有一个实际的和名义上的元素交换:

  $nominal.before('<div />') $nb=$nominal.prev() $nominal.insertAfter($actual) $actual.insertAfter($nb) $nb.remove() 

然后insert <div> before和之后的remove只需要,如果你不能确保,总是有一个元素befor(在我的情况是这样)

如果你想交换在jQuery对象中select的两个项目,你可以使用这个方法

http://www.vertstudios.com/blog/swap-jquery-plugin/

看看jQuery插件“Swapable”

http://code.google.com/p/jquery-swapable/

它build立在“Sortable”之上,看起来像可sorting(drag-n-drop,占位符等),但只交换两个元素:拖放。 所有其他元素不受影响,并保持当前位置。

这是基于@lotif的答案逻辑的答案,但有点更一般化

如果在元素实际移动之前/之前添加/前置
=>不需要克隆
=>保持的事件

有两种情况可能发生

  1. 一个目标有一些“ .prev() ”=>我们可以把另一个目标.after()那个。
  2. 一个目标是它的第一个孩子.parent() =>我们可以.parent()另一个目标为父。

代码

这段代码甚至可以做得更短,但为了可读性,我保持这种方式。 请注意,预先存储父母(如果需要)和以前的元素是强制性的。

 $(function(){ var $one = $("#one"); var $two = $("#two"); var $onePrev = $one.prev(); if( $onePrev.length < 1 ) var $oneParent = $one.parent(); var $twoPrev = $two.prev(); if( $twoPrev.length < 1 ) var $twoParent = $two.parent(); if( $onePrev.length > 0 ) $onePrev.after( $two ); else $oneParent.prepend( $two ); if( $twoPrev.length > 0 ) $twoPrev.after( $one ); else $twoParent.prepend( $one ); }); 

…随意包装在一个函数的内部代码:)

示例小提琴有额外的点击事件附加演示事件保存…
示例小提琴: https //jsfiddle.net/ewroodqa/

…将适用于各种情况 – 甚至一个例如:

 <div> <div id="one">ONE</div> </div> <div>Something in the middle</div> <div> <div></div> <div id="two">TWO</div> </div> 

我想要一个解决scheme女巫不使用克隆(),因为它有附加事件的副作用,这是我最终要做的

 jQuery.fn.swapWith = function(target) { if (target.prev().is(this)) { target.insertBefore(this); return; } if (target.next().is(this)) { target.insertAfter(this); return } var this_to, this_to_obj, target_to, target_to_obj; if (target.prev().length == 0) { this_to = 'before'; this_to_obj = target.next(); } else { this_to = 'after'; this_to_obj = target.prev(); } if (jQuery(this).prev().length == 0) { target_to = 'before'; target_to_obj = jQuery(this).next(); } else { target_to = 'after'; target_to_obj = jQuery(this).prev(); } if (target_to == 'after') { target.insertAfter(target_to_obj); } else { target.insertBefore(target_to_obj); } if (this_to == 'after') { jQuery(this).insertAfter(this_to_obj); } else { jQuery(this).insertBefore(this_to_obj); } return this; }; 

它不能用于包含多个DOM元素的jQuery对象

如果你有每个元素的多个副本,你需要在循环中自然地做一些事情。 我最近有这种情况。 我需要切换的两个重复元素有类和一个容器div,如下所示:

 <div class="container"> <span class="item1">xxx</span> <span class="item2">yyy</span> </div> and repeat... 

下面的代码允许我遍历所有东西,然后反向…

 $( ".container " ).each(function() { $(this).children(".item2").after($(this).children(".item1")); }); 

我已经完成了这个片段

 // Create comments var t1 = $('<!-- -->'); var t2 = $('<!-- -->'); // Position comments next to elements $(ui.draggable).before(t1); $(this).before(t2); // Move elements t1.after($(this)); t2.after($(ui.draggable)); // Remove comments t1.remove(); t2.remove(); 

我做了一个在数据库中使用.after().before(),改变obj的顺序的表,所以这是从我的实验。

 $(obj1).after$(obj2) 

在obj2和之前插入obj1

 $(obj1).before$(obj2) 

反之亦然。

所以如果obj1在obj4之后的obj3和obj2之后,并且如果你想要改变obj1和obj2的位置,你将会像

 $(obj1).before$(obj4) $(obj2).before$(obj3) 

这应该这样做顺便说一句,你可以使用.prev()和.next()来findobj3和obj4,如果你还没有某种索引。

如果nodeA和nodeB是同胞,在同一个<tbody>可以使用两个<tr> ,您可以使用$(trA).insertAfter($(trB))$(trA).insertBefore($(trB)) $(trA).insertAfter($(trB))他们,这对我有用。 你不需要在$(trA).remove()之前调用,否则你需要重新绑定$(trA)上的一些点击事件,

最好的select是用clone()方法克隆它们。

我想你可以做得很简单。 例如,假设你有下一个结构:…

 <div id="first">...</div> <div id="second">...</div> 

结果应该是

 <div id="second">...</div> <div id="first">...</div> 

jQuery的:

 $('#second').after($('#first')); 

我希望它有帮助!