Existe uma function jQuery nativa para alternar elementos?

Posso trocar facilmente dois elementos com jQuery?

Eu estou olhando para fazer isso com uma linha, se possível.

Eu tenho um elemento select e eu tenho dois botões para mover para cima ou para baixo as opções, e eu já tenho o selecionado e os seletores de destino no lugar, eu faço isso com um if, mas eu queria saber se há uma maneira mais fácil.

    Eu encontrei uma maneira interessante de resolver isso usando apenas jQuery:

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

    ou

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

    🙂

    Paulo está certo, mas não sei por que ele está clonando os elementos em questão. Isso não é realmente necessário e perderá quaisquer referências ou ouvintes de events associados aos elementos e seus descendentes.

    Aqui está uma versão sem clonagem usando methods DOM simples (já que o jQuery realmente não tem nenhuma function especial para tornar esta operação em particular mais fácil):

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

    Não, não há, mas você pode agitar um deles:

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

    Uso:

     $(selector1).swapWith(selector2); 

    Observe que isso só funciona se os seletores corresponderem a apenas 1 elemento cada, caso contrário, poderá dar resultados estranhos.

    Há muitos casos de limites para esse problema, que não são tratados pela resposta aceita ou pela resposta de Bobince. Outras soluções que envolvem clonagem estão no caminho certo, mas a clonagem é cara e desnecessária. Somos tentados a clonar, devido ao antigo problema de como trocar duas variables, em que uma das etapas é atribuir uma das variables ​​a uma variável temporária. A atribuição (clonagem), neste caso, não é necessária. Aqui está uma solução baseada em jQuery:

     function swap(a, b) { a = $(a); b = $(b); var tmp = $('').hide(); a.before(tmp); b.before(a); tmp.replaceWith(b); }; 

    Você não deveria precisar de dois clones, um servirá. Tomando Paolo Bergantino resposta temos:

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

    Deve ser mais rápido. Passar no menor dos dois elementos também deve acelerar as coisas.

    Muitas dessas respostas são simplesmente erradas para o caso geral, outras são desnecessariamente complicadas se de fato até funcionarem. Os methods jQuery .after e .after fazem a maior parte do que você quer fazer, mas você precisa de um terceiro elemento da maneira que muitos algoritmos de swap funcionam. É bem simples – crie um elemento DOM temporário como um espaço reservado enquanto você movimenta as coisas. Não há necessidade de olhar para os pais ou irmãos, e certamente não há necessidade de clonar …

     $.fn.swapWith = function(that) { var $this = this; var $that = $(that); // create temporary placeholder var $temp = $("
    "); // 3-step swap $this.before($temp); $that.before($this); $temp.after($that).remove(); return $this; }

    1) coloque a temporária div temp antes this

    2) mova this antes that

    3) mova that depois de temp

    3b) remover temp

    Então simplesmente

     $(selectorA).swapWith(selectorB); 

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

    Eu usei uma técnica como essa antes. Eu uso para a lista de conectores em 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'); 

    Eu fiz uma function que permite mover várias opções selecionadas para cima ou para baixo

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

    Dependências:

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

    Primeiro, verifica se a primeira / última opção selecionada é capaz de se mover para cima / para baixo. Em seguida, ele passa por todos os elementos e chama

    swapWith (element.next () ou 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); } 

    um outro sem clonagem:

    Eu tenho um elemento real e um nominal para trocar:

      $nominal.before('
    ') $nb=$nominal.prev() $nominal.insertAfter($actual) $actual.insertAfter($nb) $nb.remove()

    então insert

    before

    e a remove depois só é necessária, se você não puder garantir, que sempre há um elemento antes (no meu caso é)

    dê uma olhada no plugin jQuery “Swapable”

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

    Ele é construído em “Classificável” e se parece com classificável (arrastar e soltar, espaço reservado, etc.), mas apenas trocar dois elementos: arrastado e solto. Todos os outros elementos não são afetados e permanecem em sua posição atual.

    Esta é uma resposta baseada na lógica de resposta do @lotif , mas pouco mais generalizada

    Se você acrescentar / preceder após / antes dos elementos serem realmente movidos
    => não é necessário clonagem
    => events mantidos

    Existem dois casos que podem acontecer

    1. Um alvo tem algo ” .prev() ious” => podemos colocar o outro alvo .after() isso.
    2. Um alvo é o primeiro filho dele. .parent() => nós podemos .prepend() o outro alvo para o pai.

    O código

    Esse código pode ser feito ainda mais curto, mas eu mantenho isso por legibilidade. Observe que o pré-teste dos pais (se necessário) e os elementos anteriores é obrigatório.

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

    … fique à vontade para embrulhar o código interno em uma function 🙂

    Exemplo de violino tem events extras de clique anexados para demonstrar a preservação de events …
    Exemplo de violino: https://jsfiddle.net/ewroodqa/

    … trabalhará em vários casos – até um como:

     
    ONE
    Something in the middle
    TWO

    Esta é a minha solução para mover vários elementos filhos para cima e para baixo dentro do elemento pai. Funciona bem para mover as opções selecionadas na checkbox de listview ( )

    Subir:

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

    Mover para baixo:

     $($(parent).find("childrenSelector").get().reverse()).each((idx, child) => { $(opt).insertAfter($(child).next().not("childrenSelector")); }); 

    Se você está querendo trocar dois itens selecionados no object jQuery, você pode usar este método

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

    Eu queria uma solução que não usasse o clone () como tem efeito colateral com events anexados, aqui está o que acabei fazendo

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

    não deve ser usado com objects jQuery contendo mais de um elemento DOM

    Se você tem várias cópias de cada elemento, você precisa fazer algo em um loop naturalmente. Eu tive essa situação recentemente. Os dois elementos repetidos que eu precisava mudar tinham classs e um contêiner div da seguinte forma:

     
    xxx yyy
    and repeat...

    O seguinte código permitiu-me iterar através de tudo e inverter …

     $( ".container " ).each(function() { $(this).children(".item2").after($(this).children(".item1")); }); 

    Eu fiz isso com este trecho

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

    Se nodeA e nodeB são irmãos, gosta de dois

    no mesmo

    , você pode usar apenas $(trA).insertAfter($(trB)) ou $(trA).insertBefore($(trB)) para trocar eles funcionam para mim. e você não precisa chamar $(trA).remove() antes, senão você precisa $(trA) alguns events de clique em $(trA)

    Eu fiz uma tabela para alterar a ordem do obj no database usado. Depois () .before (), então isso é do que eu experimentei.

     $(obj1).after$(obj2) 

    É inserir obj1 antes de obj2 e

     $(obj1).before$(obj2) 

    faça o contrário.

    Então, se obj1 é depois de obj3 e obj2 depois de obj4, e se você quiser mudar de lugar obj1 e obj2 você fará como

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

    Isto deve ser feito BTW você pode usar .prev () e .next () para encontrar obj3 e obj4 se você não tiver algum tipo de índice para ele já.

    A melhor opção é cloná-los com o método clone ().

    Eu acho que você pode fazer isso muito simples. Por exemplo, digamos que você tenha a próxima estrutura: …

     
    ...
    ...

    e o resultado deve ser

     
    ...
    ...

    jquery:

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

    Espero que ajude!