是否有一个本地的 jQuery 函数来切换元素?

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

如果可能的话,我想用一句话来表达。

我有一个 select 元素,我有两个按钮可以向上或向下移动选项,我已经有了选择和目标选择器,我使用了一个 if,但是我想知道是否有更简单的方法。

134606 次浏览

不,没有,但你可以做一个:

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);

注意,只有当每个选择器只匹配1个元素时,这种方法才有效,否则它可能会产生奇怪的结果。

保罗说得对,但我不明白他为什么要克隆相关元素。这实际上没有必要,并且将丢失与元素及其后代相关联的任何引用或事件侦听器。

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

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);
}

最好的选择是使用 clone ()方法克隆它们。

你不需要两个克隆人,一个就够了:

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

应该更快。传入两个元素中较小的元素也应该加快速度。

看看 jQuery 插件“可切换”

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

它构建在“ Sortable”之上,看起来像是可排序的(拖放 n-drop、占位符等) ,但只交换两个元素: 拖放。所有其他元素不受影响,保持在当前位置。

如果希望交换 jQuery 对象中选定的两个项,可以使用这个方法

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

我已经做了一个函数,让你移动 多个选择的选项向上或向下

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

依赖性:

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

首先,它检查第一个/最后一个选项是否能够向上/向下移动。 然后它循环遍历所有元素和调用

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);
}

这里有一个有趣的方法来解决这个问题,只使用 jQuery (如果这两个元素是 紧挨着) :

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

或者

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

我以前使用过类似的技术,我将它用于 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');

我认为你可以做得很简单,比如说你有下一个结构: ...

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

结果应该是

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

Jquery:

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

希望能有所帮助!

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

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 对象一起使用

这个问题有很多边界情况,这些情况不是由已接受的答案或者弹跳的答案来处理的。其他涉及到克隆的解决方案都在正确的轨道上,但是克隆是昂贵的和不必要的。我们想要克隆,因为如何交换两个变量这个古老的问题,其中一个步骤是将其中一个变量赋给一个临时变量。在这种情况下,不需要赋值(克隆)。下面是一个基于 jQuery 的解决方案:

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

另一个没有克隆的:

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

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

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

如果每个元素有多个副本,则需要在循环中自然地执行某些操作。我最近遇到了这种情况。我需要切换的两个重复元素有类和容器 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();

这是一个基于 @ lotif的答案逻辑的答案,但是比较一般化

如果在元素实际上 < em > < strong > 移动之前添加/prepend after/
= > 不需要克隆
= > 资料保存

有两种情况可能发生

  1. 一个目标有“ .prev() ious”= > 我们可以把另一个目标 .after()
  2. 一个目标是它的 .parent() = > 的第一个子目标,我们可以 .prepend()另一个目标到父目标。

密码

这段代码可以做得更短,但我保持这样的可读性。注意,预存父元素(如果需要)和以前的元素是强制性的。

$(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 );


});

... 可以将内部代码封装在函数中:)

示例小提琴有额外的点击事件附加演示事件保存..。
小提琴示例: < a href = “ https://jsfiddle.net/ewroodqa/”rel = “ nofollow norefrer”> 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>

JQuery .before方法可以通过添加一个临时的第三个元素作为书签来交换元素——当您移动东西时,创建一个临时的 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.before($that).remove();
        

return $this;
}
  1. 将临时 div temp置于 this之前

  2. that之前移动 this

  3. temp之前移动 that

3b)清除 temp

那就这样用

$(selectorA).swapWith(selectorB);

演示: https://jsfiddle.net/7t1hz94y/

我做了一个改变数据库中 obj 使用顺序的表。之后。这是我的实验结果。

$(obj1).after($(obj2))

在 objec2和

$(obj1).before($(obj2))

反之亦然。

因此,如果 ob1位于 ob3之后,而 ob2位于 ob4之后,并且如果您想要更改 ob1和 ob2的位置,那么您将按照以下方法进行操作

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

这个应该够了 顺便说一下,你可以用。前情提要。如果还没有对它进行某种索引,那么 next ()可以查找 objec3和 objec4。

如果 nodeA 和 nodeB 是兄弟,喜欢两个 <tr>在同一个 <tbody>,你可以只使用 $(trA).insertAfter($(trB))$(trA).insertBefore($(trB))交换他们,它为我工作。而且之前不需要调用 $(trA).remove(),否则需要重新绑定 $(trA)上的一些单击事件

这是我在父元素中上下移动多个子元素的解决方案。 适用于在列表框(<select multiple></select>)中移动选定选项

前进:

$(parent).find("childrenSelector").each((idx, child) => {
$(child).insertBefore($(child).prev().not("childrenSelector"));
});

向下移动:

$($(parent).find("childrenSelector").get().reverse()).each((idx, child) => {
$(opt).insertAfter($(child).next().not("childrenSelector"));
});
$('.five').swap('.two');

像这样创建一个 jQuery 函数

$.fn.swap = function (elem)
{
elem = elem.jquery ? elem : $(elem);
return this.each(function ()
{
$('<span></span>').insertBefore(this).before(elem.before(this)).remove();
});
};

感谢 https://jsfiddle.net/ARTsinn/TVjnr/台的 Yannick Guinness

目前,任何主流浏览器都不需要使用 jquery 来交换元素。本地 Dom 方法,无论它们位置如何,insertAdjacentElement都能做到这一点:

var el1 = $("el1");
var el2 = $("el2");
el1[0].insertAdjacentElement("afterend", el2[0]);