Есть ли встроенная функция jQuery для переключения элементов? - PullRequest
165 голосов
/ 30 марта 2009

Могу ли я легко поменять два элемента с помощью jQuery?

Я хочу сделать это с одной строкой, если это возможно.

У меня есть элемент выбора, и у меня есть две кнопки для перемещения вверх или вниз по опциям, и у меня уже есть выбранные и целевые селекторы на месте, я делаю это с помощью if, но мне было интересно, есть ли проще способ.

Ответы [ 20 ]

219 голосов
/ 26 декабря 2011

Я нашел интересный способ решить эту проблему, используя только jQuery:

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

или

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

:)

75 голосов
/ 30 марта 2009

Пауло прав, но я не уверен, почему он клонирует соответствующие элементы. В этом нет необходимости, и он потеряет все ссылки или прослушиватели событий, связанные с элементами и их потомками.

Вот не клонирующая версия, использующая простые методы 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);
}
66 голосов
/ 30 марта 2009

Нет, нет, но вы могли бы поднять один:

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 элементу, в противном случае это может привести к странным результатам.

36 голосов
/ 26 сентября 2013

Есть много крайних случаев для этой проблемы, которые не обрабатываются принятым ответом или ответом Бобинса. Другие решения, которые включают клонирование, находятся на правильном пути, но клонирование стоит дорого и не нужно. Мы испытываем искушение клонировать из-за давней проблемы обмена двумя переменными, в которой одним из шагов является назначение одной из переменных временной переменной. Назначение (клонирование) в этом случае не требуется. Вот решение на основе jQuery:

function swap(a, b) {
    a = $(a); b = $(b);
    var tmp = $('<span>').hide();
    a.before(tmp);
    b.before(a);
    tmp.replaceWith(b);
};
15 голосов
/ 22 июля 2016

Многие из этих ответов просто неверны для общего случая, другие излишне сложны, если они фактически даже работают. Методы 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

3б) удалить temp

Тогда просто

$(selectorA).swapWith(selectorB);

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

11 голосов
/ 04 февраля 2010

Вам не нужно два клона, один подойдет. Принимая ответ Паоло Бергантино, мы имеем:

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

Должно быть быстрее. Прохождение меньшего из двух элементов также должно ускорить процесс.

7 голосов
/ 26 февраля 2012

Я использовал такую ​​технику раньше. Я использую его для списка соединителей на 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');
3 голосов
/ 27 января 2011

Я сделал функцию, которая позволяет вам перемещать несколько выбранных опций вверх или вниз

$('#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);
}
3 голосов
/ 14 сентября 2014

другой без клонирования:

У меня есть фактический и номинальный элемент для обмена:

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

затем insert <div> before и remove впоследствии необходимы только, если вы не можете гарантировать, что всегда есть элемент до (в моем случае это так)

2 голосов
/ 04 июля 2010

взгляните на плагин jQuery "Swapable"

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

он построен на «Сортируемом» и выглядит как сортируемый (drag-n-drop, заполнитель и т. Д.), Но поменяет местами только два элемента: перетаскиваемый и опускаемый Все остальные элементы не затрагиваются и остаются на своей текущей позиции.

...