Como mover um elemento para outro elemento?


1689

Eu gostaria de mover um elemento DIV para dentro de outro. Por exemplo, eu quero mover isso (incluindo todos os filhos):

<div id="source">
...
</div>

nisso:

<div id="destination">
...
</div>

para que eu tenha isso:

<div id="destination">
  <div id="source">
    ...
  </div>
</div>

21
Basta usar $ (target_element) .append (to_be_inserted_element);
— Mohammad Areeb Siddiqui

2
Ou: destination.appendChild (origem) usando javascript simples
— luke

podemos conseguir isso usando CSS? isso é possível ?
— RajKumar Samala

6
O @RajKumarSamala CSS não pode alterar a estrutura do HTML, apenas sua apresentação.
— Mark Richman

Respostas:


39

Já tentou JavaScript simples ... destination.appendChild(source);?

onclick = function(){ destination.appendChild(source); }
div{ margin: .1em; } 
#destination{ border: solid 1px red; }
#source {border: solid 1px gray; }
<!DOCTYPE html>
<html>

 <body>

  <div id="destination">
   ###
  </div>
  <div id="source">
   ***
  </div>

 </body>
</html>


* alguém prefixou o evento global onclick do snippet de demonstração com a palavra-chave varem sua tentativa de aprimorar a publicação - mas isso está errado!
— Bekim Bacaj

6
É incrível como as pessoas ainda pensam que jQuery é igual a JavaScript. Não há mais necessidade de jQuery em 2017, realmente.
— Nckollaw

2
não há necessidade de jquery em 2017, mas às vezes ajuda a usar algo mais leve e semelhante para tarefas que você se encontra fazendo repetidas vezes em cada projeto. Eu uso o cash-dom como uma maneira fácil de escutar os eventos document.ready, window.load de uma maneira amigável entre navegadores. mole-mole.
— eballeste

1
Alterando isso para a resposta aceita, agora que é 2020 :)
— Mark Richman

1
É incrível como as pessoas ainda pensam que jQuery é igual a JavaScript. Não há mais necessidade de jQuery em 2020, realmente.
— ii iml0sto1 23/04

1794

Você pode querer usar a appendTofunção (que adiciona ao final do elemento):

$("#source").appendTo("#destination");

Como alternativa, você pode usar a prependTofunção (que adiciona ao início do elemento):

$("#source").prependTo("#destination");

Exemplo:


23
Um aviso de que isso pode não funcionar corretamente no jQuery mobile, pois pode criar outra cópia do elemento.
— Jordan Reiter

32
o appenTo cria uma cópia ou realmente move toda a div para o destino? (porque se copia, criaria Erros ao chamar o div pela id)

50
Aqui está um excelente artigo sobre como remover, substituir e mover elementos no jQuery: elated.com/articles/jquery-removing-replacing-moving-elements
— xhh

42
Observe a documentação do jQuery para os estados appendTo em que o elemento é movido: it will be moved into the target (not cloned) and a new set consisting of the inserted element is returned- api.jquery.com/appendto
— John K

15
Você não está movendo, apenas anexando. A resposta abaixo faz um bom MOVIMENTO.
— Aaron

913

minha solução:

MOVER:

jQuery("#NodesToMove").detach().appendTo('#DestinationContainerNode')

CÓPIA DE:

jQuery("#NodesToMove").appendTo('#DestinationContainerNode')

Observe o uso de .detach (). Ao copiar, tenha cuidado para não duplicar IDs.


86
Melhor resposta. A resposta aceita cria uma cópia, não move o elemento como a pergunta pede.
— paulscode

97
Desculpe, mas a resposta aceita por Andrew Hare está correta - a remoção é desnecessária. Experimente no JSFiddle da Pixic acima - se você remover as chamadas de desanexação, funciona exatamente da mesma forma, ou seja, faz uma jogada, NÃO uma cópia. Aqui está a bifurcação com apenas uma alteração: jsfiddle.net/D46y5 Conforme documentado na API: api.jquery.com/appendTo : "Se um elemento selecionado dessa maneira for inserido em um único local em outro local do DOM, ele será movido no destino (não clonado) e um novo conjunto que consiste no elemento inserido é retornado "
— John - Não é um número

8
@ John-NotANumber está certo - detach () não é necessário aqui. A resposta aceita é a melhor, você só precisa ler a documentação corretamente.
— LeonardChallis 23/09

11
A documentação appendTo também diz: "Se houver mais de um elemento de destino, no entanto, cópias clonadas do elemento inserido serão criadas para cada destino após o primeiro e esse novo conjunto (o elemento original mais os clones) será retornado.". Portanto, no caso geral, esta solução também pode criar cópias!
— Vincent Pazeller

ótimo! Ou você pode usar isso para ser mais específico sobre onde mover$('#nodeToMove').insertAfter('#insertAfterThisElement');
— Victor Augusto

108

Eu apenas usei:

$('#source').prependTo('#destination');

Que eu peguei daqui .


7
Bem, desanexar é útil quando você deseja manter o elemento e reinseri-lo mais tarde, mas no seu exemplo, você o reinsere instantaneamente de qualquer maneira.
— Tim Büthe

1
Receio não estar entendendo o que você está falando, você poderia fornecer um código de exemplo?
— precisa saber é o seguinte

1
Quero dizer, prependTo, desconecta o elemento de sua posição original e o insere no novo. A função de desanexação, por outro lado, apenas desanexa o elemento selecionado e você pode salvá-lo em uma variável para inseri-lo no DOM posteriormente. O problema é que sua chamada de desanexação é desnecessária. Remova-o e você obterá o mesmo efeito.
— Tim Büthe

1
Incrível que as edições mudou esta resposta completamente a tal ponto que uma outra resposta foi adicionado um ano depois (idêntico ao original) e tem mais de 800 upvotes ...
— hlscalon

96

Que tal uma solução JavaScript ?

// Declare a fragment:
var fragment = document.createDocumentFragment();

// Append desired element to the fragment:
fragment.appendChild(document.getElementById('source'));

// Append fragment to desired element:
document.getElementById('destination').appendChild(fragment);

Confira.


8
Por que usar createDocumentFragment em vez de simplesmente document.getElementById ('destination'). AppendChild (document.getElementById ('source'))?
— Gunar Gessner

6
@ GunarC.Gessner supondo que você precise modificar o objeto de origem antes de adicioná-lo ao objeto de destino, a melhor abordagem é usar o fragmento que é um objeto imaginário e não faz parte da árvore do DOM, você obtém um melhor desempenho ao modificar o objeto de origem quando ele foi transferido de seu local original (agora está dentro do fragmento) em vez de modificá-lo no local inicial antes de anexá-lo.
— Ali Bassam

5
Quero acrescentar a relevância de oferecer uma solução pura para JavaScript. Não deve ser assumido jQuery está sempre sendo usado
— Alexander Fradiani

1
Pergunta: Ao anexar o nó filho, estamos perdendo os eventos anexados?
— jimasun

1
A resposta para minha própria pergunta é sim, ela mantém os eventos em anexo.
— jimasun

95

Se o divlocal em que você deseja colocar seu elemento possui conteúdo e você deseja que o elemento seja exibido após o conteúdo principal:

  $("#destination").append($("#source"));

Se o divlocal em que você deseja colocar seu elemento possui conteúdo e você deseja mostrar o elemento antes do conteúdo principal:

$("#destination").prepend($("#source"));

Se o divlocal em que você deseja colocar seu elemento estiver vazio, ou você desejar substituí- lo totalmente:

$("#element").html('<div id="source">...</div>');

Se você deseja duplicar um elemento antes de qualquer uma das opções acima:

$("#destination").append($("#source").clone());
// etc.

Estou achando um pouco difícil de ler todo o negrito, mas esta é a resposta mais informativa, por isso recebe meu voto positivo.
— Michael Scheper

32

Você pode usar:

Para inserir depois,

jQuery("#source").insertAfter("#destination");

Para inserir dentro de outro elemento,

jQuery("#source").appendTo("#destination");

20

Se você quiser uma demonstração rápida e mais detalhes sobre como mover elementos, tente este link:

http://html-tuts.com/move-div-in-another-div-with-jquery


Aqui está um pequeno exemplo:

Para mover ACIMA de um elemento:

$('.whatToMove').insertBefore('.whereToMove');

Para mover APÓS um elemento:

$('.whatToMove').insertAfter('.whereToMove');

Para mover-se dentro de um elemento, ACIMA DE TODOS os elementos dentro desse contêiner:

$('.whatToMove').prependTo('.whereToMove');

Para mover-se dentro de um elemento, APÓS TODOS os elementos dentro desse contêiner:

$('.whatToMove').appendTo('.whereToMove');

19

Você pode usar o seguinte código para mover a origem para o destino

 jQuery("#source")
       .detach()
       .appendTo('#destination');

tente trabalhar codepen


11

Pergunta antiga, mas cheguei aqui porque preciso mover o conteúdo de um contêiner para outro, incluindo todos os ouvintes do evento .

O jQuery não tem como fazê-lo, mas a função DOM padrão appendChild possui.

//assuming only one .source and one .target
$('.source').on('click',function(){console.log('I am clicked');});
$('.target')[0].appendChild($('.source')[0]);

O uso de appendChild remove o .source e o coloca no destino, incluindo seus ouvintes de eventos: https://developer.mozilla.org/en-US/docs/Web/API/Node.appendChild


6

Você também pode tentar:

$("#destination").html($("#source"))

Mas isso substituirá completamente tudo o que você possui #destination.


2
E interrompa os ouvintes de eventos no elemento movido.
— Igor Pomaranskiy

4

Percebi uma grande perda de memória e diferença de desempenho entre insertAfter& afterou insertBefore& before.. Se você possui vários elementos DOM ou precisa usar after()ou before()dentro de um evento MouseMove , a memória do navegador provavelmente aumentará e as próximas operações serão muito lentas.

A solução que acabei de experimentar é usar o insertBefore before()e depois o insertAfter after().


Parece um problema dependente da implementação do mecanismo JavaScript. Com qual versão do navegador e mecanismo JS você vê isso?
— Mark Richman

1
Estou na versão 36.0.1985.125 do Chrome e estou usando o jQuery v1.11.1. Vinculo uma função ao evento mousemove, que move um DIV simples para baixo ou para cima do elemento sobre o qual o mouse está. Portanto, esse evento e função é executado enquanto você arrasta o cursor. O vazamento de memória ocorre com after () e before (), se você mover o cursor por 30seg +, e desaparece se eu apenas usar insertAfter & insertBefore.
— Spetsnaz

1
Eu abriria um bug com o Google nesse caso.
— Mark Richman

2

Você pode usar JavaScript puro, usando o appendChild()método ...

O método appendChild () anexa um nó como o último filho de um nó.

Dica: Se você deseja criar um novo parágrafo, com texto, lembre-se de criar o texto como um nó Texto que você anexa ao parágrafo e, em seguida, anexa o parágrafo ao documento.

Você também pode usar esse método para mover um elemento de um elemento para outro.

Dica: Use o método insertBefore () para inserir um novo nó filho antes de um nó filho especificado e existente.

Para que você possa fazer isso, é isso que eu criei para você, usando appendChild(), execute e veja como funciona no seu caso:

function appendIt() {
  var source = document.getElementById("source");
  document.getElementById("destination").appendChild(source);
}
#source {
  color: white;
  background: green;
  padding: 4px 8px;
}

#destination {
  color: white;
  background: red;
  padding: 4px 8px;
}

button {
  margin-top: 20px;
}
<div id="source">
  <p>Source</p>
</div>

<div id="destination">
  <p>Destination</p>
</div>

<button onclick="appendIt()">Move Element</button>


0

Por uma questão de integridade, há outra abordagem wrap()ou wrapAll()mencionada neste artigo . Portanto, a questão do OP poderia ser resolvida com isso (ou seja, assumindo <div id="destination" />que ainda não exista, a seguinte abordagem criará esse invólucro do zero - o OP não ficou claro se o invólucro já existe ou não):

$("#source").wrap('<div id="destination" />')
// or
$(".source").wrapAll('<div id="destination" />')

Parece promissor. No entanto, quando eu estava tentando fazer $("[id^=row]").wrapAll("<fieldset></fieldset>")em várias estruturas aninhadas como esta:

<div id="row1">
    <label>Name</label>
    <input ...>
</div>

Ela envolve corretamente os <div>...</div>e <input>...</input>mas de alguma forma deixa de fora a <label>...</label>. Então acabei usando o explícito $("row1").append("#a_predefined_fieldset"). Então, YMMV.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.