是否有原生的 jQuery 函数来切换元素?

IT技术 jquery swap javascript
2021-01-14 16:37:06

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

如果可能的话,我希望用一条线来做到这一点。

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

6个回答

我找到了一种有趣的方法来仅使用 jQuery 来解决这个问题:

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

或者

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

:)

我最喜欢这个选项!简单而兼容。尽管我喜欢使用 el1.insertBefore(el2) 和 el1.insertAfter(el2) 来提高可读性。
2021-03-28 16:37:06
不过有一个旁注..(我猜这适用于本页上的所有解决方案),因为我们在这里操作 DOM。当您移动的元素中存在 iframe 时,删除和添加效果不佳。iframe 将重新加载。它也将重新加载到它的原始 url 而不是当前的 url。非常烦人但与安全相关。我还没有找到解决方案
2021-03-29 16:37:06
这不会交换两个元素,除非这两个元素紧挨着彼此。
2021-04-06 16:37:06
这不再是公认的答案。它在一般情况下不起作用。
2021-04-06 16:37:06
是的,这应该有效:文档说:“如果以这种方式选择的元素插入其他地方,它将在目标之前移动(未克隆)”。
2021-04-08 16:37:06

保罗是对的,但我不确定他为什么要克隆相关元素。这并不是真正必要的,并且会丢失与元素及其后代关联的任何引用或事件侦听器。

这是一个使用普通 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);
}
我有一个对顺序非常敏感的列表,需要保留事件和 ID,这就像一个魅力!谢谢!
2021-03-18 16:37:06
docs.jquery.com/Clone - 传递“true”也会克隆事件。我没有先克隆它,但它正在做你目前所做的事情:它将第一个与第二个交换,并保持第一个不变。
2021-03-24 16:37:06
我觉得你应该添加一个 jQuery 版本来在技术上满足这个问题的标题。:)
2021-03-27 16:37:06
啊,有一个极端情况,a 的下一个兄弟是 b 本身。在上面的片段中修复。jQuery 正在做完全相同的事情。
2021-03-28 16:37:06
如果我有 <div id="div1">1</div><div id="div2">2</div> 并调用 swapNodes(document.getElementById('div1'), document.getElementById('div2') ); 我得到 <div id="div1">1</div><div id="div2">1</div>
2021-04-08 16:37:06

不,没有,但你可以掀起一个:

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 个元素的情况,否则可能会产生奇怪的结果。

有必要克隆它们吗?
2021-03-18 16:37:06
这应该是公认的答案。它扩展了 jQuery 以提供所需的内容。
2021-03-18 16:37:06
也许您可以直接使用 html() 编写它们?
2021-03-22 16:37:06
当 div 不相邻时效果很好:)
2021-03-31 16:37:06
@Ed Woodcock 如果你这样做,我很确定你会丢失那些元素上的绑定事件。
2021-04-02 16:37:06

这个问题有很多边缘情况,它们没有被接受的答案或 bobince 的答案处理。其他涉及克隆的解决方案都在正确的轨道上,但克隆既昂贵又不必要。我们很想进行克隆,因为如何交换两个变量是一个古老的问题,其中一个步骤是将其中一个变量分配给一个临时变量。在这种情况下不需要分配(克隆)。这是一个基于 jQuery 的解决方案:

function swap(a, b) {
    a = $(a); b = $(b);
    var tmp = $('<span>').hide();
    a.before(tmp);
    b.before(a);
    tmp.replaceWith(b);
};
这是更好的答案!我碰巧有一个 ul 作为我交换元素的子元素,它是一个 jquery 可排序元素。在与 Paolo Bergantino 的答案交换后,列表项不能再被删除。有了 user2820356 的回答,一切仍然正常。
2021-03-22 16:37:06
这应该是公认的答案。克隆会删除任何事件触发器,这不是必需的。我在我的代码中使用了这个确切的方法。
2021-04-11 16:37:06

对于一般情况,这些答案中的许多答案都是错误的,其他答案即使实际上有效,也会不必要地复杂化。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);

演示:http : //codepen.io/anon/pen/akYajE

谢谢,这个解决方案适用于所有情况,并且解释得详细而简单,它也可以标记为正确答案。这个stackoverflow.com/a/61212946/903998我想是类似的,但解释得更少,更复杂一点。
2021-03-28 16:37:06
这是最好的答案,所有其他人都假设元素彼此相邻。这适用于任何情况。
2021-03-29 16:37:06
@robisrob 和其他读者可能会注意到这3) move that after temp也可能是3) move that before temp因为 temp 在用作定位点后将被删除。
2021-03-29 16:37:06