web-dev-qa-db-fra.com

Comment insérer un élément après un autre élément en JavaScript sans utiliser de bibliothèque?

Il y a insertBefore() en JavaScript, mais comment puis-je insérer un élément après un autre élément sans utiliser jQuery ou une autre bibliothèque?

582
Xah Lee
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);

referenceNode est le noeud que vous voulez mettre newNode après. Si referenceNode est le dernier enfant de son élément parent, pas de problème, car referenceNode.nextSibling sera null et insertBefore gère ce cas en ajoutant à la fin de la liste.

Alors:

function insertAfter(newNode, referenceNode) {
    referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}

Essayez-le ici.

1035
karim79

Une recherche rapide sur Google révèle ce script

// create function, it expects 2 values.
function insertAfter(newElement,targetElement) {
    // target is what you want it to go after. Look for this elements parent.
    var parent = targetElement.parentNode;

    // if the parents lastchild is the targetElement...
    if (parent.lastChild == targetElement) {
        // add the newElement after the target element.
        parent.appendChild(newElement);
    } else {
        // else the target has siblings, insert the new element between the target and it's next sibling.
        parent.insertBefore(newElement, targetElement.nextSibling);
    }
}
31
James Long

insertAdjacentHTML + outerHTML

elementBefore.insertAdjacentHTML('afterEnd', elementAfter.outerHTML)

Upsides:

  • DRYer: vous n'avez pas besoin de stocker le noeud précédent dans une variable et de l'utiliser deux fois. Si vous renommez la variable, moins d’occurrences à modifier. 
  • les golfs sont meilleurs que la variable insertBefore (même si le nom de variable de nœud existant a une longueur de 3 caractères)

Inconvénients:

  • prise en charge inférieure du navigateur depuis les nouvelles: https://caniuse.com/#feat=insert-adjacent
  • perdra les propriétés de l'élément telles que les événements, car outerHTML convertit l'élément en chaîne. Nous en avons besoin car insertAdjacentHTML ajoute du contenu à partir de chaînes plutôt que d'éléments.

Bien que insertBefore() (voir MDN ) soit excellent et référencé par la plupart des réponses ici. Pour plus de flexibilité et pour être un peu plus explicite, vous pouvez utiliser:

insertAdjacentElement() (see MDN ) Ceci vous permet de référencer n'importe quel élément et d'insérer l'élément à déplacer exactement là où vous le souhaitez:

<!-- refElem.insertAdjacentElement('beforebegin', moveMeElem); -->
<p id="refElem">
    <!-- refElem.insertAdjacentElement('afterbegin', moveMeElem); -->
    ... content ...
    <!-- refElem.insertAdjacentElement('beforeend', moveMeElem); -->
</p>
<!-- refElem.insertAdjacentElement('afterend', moveMeElem); -->

Autres à prendre en compte pour des cas d'utilisation similaires: insertAdjacentHTML() et insertAdjacentText()

Références:

https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentElementhttps://developer.mozilla.org/en-US/docs/Web/ API/Element/insertAdjacentHTMLhttps://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentText

9
bit-less

node1.after(node2) produit <node1/><node2/>,

où node1 et node2 sont des noeuds DOM.

.after() n'est pas pris en charge par les anciens navigateurs [1] , vous devrez peut-être appliquer un remplissage multiple.

7
golopot

Ou vous pouvez simplement faire:

referenceNode.parentNode.insertBefore( newNode, referenceNode )
referenceNode.parentNode.insertBefore( referenceNode, newNode )
4
olvlvl

Étape 1. Préparer les éléments:

var element = document.getElementById('ElementToAppendAfter');
var newElement = document.createElement('div');
var elementParent = element.parentNode;

Étape 2. Ajouter après:

elementParent.insertBefore(newElement, element.nextSibling);
4
Malik Khalil

la méthode insertBefore () est utilisée comme parentNode.insertBefore(). Donc, pour imiter cela et créer une méthode parentNode.insertAfter(), nous pouvons écrire le code suivant.

JavaScript

Node.prototype.insertAfter = function(newNode, referenceNode) {
    return referenceNode.parentNode.insertBefore(
        newNode, referenceNode.nextSibling); // based on karim79's solution
};

// getting required handles
var refElem = document.getElementById("pTwo");
var parent = refElem.parentNode;

// creating <p>paragraph three</p>
var txt = document.createTextNode("paragraph three");
var paragraph = document.createElement("p");
paragraph.appendChild(txt);

// now we can call it the same way as insertBefore()
parent.insertAfter(paragraph, refElem);

HTML

<div id="divOne">
    <p id="pOne">paragraph one</p>
    <p id="pTwo">paragraph two</p>
</div>

Notez que l'extension du DOM peut ne pas être la bonne solution pour vous, comme indiqué dans cet article .

Hovewer, cet article a été écrit en 2010 et les choses pourraient être différentes maintenant. Alors décidez vous-même.

Méthode JavaScript DOM insertAfter () @ jsfiddle.net

2
Dmytro Dzyubak

Idéalement, insertAfter devrait fonctionner de la même manière que insertBefore . Le code ci-dessous effectuera les opérations suivantes:

  • S'il n'y a pas d'enfants, la nouvelle Node est ajoutée
  • S'il n'y a pas de référence Node, la nouvelle Node est ajoutée
  • S'il n'y a pas de Node après la référence Node, la nouvelle Node est ajoutée
  • Si la référence Node a un frère après, le nouveau Node est inséré avant ce frère
  • Renvoie la nouvelle Node

Extension Node

Node.prototype.insertAfter = function(node, referenceNode) {

    if (node)
        this.insertBefore(node, referenceNode && referenceNode.nextSibling);

    return node;
};

Un exemple commun

node.parentNode.insertAfter(newNode, node);

Voir le code courant

// First extend
Node.prototype.insertAfter = function(node, referenceNode) {
    
    if (node)
        this.insertBefore(node, referenceNode && referenceNode.nextSibling);

    return node;
};

var referenceNode,
    newNode;

newNode = document.createElement('li')
newNode.innerText = 'First new item';
newNode.style.color = '#FF0000';

document.getElementById('no-children').insertAfter(newNode);

newNode = document.createElement('li');
newNode.innerText = 'Second new item';
newNode.style.color = '#FF0000';

document.getElementById('no-reference-node').insertAfter(newNode);

referenceNode = document.getElementById('no-sibling-after');
newNode = document.createElement('li');
newNode.innerText = 'Third new item';
newNode.style.color = '#FF0000';

referenceNode.parentNode.insertAfter(newNode, referenceNode);

referenceNode = document.getElementById('sibling-after');
newNode = document.createElement('li');
newNode.innerText = 'Fourth new item';
newNode.style.color = '#FF0000';

referenceNode.parentNode.insertAfter(newNode, referenceNode);
<h5>No children</h5>
<ul id="no-children"></ul>

<h5>No reference node</h5>
<ul id="no-reference-node">
  <li>First item</li>
</ul>

<h5>No sibling after</h5>
<ul>
  <li id="no-sibling-after">First item</li>
</ul>

<h5>Sibling after</h5>
<ul>
  <li id="sibling-after">First item</li>
  <li>Third item</li>
</ul>

1
Darlesson

Ce code permet d’insérer un lien juste après le dernier enfant existant dans inlining un petit fichier css

var raf, cb=function(){
    //create newnode
    var link=document.createElement('link');
    link.rel='stylesheet';link.type='text/css';link.href='css/style.css';

    //insert after the lastnode
    var nodes=document.getElementsByTagName('link'); //existing nodes
    var lastnode=document.getElementsByTagName('link')[nodes.length-1]; 
    lastnode.parentNode.insertBefore(link, lastnode.nextSibling);
};

//check before insert
try {
    raf=requestAnimationFrame||
        mozRequestAnimationFrame||
        webkitRequestAnimationFrame||
        msRequestAnimationFrame;
}
catch(err){
    raf=false;
}

if (raf)raf(cb); else window.addEventListener('load',cb);
0
Chetabahana

Je sais que cette question a déjà beaucoup trop de réponses, mais aucune d’entre elles ne répondait exactement à mes exigences.

Je voulais une fonction ayant exactement le comportement opposé de parentNode.insertBefore - c'est-à-dire qu'elle doit accepter une valeur null referenceNode (que le réponse acceptée ne le fait pas) et que insertBefore insère à la fin des enfants que celui-ci doit insérer au start, sinon il n'y aurait aucun moyen d'insérer à l'emplacement de départ avec cette fonction; la même raison insertBefore insère à la fin.

Puisqu’une null referenceNode nécessite que vous localisiez le parent, nous devons savoir que le parent - insertBefore est une méthode de parentNode, afin qu’il ait accès au parent de cette façon; notre fonction ne le fait pas, nous devrons donc passer le parent en tant que paramètre.

La fonction résultante ressemble à ceci:

function insertAfter(parentNode, newNode, referenceNode) {
  parentNode.insertBefore(
    newNode,
    referenceNode ? referenceNode.nextSibling : parentNode.firstChild
  );
}

Ou (si vous devez, je ne le recommande pas), vous pouvez bien sûr améliorer le prototype Node:

if (! Node.prototype.insertAfter) {
  Node.prototype.insertAfter = function(newNode, referenceNode) {
    this.insertBefore(
      newNode,
      referenceNode ? referenceNode.nextSibling : this.firstChild
    );
  };
}
0
mindplay.dk

Vous pouvez utiliser la fonction appendChild pour insérer après un élément.

Référence: http://www.w3schools.com/jsref/met_node_appendchild.asp

0
Doug LN

une implémentation robuste de insertAfter.

// source: https://github.com/jserz/domPlus/blob/master/src/insertAfter()/insertAfter.js
Node.prototype.insertAfter = Node.prototype.insertAfter || function (newNode, referenceNode) {
  function isNode(node) {
    return node instanceof Node;
  }

  if(arguments.length < 2){
    throw(new TypeError("Failed to execute 'insertAfter' on 'Node': 2 arguments required, but only "+ arguments.length +" present."));
  }

  if(isNode(newNode)){
    if(referenceNode === null || referenceNode === undefined){
      return this.insertBefore(newNode, referenceNode);
    }

    if(isNode(referenceNode)){
      return this.insertBefore(newNode, referenceNode.nextSibling);
    }

    throw(new TypeError("Failed to execute 'insertAfter' on 'Node': parameter 2 is not of type 'Node'."));
  }

  throw(new TypeError("Failed to execute 'insertAfter' on 'Node': parameter 1 is not of type 'Node'."));

};

0
jszhou

Permet de gérer tous les scénarios

 function insertAfter(newNode, referenceNode) {
        if(referenceNode && referenceNode.nextSibling && referenceNode.nextSibling.nodeName == '#text')
            referenceNode = referenceNode.nextSibling;

        if(!referenceNode)
            document.body.appendChild(newNode);
        else if(!referenceNode.nextSibling)
            document.body.appendChild(newNode);
        else            
            referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);            
    }
0
Sami
if( !Element.prototype.insertAfter ) {
    Element.prototype.insertAfter = function(item, reference) {
        if( reference.nextSibling )
            reference.parentNode.insertBefore(item, reference.nextSibling);
        else
            reference.parentNode.appendChild(item);
    };
}
0
yavuzkavus
 <!DOCTYPE html>
 <html lang="ca">
 <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script>
        function createDiv(){
            var newDiv = document.createElement("div");
            var txt = document.createTextNode("I'm the second div");
            newDiv.appendChild(txt);
            var x = document.getElementsByTagName("BODY")[0];
            x.insertBefore(newDiv, third);
        }
    </script>
</head>
<body>
    <div class="first">
        <p>
            I'm the first div
        </p>
    </div>
    <div id="third">
        <p>
            I'm the third div
        </p>
    </div>
    <button type= " button " name= " button " onclick = " createDiv() " >
        Create the second Div
    </button>
</body>
</html>
0
Kunal Awasthi