Czy istnieje natywna funkcja jQuery do przełączania elementów?

Czy mogę łatwo zamienić dwa elementy za pomocą jQuery?

Chcę to zrobić jedną linijką, jeśli to możliwe.

Mam element select i mam dwa przyciski do przesuwania w górę lub w dół opcji, I Mam już selektory selected i destination na miejscu, robię to Z if, ale zastanawiałem się, czy nie ma łatwiejszego sposobu.

Author: juan, 2009-03-30

20 answers

Znalazłem ciekawy sposób na rozwiązanie tego problemu używając tylko jQuery:

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

Lub

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

:)

 204
Author: lotif,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-09 12:38:11

Paulo ma rację, ale nie wiem, dlaczego klonuje te elementy. Nie jest to tak naprawdę konieczne i spowoduje utratę jakichkolwiek odniesień lub słuchaczy zdarzeń związanych z elementami i ich potomkami.

Oto wersja bez klonowania przy użyciu zwykłych metod DOM (ponieważ jQuery tak naprawdę nie ma żadnych specjalnych funkcji ułatwiających tę operację):

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);
}
 73
Author: bobince,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-24 21:06:35

Nie, Nie Ma, ale można by coś wrzucić:

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

Użycie:

$(selector1).swapWith(selector2);

Uwaga To działa tylko wtedy, gdy selektory pasują Tylko do 1 elementu, w przeciwnym razie może to dać dziwne wyniki.

 65
Author: Paolo Bergantino,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-30 18:13:14

Istnieje wiele przypadków skrajnych tego problemu, które nie są obsługiwane przez zaakceptowaną odpowiedź lub odpowiedź bobince. Inne rozwiązania związane z klonowaniem są na dobrej drodze, ale klonowanie jest drogie i niepotrzebne. Kusi nas klonowanie, ze względu na odwieczny problem zamiany dwóch zmiennych, w którym jednym z kroków jest przypisanie jednej ze zmiennych do zmiennej tymczasowej. Przypisanie, (klonowanie), w tym przypadku nie jest potrzebne. Oto rozwiązanie oparte na jQuery:

function swap(a, b) {
    a = $(a); b = $(b);
    var tmp = $('<span>').hide();
    a.before(tmp);
    b.before(a);
    tmp.replaceWith(b);
};
 32
Author: user2820356,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-26 16:39:02

Wiele z tych odpowiedzi jest po prostu błędnych w ogólnym przypadku, inne są niepotrzebnie skomplikowane, jeśli faktycznie działają. Metody jQuery .before i .after wykonują większość tego, co chcesz, ale potrzebujesz trzeciego elementu, tak jak wiele algorytmów wymiany działa. To dość proste - Utwórz tymczasowy element DOM jako element zastępczy podczas przenoszenia rzeczy. Nie ma potrzeby patrzeć na rodziców lub rodzeństwo, a na pewno nie ma potrzeby klonowania...

$.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) Umieść tymczasowy div temp przed this

2) Przesuń this przed that

3) Przesuń that po temp

3B) Usuń temp

Potem po prostu

$(selectorA).swapWith(selectorB);

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

 13
Author: robisrob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-22 14:03:10

Nie powinieneś potrzebować dwóch klonów, wystarczy jeden. Biorąc Paolo Bergantino odpowiedź mamy:

jQuery.fn.swapWith = function(to) {
    return this.each(function() {
        var copy_to = $(to).clone(true);
        $(to).replaceWith(this);
        $(this).replaceWith(copy_to);
    });
};
Powinno być szybciej. Przechodzenie w mniejszym z dwóch elementów powinno również przyspieszyć.
 11
Author: Matthew Wilcoxson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-04 16:44:42

Kiedyś używałem takiej techniki. Używam go do listy konektorów na 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');
 7
Author: Eric Warnke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-26 06:00:32

Zrobiłem funkcję, która pozwala przenieść Wiele wybranych opcji w górę lub w dół

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

Zależności:

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

Najpierw sprawdza, czy pierwsza / ostatnia wybrana opcja jest w stanie poruszać się w górę/w dół. Następnie przecina wszystkie elementy i wywołuje

SwapWith (element.next() lub 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
Author: Tom Maeckelberghe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-27 14:34:49

Inny bez klonowania:

Mam element rzeczywisty i nominalny do zamiany:

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

Następnie insert <div> before i remove potem są potrzebne tylko, jeśli nie możesz zapewnić, że zawsze istnieje element befor (w moim przypadku jest)

 3
Author: halfbit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-14 17:10:27

Spójrz na wtyczkę jQuery "Swapable"

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

Jest zbudowany na "Sortable" i wygląda jak sortable (drag-n-drop, placeholder, itp.) ale tylko Zamień dwa elementy: przeciągnięty i upuszczony. Wszystkie inne elementy nie są naruszone i pozostać na ich aktualnej pozycji.

 2
Author: vadimk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-04 22:27:11

Jest to odpowiedź oparta na logice odpowiedzi @lotif, ale nieco bardziej uogólniona

Jeśli dodasz / prepend after / before the elements are actually przeniesiony
= > nie trzeba klonować
= > wydarzenia przechowywane

Są dwa przypadki, które mogą się zdarzyć]}
  1. jeden cel ma coś ".prev() ious " = > możemy umieścić drugi cel .after() to.
  2. jeden cel jest pierwszym dzieckiem tego .parent() => możemy .prepend() drugi cel do rodzica.

Kod

Ten kod można zrobić jeszcze krócej, ale zachowałem go w ten sposób dla czytelności. Należy pamiętać, że wstępne sprawdzanie rodziców (w razie potrzeby) i poprzednich elementów jest obowiązkowe.

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

});

...nie krępuj się zawijać kodu wewnętrznego w funkcję:)

Przykład fiddle ma dołączone dodatkowe zdarzenia kliknięcia, aby zademonstrować zachowanie zdarzenia...
przykładowe skrzypce: https://jsfiddle.net/ewroodqa /

...będzie działać w różnych przypadkach-nawet takich jak:

<div>
  <div id="one">ONE</div>
</div>
<div>Something in the middle</div>
<div>
  <div></div>
  <div id="two">TWO</div>
</div>
 2
Author: jave.web,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-05 00:23:18

To jest moje rozwiązanie do przenoszenia wielu elementów potomnych w górę iw dół wewnątrz elementu nadrzędnego. Działa dobrze przy przenoszeniu wybranych opcji w listbox (<select multiple></select>)

Przesuń w górę:

$(parent).find("childrenSelector").each((idx, child) => {
    $(child).insertBefore($(child).prev().not("childrenSelector"));
});

Przesuń w dół:

$($(parent).find("childrenSelector").get().reverse()).each((idx, child) => {
    $(opt).insertAfter($(child).next().not("childrenSelector"));
});
 2
Author: pistipanko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 15:15:49

Jeśli chcesz zamienić dwa elementy zaznaczone w obiekcie jQuery, możesz użyć tej metody

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

 1
Author: Joseph McCullough,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-12 09:04:13

Chciałem rozwiązanie wiedźma nie używa clone (), ponieważ ma efekt uboczny z dołączonymi zdarzeniami, oto co skończyłem zrobić

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

Nie może być używany z obiektami jQuery zawierającymi więcej niż jeden element DOM

 1
Author: Mistic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-15 09:52:13

Jeśli masz wiele kopii każdego elementu, musisz zrobić coś w pętli naturalnie. Ostatnio miałem taką sytuację. Dwa powtarzające się elementy, które musiałem przełączyć, miały klasy i kontener div w ten sposób:

<div class="container">
  <span class="item1">xxx</span>
  <span class="item2">yyy</span>
</div> 
and repeat...

Poniższy kod pozwolił mi przejść przez wszystko i odwrócić...

$( ".container " ).each(function() {
  $(this).children(".item2").after($(this).children(".item1"));
});
 1
Author: AdamJones,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-16 17:19:30

I have done it with this snippet

// 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();
 1
Author: zveljkovic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-14 10:03:08

Zrobiłem tabelę do zmiany kolejności obj w bazie danych .po() .przed (), więc to jest z tego co mam eksperyment.

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

Jest insert obj1 przed obj2 i

$(obj1).before($(obj2)) 
Zrób odwrotnie.

Więc jeśli obj1 jest po obj3 i obj2 po obj4, a jeśli chcesz zmienić miejsce obj1 i obj2 zrobisz to jak

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

To powinno wystarczyć BTW możesz użyć .prev () oraz .next() to find obj3 and obj4 if you didn ' t have some kind of index for it already.

 1
Author: Tran Vu Dang Khoa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-02 10:07:01

Jeśli nodeA i nodeB są rodzeństwem, lubi dwa <tr> w tym samym <tbody>, możesz po prostu użyć $(trA).insertAfter($(trB)) lub $(trA).insertBefore($(trB)), aby je zamienić, to działa dla mnie. nie musisz wcześniej wywoływać $(trA).remove(), w przeciwnym razie musisz ponownie powiązać niektóre zdarzenia kliknięcia na $(trA)

 0
Author: Spark.Bao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-26 03:36:42

Najlepszą opcją jest ich sklonowanie za pomocą metody clone ().

 -2
Author: user84771,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-30 19:03:08

Myślę, że możesz to zrobić bardzo prosto. Na przykład powiedzmy, że masz następną strukturę: ...

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

I wynik powinien być

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

Jquery:

$('#second').after($('#first'));
Mam nadzieję, że to pomoże!
 -2
Author: Jernej Gololicic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-10 17:11:28