我可以轻松地用jQuery交换两个元素吗?
如果可能的话,我正在寻找一行。
我有一个select元素,并且有两个按钮可以上下移动选项,并且已经有选择对象和目标选择器,我使用if来实现,但是我想知道是否有更简单的方法。
我可以轻松地用jQuery交换两个元素吗?
如果可能的话,我正在寻找一行。
我有一个select元素,并且有两个按钮可以上下移动选项,并且已经有选择对象和目标选择器,我使用if来实现,但是我想知道是否有更简单的方法。
Answers:
我发现了一种仅使用jQuery解决此问题的有趣方法:
$("#element1").before($("#element2"));
要么
$("#element1").after($("#element2"));
:)
Paulo是对的,但我不确定他为什么要克隆相关要素。这实际上不是必需的,并且会丢失与元素及其后代关联的任何引用或事件侦听器。
这是使用普通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);
}
不,没有,但是您可以鞭打一个:
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个元素的情况下才有效,否则可能会产生奇怪的结果。
这个问题有很多极端的情况,不能通过公认的答案或bobince的答案来处理。涉及克隆的其他解决方案也步入正轨,但是克隆既昂贵又不必要。由于试图交换两个变量的古老问题,我们很容易克隆,其中一个步骤是将一个变量分配给一个临时变量。在这种情况下,不需要分配(克隆)。这是一个基于jQuery的解决方案:
function swap(a, b) {
a = $(a); b = $(b);
var tmp = $('<span>').hide();
a.before(tmp);
b.before(a);
tmp.replaceWith(b);
};
这些答案中的许多答案对于一般情况来说都是错误的,如果实际上可行,其他答案则不必要地变得复杂。jQuery .before
和.after
方法完成了大多数您想做的事情,但是许多交换算法的工作方式都需要第三个元素。这非常简单-在移动内容时将一个临时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)把临时div temp
前this
2)移动 this
在之前that
3)移动 that
后temp
3b)移除 temp
然后简单地
$(selectorA).swapWith(selectorB);
您不需要两个克隆,一个就可以。以保罗·贝尔甘蒂诺的答案,我们有:
jQuery.fn.swapWith = function(to) {
return this.each(function() {
var copy_to = $(to).clone(true);
$(to).replaceWith(this);
$(this).replaceWith(copy_to);
});
};
应该更快。传递两个元素中较小的一个也可以加快速度。
我以前使用过这样的技术。我将其用于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');
end()
如果您不继续进行连锁,则无需这样做。怎么样$('element1').clone().before('element2').end().replaceWith('element2');
clone()
,data()
除非您指定,否则不会保留任何clone(true)
我做了一个功能,允许您向上或向下移动多个选择的选项
$('#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);
}
另一个没有克隆的:
我有一个实际和名义上的要交换的元素:
$nominal.before('<div />')
$nb=$nominal.prev()
$nominal.insertAfter($actual)
$actual.insertAfter($nb)
$nb.remove()
然后insert <div> before
,remove
仅在您不能确保之后,才需要在此之前始终存在一个元素(在我的情况下是这样)
.prev()
的长度,如果为0,然后.prepend()
到.parent()
:)这样,你不需要创建额外的元素。
看一下jQuery插件“可交换”
http://code.google.com/p/jquery-swapable/
它建立在“可排序”之上,看起来像可排序的(拖放,占位符等),但仅交换两个元素:拖放。所有其他元素均不受影响,并保持其当前位置。
这是基于@lotif的答案的答案逻辑的答案,但有点笼统
如果您在元素实际移动
之后/之前添加/添加
=>无需克隆
=>保留事件
.prev()
错” =>我们可以把另一个目标放进去.after()
。.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 );
});
...随意将内部代码包装在一个函数中:)
小提琴示例附带了额外的单击事件,以演示事件保存...
示例小提琴: 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>
这是我在父元素内上下移动多个子元素的解决方案。适用于在列表框(<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"));
});
如果要交换在jQuery对象中选择的两个项目,则可以使用此方法
我想要一种解决方案,女巫不使用clone(),因为它会对附加事件产生副作用,这就是我最终要做的事情
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"));
});
我做了一个表,用于更改使用.after().before()的数据库中obj的顺序,所以这是根据我的实验得出的。
$(obj1).after($(obj2))
是在obj2之前插入obj1并
$(obj1).before($(obj2))
反之亦然。
因此,如果obj1在obj3之后,而obj2在obj4之后,并且如果您要更改放置obj1和obj2,则可以这样做
$(obj1).before($(obj4))
$(obj2).before($(obj3))
顺便说一句,如果您还没有某种索引,可以使用.prev()和.next()查找obj3和obj4。
$('.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/
我认为您可以轻松完成。例如,假设您具有下一个结构:...
<div id="first">...</div>
<div id="second">...</div>
结果应该是
<div id="second">...</div>
<div id="first">...</div>
jQuery的:
$('#second').after($('#first'));
希望对您有所帮助!