Comment déplacer un élément dans un autre élément?

1689

Je voudrais déplacer un élément DIV à l'intérieur d'un autre. Par exemple, je veux déplacer ceci (y compris tous les enfants):

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

en cela:

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

de sorte que j'ai ceci:

<div id="destination">
  <div id="source">
    ...
  </div>
</div>
Mark Richman
la source
21
Utilisez simplement $ (target_element) .append (to_be_instered_element);
Mohammad Areeb Siddiqui
2
Ou: destination.appendChild (source) en utilisant du javascript ordinaire
luke
pouvons-nous y parvenir en utilisant CSS? est-ce possible ?
RajKumar Samala,
6
@RajKumarSamala CSS ne peut pas modifier la structure du HTML, seulement sa présentation.
Mark Richman

Réponses:

39

Avez-vous déjà essayé du JavaScript simple ... 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>

Bekim Bacaj
la source
* quelqu'un a préfixé l' événement global onclick de l'extrait de démo avec le mot-clé vardans sa tentative d'améliorer la publication - mais c'est faux!
Bekim Bacaj
6
C'est incroyable de voir comment les gens pensent toujours que jQuery est égal à JavaScript. Plus besoin de jQuery en 2017, vraiment.
nkkollaw
2
pas besoin de jquery en 2017, mais il est parfois utile d'utiliser quelque chose de plus léger et similaire pour les tâches que vous vous retrouvez à faire encore et encore dans chaque projet. J'utilise cash-dom comme un moyen facile d'écouter les événements document.ready, window.load d'une manière conviviale pour tous les navigateurs. peasy facile.
eballeste
1
Changer cela en réponse acceptée, maintenant que c'est 2020 :)
Mark Richman
1
C'est incroyable de voir comment les gens pensent toujours que jQuery est égal à JavaScript. Plus besoin de jQuery en 2020, vraiment.
ii iml0sto1
1794

Vous voudrez peut-être utiliser la appendTofonction (qui ajoute à la fin de l'élément):

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

Alternativement, vous pouvez utiliser la prependTofonction (qui ajoute au début de l'élément):

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

Exemple:

Andrew Hare
la source
23
Un avertissement que cela peut ne pas fonctionner correctement dans jQuery mobile, car il peut créer une autre copie de l'élément à la place.
Jordan Reiter
32
l'appliPour créer une copie ou déplace-t-elle réellement la division entière vers la destination? (parce que s'il copie, cela créerait des erreurs lors de l'appel de la div par l'ID)
50
Voici un excellent article sur la suppression, le remplacement et le déplacement d'éléments dans jQuery: elated.com/articles/jquery-removing-replacing-moving-elements
xhh
42
Notez la documentation jQuery pour appendTo indique que l'élément est déplacé: 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
Vous ne le déplacez pas, vous ajoutez simplement. La réponse ci-dessous fait un bon mouvement.
Aaron
913

ma solution:

BOUGE TOI:

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

COPIE:

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

Notez l'utilisation de .detach (). Lors de la copie, veillez à ne pas dupliquer les ID.

Alejandro Illecas
la source
86
Meilleure réponse. La réponse acceptée crée une copie, ne déplace pas l'élément comme le demande la question.
paulscode
97
Désolé, mais la réponse acceptée d'Andrew Hare est correcte - le détachement n'est pas nécessaire. Essayez-le dans JSFiddle de Pixic ci-dessus - si vous supprimez les appels de détachement, cela fonctionne exactement de la même manière, c'est-à-dire qu'il effectue un mouvement, PAS une copie. Voici le fork avec juste un changement: jsfiddle.net/D46y5 Comme documenté dans l'API: api.jquery.com/appendTo : "Si un élément sélectionné de cette façon est inséré dans un seul emplacement ailleurs dans le DOM, il sera déplacé dans la cible (non cloné) et un nouvel ensemble composé de l'élément inséré est renvoyé "
John - Not A Number
8
@ John-NotANumber a raison - detach () n'est pas nécessaire ici. La réponse acceptée est la meilleure, il vous suffit de lire correctement la documentation.
LeonardChallis
11
La documentation appendTo indique également: "S'il y a plus d'un élément cible, cependant, des copies clonées de l'élément inséré seront créées pour chaque cible après la première, et ce nouvel ensemble (l'élément d'origine plus les clones) est renvoyé.". Donc dans le cas général, cette solution PEUT aussi créer des copies!
Vincent Pazeller
génial! Ou vous pouvez l'utiliser pour être plus précis sur l'endroit où vous déplacer$('#nodeToMove').insertAfter('#insertAfterThisElement');
Victor Augusto
108

Je viens d'utiliser:

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

Que j'ai attrapé d' ici .

kjc26ster
la source
7
Eh bien, détacher est utile lorsque vous souhaitez conserver l'élément et le réinsérer plus tard, mais dans votre exemple, vous le réinsérez instantanément de toute façon.
Tim Büthe
1
J'ai bien peur de ne pas comprendre ce que vous voulez dire, pourriez-vous fournir un exemple de code?
kjc26ster
1
Je veux dire, prependTo, détache l'élément de sa position d'origine et l'insère à la nouvelle. La fonction de détachement, d'autre part, détache simplement l'élément sélectionné et vous pouvez l'enregistrer dans une variable pour l'insérer dans le DOM ultérieurement. Le fait est que votre appel de détachement n'est pas nécessaire. Retirez-le et vous obtiendrez le même effet.
Tim Büthe
1
Incroyable que les modifications ont complètement changé cette réponse au point qu'une autre réponse a été ajoutée un an plus tard (identique à l'original) et a obtenu plus de 800 votes positifs ...
hlscalon
96

Et une solution 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);

Vérifiez-le.

Ali Bassam
la source
8
Pourquoi utiliser createDocumentFragment au lieu de simplement document.getElementById ('destination'). AppendChild (document.getElementById ('source'))?
Gunar Gessner
6
@ GunarC.Gessner en supposant que vous devez modifier l'objet source avant de l'ajouter à l'objet de destination, la meilleure approche consiste à utiliser le fragment qui est un objet imaginaire et qui ne fait pas partie de l'arborescence DOM, vous obtenez de meilleures performances lors de la modification du objet source lorsqu'il a été transféré de son emplacement d'origine (maintenant il se trouve à l'intérieur du fragment) plutôt que de le modifier à son emplacement initial avant de l'ajouter.
Ali Bassam
5
Je veux ajouter pour la pertinence d'offrir une solution pure JavaScript. Il ne faut pas supposer que jQuery est toujours utilisé
Alexander Fradiani
1
Question: En ajoutant le nœud enfant, perdons-nous les événements attachés?
jimasun
1
La réponse à ma propre question est oui, elle conserve les événements joints.
jimasun
95

Si l' divendroit où vous souhaitez placer votre élément contient du contenu et que vous souhaitez que l'élément s'affiche après le contenu principal:

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

Si l' divemplacement où vous souhaitez placer votre élément contient du contenu et que vous souhaitez afficher l'élément avant le contenu principal:

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

Si l' divendroit où vous souhaitez placer votre élément est vide, ou si vous souhaitez le remplacer entièrement:

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

Si vous souhaitez dupliquer un élément avant l'un des éléments ci-dessus:

$("#destination").append($("#source").clone());
// etc.
sbaaaang
la source
Je trouve tous les caractères gras un peu difficiles à lire, mais c'est la réponse la plus informative, donc cela obtient mon vote positif.
Michael Scheper
32

Vous pouvez utiliser:

Pour insérer après,

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

Pour insérer à l'intérieur d'un autre élément,

jQuery("#source").appendTo("#destination");
Subrahmanyam
la source
20

Si vous souhaitez une démonstration rapide et plus de détails sur la façon dont vous déplacez les éléments, essayez ce lien:

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


Voici un petit exemple:

Pour se déplacer au-dessus d'un élément:

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

Pour se déplacer APRÈS un élément:

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

Pour se déplacer à l'intérieur d'un élément, AU-DESSUS DE TOUS les éléments à l'intérieur de ce conteneur:

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

Pour se déplacer à l'intérieur d'un élément, APRÈS TOUS les éléments à l'intérieur de ce conteneur:

$('.whatToMove').appendTo('.whereToMove');
Dan
la source
19

Vous pouvez utiliser le code suivant pour déplacer la source vers la destination

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

essayez de travailler codepen

Subodh Ghulaxe
la source
11

Vieille question mais arrivée ici parce que je dois déplacer le contenu d'un conteneur à un autre, y compris tous les écouteurs d'événements .

jQuery n'a pas de moyen de le faire, mais la fonction DOM standard appendChild en a un.

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

L'utilisation d'appendChild supprime le .source et le place dans la cible, y compris ses écouteurs d'événements: https://developer.mozilla.org/en-US/docs/Web/API/Node.appendChild

HMR
la source
6

Vous pouvez également essayer:

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

Mais cela écrasera complètement tout ce que vous avez #destination.

Tamas
la source
2
Et brisez les écouteurs d'événements sur l'élément déplacé.
Igor Pomaranskiy
4

J'ai remarqué une énorme fuite de mémoire et une différence de performances entre insertAfter& afterou insertBefore& before.. Si vous avez des tonnes d'éléments DOM, ou si vous devez utiliser after()ou à l' before()intérieur d'un événement MouseMove , la mémoire du navigateur augmentera probablement et les opérations suivantes s'exécuteront très lentement.

La solution que je viens de découvrir est d'utiliser à la place before()inserBefore et insertAfter à la place after().

spetsnaz
la source
Cela ressemble à un problème dépendant de l'implémentation du moteur JavaScript. Avec quelle version de navigateur et quel moteur JS voyez-vous cela?
Mark Richman
1
Je suis sur la version Chrome 36.0.1985.125 et j'utilise jQuery v1.11.1. Je lie une fonction sur l'événement mousemove, qui déplace un simple DIV vers le bas ou vers le haut de l'élément sur lequel se trouve la souris. Par conséquent, cet événement et cette fonction s'exécutent pendant que vous faites glisser votre curseur. La fuite de mémoire se produit avec after () et before (), si vous déplacez votre curseur pendant 30 sec +, et elle disparaît si j'utilise à la place insertAfter et insertBefore.
spetsnaz
1
J'ouvrirais un bogue avec Google à ce sujet.
Mark Richman
2

Vous pouvez utiliser du JavaScript pur, en utilisant la appendChild()méthode ...

La méthode appendChild () ajoute un nœud en tant que dernier enfant d'un nœud.

Conseil: Si vous souhaitez créer un nouveau paragraphe, avec du texte, n'oubliez pas de créer le texte en tant que nœud de texte que vous ajoutez au paragraphe, puis ajoutez le paragraphe au document.

Vous pouvez également utiliser cette méthode pour déplacer un élément d'un élément à un autre.

Conseil: utilisez la méthode insertBefore () pour insérer un nouveau nœud enfant avant un nœud enfant spécifié et existant.

Vous pouvez donc faire cela pour faire le travail, voici ce que j'ai créé pour vous, en utilisant appendChild(), en exécutant et en voyant comment cela fonctionne pour votre cas:

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>

Alireza
la source
0

Par souci d'exhaustivité, il existe une autre approche wrap()ou wrapAll()mentionnée dans cet article . Donc, la question de l'OP pourrait éventuellement être résolue par cela (c'est-à-dire, en supposant que le <div id="destination" />n'existe pas encore, l'approche suivante créera un tel wrapper à partir de zéro - l'OP n'était pas clair quant à savoir si le wrapper existe déjà ou non):

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

Cela semble prometteur. Cependant, lorsque j'essayais de faire $("[id^=row]").wrapAll("<fieldset></fieldset>")sur plusieurs structures imbriquées comme ceci:

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

Il enveloppe correctement ceux-ci <div>...</div>et <input>...</input>MAIS QUELQUES-UNS LAISSENT <label>...</label>. J'ai donc fini par utiliser l'explicite à la $("row1").append("#a_predefined_fieldset")place. Alors, YMMV.

RayLuo
la source
0

amélioration de la taille sale de la réponse de Bekim Bacaj

div { border: 1px solid ; margin: 5px }
<div id="source" onclick="destination.appendChild(this)">click me</div>
<div id="destination" >...</div>

Kamil Kiełczewski
la source