Elemento móvel de JavaScript no DOM

97

Digamos que eu tenha três <div>elementos em uma página. Como posso trocar as posições da primeira e da terceira <div>? jQuery está bem.

testemunho
fonte

Respostas:

110

Trivial com jQuery

$('#div1').insertAfter('#div3');
$('#div3').insertBefore('#div2');

Se quiser fazer isso repetidamente, você precisará usar seletores diferentes, pois os divs manterão seus ids conforme são movidos.

$(function() {
    setInterval( function() {
        $('div:first').insertAfter($('div').eq(2));
        $('div').eq(1).insertBefore('div:first');
    }, 3000 );
});
Tvanfosson
fonte
1
@Ionut - o ponto é que depende do posicionamento relativo dos elementos. Depois de alterar a ordem, você não pode mais encontrar o primeiro e o terceiro por seus ids e precisa descobrir outra maneira. Minha resposta pretendia apenas ilustrar a funcionalidade dos métodos para realizar a tarefa solicitada, não ser uma solução abrangente para trocar o primeiro e o terceiro divs em um conjunto um número arbitrário de vezes.
tvanfosson 01 de
Olá pessoal, uma pergunta rápida: existe uma maneira fácil de restaurar o estado Dom original depois que a função jquery acima for concluída?
Vikita
@Vikita - sim, salve o HTML original e restaure-o. Você pode ter que reaplicar quaisquer manipuladores se eles foram aplicados diretamente em vez de delegados a um elemento superior. Por exemplo,var html = $('#container').html(); ...; $('#container').html(html);
tvanfosson
171

Não há necessidade de usar uma biblioteca para uma tarefa tão trivial:

var divs = document.getElementsByTagName("div");   // order: first, second, third
divs[2].parentNode.insertBefore(divs[2], divs[0]); // order: third, first, second
divs[2].parentNode.insertBefore(divs[2], divs[1]); // order: third, second, first

Isso leva em consideração o fato de que getElementsByTagNameretorna um NodeList ativo que é atualizado automaticamente para refletir a ordem dos elementos no DOM à medida que são manipulados.

Você também pode usar:

var divs = document.getElementsByTagName("div");   // order: first, second, third
divs[0].parentNode.appendChild(divs[0]);           // order: second, third, first
divs[1].parentNode.insertBefore(divs[0], divs[1]); // order: third, second, first

e existem várias outras permutações possíveis, se você quiser experimentar:

divs[0].parentNode.appendChild(divs[0].parentNode.replaceChild(divs[2], divs[0]));

por exemplo :-)

NickFitz
fonte
15
É verdade, mas é difícil argumentar contra a elegância e a legibilidade que algo como o jQuery oferece - sem mencionar os recursos aprimorados prontos para uso.
Crazy Joe Malloy
13
Sim, mas quem faz apenas uma coisa?
tvanfosson 01 de
1
... ou tem apenas 3 divs na página
Ryan Florence
38
@everybody: a pergunta original perguntava como trocar o terceiro e o primeiro divs em uma página que tinha três divs. Essa foi a pergunta que respondi. Se o OP tivesse uma pergunta mais complexa, eles deveriam tê-la feito, e eles teriam uma resposta mais complexa ;-)
NickFitz
26
Se alguém estiver procurando por isso em 2014, considere esta resposta. O jQuery ERA útil naquela época, mas agora não é mais tão útil, porque os navegadores são padronizados, então não há necessidade de adicionar uma biblioteca de 80 kb apenas para fazer uma tarefa tão simples. Além disso, você não saberá o que o DOM realmente é até experimentá-lo sem jQuery :)
gustavohenke
29

.antes e depois

Use o JS vanilla moderno! Muito melhor / mais limpo do que antes. Não há necessidade de consultar um pai.

const div1 = document.getElementById("div1");
const div2 = document.getElementById("div2");
const div3 = document.getElementById("div3");

div2.after(div1);
div2.before(div3);

Suporte do navegador - 94,23% global em julho de 20

Gibolt
fonte
Ainda não há suporte para Internet Explorer.
justnorris
11
Você não deveria ter que escrever um código menos sustentável para dar suporte às pessoas em navegadores que são antigos ou não estão em conformidade com os padrões. A menos que você trabalhe em uma empresa, poucos usuários perderão
Gibolt
Outros métodos funcionam tão bem no que diz respeito à manutenção, especialmente quando envolvidos em uma função de limpeza agradável. Sou totalmente a favor de escrever código moderno, mas isso é o que há de mais moderno. É ótimo saber o que o futuro reserva, mas por mais que eu não goste de nada relacionado ao IE - é importante saber qual é o impacto de suas decisões. Neste caso - um aplicativo da web quebrado em qualquer navegador IE. Se estiver tudo bem para você - ótimo! Eu adicionei o comentário apenas para informar a alguém que está pesquisando sobre isso :)
justnorris
1
Então, 27% dos usuários são poucos usuários ? Estamos falando de milhões!
SandRock
5
Em um ano, esse número ficará mais próximo de 10%. Trata-se principalmente de dispositivos móveis corporativos, governamentais e mais antigos. Isso geralmente significa dispositivos não pessoais ou usuários com menos inclinação técnica. As respostas devem ser futuras, para que não fiquemos parados no desenvolvimento em 2009.
Gibolt
11
jQuery.fn.swap = function(b){ 
    b = jQuery(b)[0]; 
    var a = this[0]; 
    var t = a.parentNode.insertBefore(document.createTextNode(''), a); 
    b.parentNode.insertBefore(a, b); 
    t.parentNode.insertBefore(b, t); 
    t.parentNode.removeChild(t); 
    return this; 
};

e use-o assim:

$('#div1').swap('#div2');

se você não quiser usar o jQuery, pode facilmente adaptar a função.

Darin Dimitrov
fonte
5
var swap = function () {
    var divs = document.getElementsByTagName('div');
    var div1 = divs[0];
    var div2 = divs[1];
    var div3 = divs[2];

    div3.parentNode.insertBefore(div1, div3);
    div1.parentNode.insertBefore(div3, div2);
};

Esta função pode parecer estranha, mas depende muito de padrões para funcionar corretamente. Na verdade, pode parecer funcionar melhor do que a versão jQuery que tvanfosson postou, que parece fazer a troca apenas duas vezes.

Em que peculiaridades dos padrões ele se baseia?

insertBefore Insere o nó newChild antes do nó filho existente refChild. Se refChild for nulo, insira newChild no final da lista de filhos. Se newChild for um objeto DocumentFragment, todos os seus filhos serão inseridos, na mesma ordem, antes de refChild. Se o novo filho já estiver na árvore, ele será removido primeiro.

Ionuț G. Stan
fonte
0

A abordagem Jquery mencionada na parte superior funcionará. Você também pode usar JQuery e CSS. Diga, por exemplo, em Div one você aplicou class1 e div2, você aplicou classe class2 (digamos, por exemplo, cada classe de css fornece uma posição específica no navegador), agora você pode trocar as classes, use jquery ou javascript (isso mudará a posição)

Rajat
fonte
0

Desculpe por interromper este tópico, tropecei no problema "trocar elementos DOM" e brinquei um pouco

O resultado é uma "solução" nativa do jQuery que parece ser muito bonita (infelizmente, não sei o que está acontecendo nos componentes internos do jQuery ao fazer isso)

O código:

$('#element1').insertAfter($('#element2'));

A documentação do jQuery diz que insertAfter() move o elemento e não o clona

Storrm
fonte