Есть ли собственная функция jQuery для переключения элементов?


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

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

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

20 161

20 ответов:

Я нашел интересный способ решить эту проблему, используя только 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);

Примечание это работает только в том случае, если селекторы соответствуют только 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 методы делают большую часть того, что вы хотите сделать, но вам нужен 3-й элемент, как работают многие алгоритмы подкачки. Это довольно просто-сделать временный элемент 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) move this до that

3) move that после temp

3b) удалить temp

потом просто

$(selectorA).swapWith(selectorB);

демо: http://codepen.io/anon/pen/akYajE

вам не нужно два клона, один будет делать. Принимая Паоло Бергантино ответ у нас есть:

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

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

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

зависимости:

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

сначала он проверяет, может ли первый/последний выбранный параметр перемещаться вверх/вниз. Затем он перебирает все элементы и вызывает

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

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

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

Он построен на "Сортируемом" и выглядит как сортируемый (drag-n-drop, placeholder и т. д.) но только поменять местами два элемента: перетаскивать. Все остальные элементы не затрагиваются и остаются на своем текущем положении.

это ответ на основе @lotifлогика ответа, но более обобщенное

если вы добавляете / добавляете После / До того, как элементы на самом деле двигался
=> клонирование не требуется
=> мероприятий

есть два случая, которые могут произойти

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

});

...не стесняйтесь обернуть внутренний код в функцию:)

пример скрипка имеет дополнительные события щелчка прилагается для демонстрации сохранения события...
пример скрипку: 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>

Это мое решение для перемещения нескольких дочерних элементов вверх и вниз внутри родительского элемента. Хорошо работает для перемещения выбранных параметров в listbox (<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, вы можете использовать этот метод

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

Я хотел, чтобы решение witch не использовало 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;
};

он не должен использоваться с объектами jQuery, содержащими более одного элемента DOM

Если у вас есть несколько копий каждого элемента, вы должны сделать что-то в цикле, естественно. У меня недавно была такая ситуация. Два повторяющихся элемента, которые мне нужно было переключить, имели классы и контейнер 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();

Я сделал таблицу для изменения порядка obj в используемой базе данных .после. )(раньше (), так что это из того, что у меня есть эксперимент.

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

вставить obj1 перед obj2 и

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

сделать наоборот.

Так что если obj1 после obj3 и obj2 после obj4, и если вы хотите изменить место obj1 и obj2 вы будете делать это как

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

это должно помочь Кстати, вы можете использовать .prev () and .следующий() найти obj3 и obj4 если у вас не было какой-то индекс для него уже есть.

если nodea и nodeb являются братьями и сестрами, любит две <tr> в том же <tbody>, вы можете просто использовать $(trA).insertAfter($(trB)) или $(trA).insertBefore($(trB)) поменять их, это работает для меня. и вам не нужно звонить $(trA).remove() раньше, иначе вам нужно повторно привязать некоторые события щелчка на $(trA)

лучший вариант-клонировать их с помощью метода clone ().

Я думаю, что вы можете сделать это очень просто. Например, допустим, у вас есть следующая структура: ...

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

и результат должен быть

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

jquery:

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

Я надеюсь, что это помогает!