Élément mobile JavaScript dans le DOM

97

Disons que j'ai trois <div>éléments sur une page. Comment puis-je échanger les positions du premier et du troisième <div>? jQuery est très bien.

coeur
la source

Réponses:

110

Trivial avec jQuery

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

Si vous voulez le faire à plusieurs reprises, vous devrez utiliser différents sélecteurs car les divs conserveront leurs identifiants lorsqu'ils sont déplacés.

$(function() {
    setInterval( function() {
        $('div:first').insertAfter($('div').eq(2));
        $('div').eq(1).insertBefore('div:first');
    }, 3000 );
});
Tvanfosson
la source
1
@Ionut - le fait est que cela dépend du positionnement relatif des éléments. Une fois que vous modifiez l'ordre, vous ne pouvez plus trouver le premier et le troisième par leurs identifiants et vous devez trouver un autre moyen. Ma réponse visait uniquement à illustrer la fonctionnalité des méthodes pour accomplir la tâche demandée, pas à être une solution complète pour échanger les premier et troisième divs dans un ensemble un nombre arbitraire de fois.
tvanfosson le
Salut les gars, une question rapide: existe-t-il un moyen simple de revenir à l'état d'origine Dom une fois la fonction jquery ci-dessus terminée?
Vikita
@Vikita - oui, enregistrez le HTML d'origine puis restaurez-le. Vous devrez peut-être réappliquer les gestionnaires s'ils ont été directement appliqués au lieu d'être délégués à un élément supérieur. Par exemple,var html = $('#container').html(); ...; $('#container').html(html);
tvanfosson
171

Il n'est pas nécessaire d'utiliser une bibliothèque pour une tâche aussi triviale:

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

Cela tient compte du fait que getElementsByTagNamerenvoie une liste de nœuds en direct qui est automatiquement mise à jour pour refléter l'ordre des éléments dans le DOM au fur et à mesure de leur manipulation.

Vous pouvez également utiliser:

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

et il existe diverses autres permutations possibles, si vous avez envie d'expérimenter:

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

par exemple :-)

NickFitz
la source
15
C'est vrai, mais il est difficile de discuter de l'élégance et de la lisibilité que fournit quelque chose comme jQuery - sans parler des capacités améliorées prêtes à l'emploi.
Crazy Joe Malloy
13
Oui, mais qui ne fait que cette chose?
tvanfosson le
1
... ou n'a que 3 divs sur la page
Ryan Florence
38
@everybody: la question initiale demandait comment échanger les troisième et premier divs sur une page qui avait trois divs. Telle était la question à laquelle j'ai répondu. Si l'OP avait une question plus complexe, ils auraient dû la poser, et ils auraient obtenu une réponse plus complexe ;-)
NickFitz
26
Si quelqu'un cherche cela en 2014, veuillez considérer cette réponse. jQuery était utile à l'époque, mais maintenant il n'est plus si utile, car les navigateurs sont standardisés, donc pas besoin d'ajouter une bibliothèque de 80 ko juste pour faire une tâche aussi simple. De plus, vous ne savez pas ce qu'est vraiment le DOM tant que vous ne l'avez pas essayé sans jQuery :)
gustavohenke
29

.avant et après

Utilisez la vanille JS moderne! Bien mieux / plus propre qu'auparavant. Pas besoin de référencer un parent.

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

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

Prise en charge des navigateurs - 94,23% dans le monde à partir de juillet 20

Gibolt
la source
Pas encore de support Internet Explorer.
justnorris
11
Vous ne devriez pas avoir à écrire du code moins maintenable pour soutenir les utilisateurs de navigateurs anciens ou non conformes aux normes. À moins que vous ne travailliez en entreprise, peu d'utilisateurs manqueront
Gibolt
D'autres méthodes fonctionnent aussi bien en ce qui concerne la maintenabilité, en particulier lors de l'enveloppement dans une fonction de nettoyage agréable. Je suis tout à fait pour écrire du code moderne, mais c'est à la fine pointe. C'est formidable de savoir ce que l'avenir nous réserve, mais autant que je n'aime pas quoi que ce soit lié à IE, il est important de savoir quel est l'impact de vos décisions. Dans ce cas - une application Web cassée dans n'importe quel navigateur IE. Si cela vous convient, c'est parfait! J'ai ajouté le commentaire juste pour informer quiconque
cherche sur
1
Donc 27% des utilisateurs sont quelques utilisateurs ? Nous parlons de millions!
SandRock
5
Dans un an, ce nombre sera plus proche de 10%. Il s'agit principalement d'appareils mobiles d'entreprise, gouvernementaux et plus anciens. Cela signifie généralement des appareils non personnels ou des utilisateurs moins techniquement enclins. Les réponses devraient être tournées vers l'avenir afin que nous ne soyons pas coincés dans le développement en 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; 
};

et utilisez-le comme ceci:

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

si vous ne souhaitez pas utiliser jQuery, vous pouvez facilement adapter la fonction.

Darin Dimitrov
la source
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);
};

Cette fonction peut paraître étrange, mais elle s'appuie fortement sur des standards pour fonctionner correctement. En fait, cela peut sembler mieux fonctionner que la version jQuery que tvanfosson a publiée et qui semble ne faire l'échange que deux fois.

Sur quelles particularités des normes s'appuie-t-il?

insertBefore Insère le nœud newChild avant le nœud enfant refChild existant. Si refChild est nul, insérez newChild à la fin de la liste des enfants. Si newChild est un objet DocumentFragment, tous ses enfants sont insérés, dans le même ordre, avant refChild. Si le newChild est déjà dans l'arborescence, il est d'abord supprimé.

Ionuț G. Stan
la source
0

L'approche Jquery mentionnée en haut fonctionnera. Vous pouvez également utiliser JQuery et CSS. Dites par exemple sur Div one que vous avez appliqué class1 et div2 vous avez appliqué la classe class2 (par exemple, chaque classe de css fournit une position spécifique sur le navigateur), maintenant vous pouvez échanger les classes utiliser jquery ou javascript (cela changera la position)

Rajat
la source
0

Désolé d'avoir heurté ce fil, j'ai trébuché sur le problème "swap DOM-elements" et j'ai joué un peu

Le résultat est une "solution" native de jQuery qui semble vraiment jolie (malheureusement, je ne sais pas ce qui se passe au niveau des composants internes de jQuery en faisant cela)

Le code:

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

La documentation jQuery dit que cela insertAfter() déplace l'élément et ne le clone pas

stockage
la source