我能否用jQuery轻松地交换两个元素?
如果可能的话,我希望用一行代码来实现这个功能。
我有一个选择元素和两个按钮,可以将选项向上或向下移动,我已经设置好了选定和目标选择器,我使用if语句来完成它,但我想知道是否有更简单的方法。
我能否用jQuery轻松地交换两个元素?
如果可能的话,我希望用一行代码来实现这个功能。
我有一个选择元素和两个按钮,可以将选项向上或向下移动,我已经设置好了选定和目标选择器,我使用if语句来完成它,但我想知道是否有更简单的方法。
以下是一种只使用 jQuery 解决此问题的有趣方法(如果这两个元素 相邻):
$("#element1").before($("#element2"));
或者
$("#element1").after($("#element2"));
保罗是对的,但我不确定为什么他要克隆相关元素。这并不是真正必要的,而且会丢失与元素及其后代相关联的任何引用或事件监听器。
以下是一个非克隆版本,使用普通的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);
注意,这仅在选择器只匹配一个元素时有效,否则可能会产生奇怪的结果。
这个问题有很多边界情况,被接受的答案或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
方法可以用于通过添加一个临时的第三个元素作为书签来交换元素 - 在移动元素时创建一个临时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;
}
将临时div temp
放置在 this
之前。
将 this
移动到 that
之前。
将 that
移动到 temp
之前。
3b) 删除 temp
。
然后像这样使用它:
$(selectorA).swapWith(selectorB);
3)将其移动到temp之后
也可以是3)将其移动到temp之前
,因为temp在被用作锚点后将被删除。 - Victor你不需要两个克隆,一个就够了。根据Paolo Bergantino的回答:
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');
怎么样? - robisrobclone()
不会保留任何jQuery data()
,除非你指定clone(true)
- 如果你正在排序,这是一个重要的区别,这样你就不会丢失所有数据。 - robisrob我已经编写了一个函数,可以让您将多个所选选项向上或向下移动。
$('#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()
中 :) 这样你就不需要创建额外的元素了。 - jave.web<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"));
});