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?
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?
Réponses:
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
Où se referenceNode
trouve le nœud que vous souhaitez placer newNode
. Si referenceNode
est le dernier enfant de son élément parent, c'est parfait, car referenceNode.nextSibling
sera null
et insertBefore
gère ce cas en ajoutant à la fin de la liste.
Donc:
function insertAfter(newNode, referenceNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
Vous pouvez le tester à l'aide de l'extrait de code suivant:
function insertAfter(referenceNode, newNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
var el = document.createElement("span");
el.innerHTML = "test";
var div = document.getElementById("foo");
insertAfter(div, el);
<div id="foo">Hello</div>
insertBefore()
fonctionne avec des nœuds de texte. Pourquoi voulez-vous insertAfter()
être différent? Vous devez créer une paire de fonctions distincte nommée insertBeforeElement()
et insertAfterElement()
pour cela.
Ajouter avant:
element.parentNode.insertBefore(newElement, element);
Ajouter après:
element.parentNode.insertBefore(newElement, element.nextSibling);
En construisant les prototypes suivants, vous pourrez appeler ces fonctions directement à partir des éléments nouvellement créés.
newElement.appendBefore(element);
newElement.appendAfter(element);
Prototype .appendBefore (élément)
Element.prototype.appendBefore = function (element) {
element.parentNode.insertBefore(this, element);
},false;
Prototype .appendAfter (élément)
Element.prototype.appendAfter = function (element) {
element.parentNode.insertBefore(this, element.nextSibling);
},false;
existingElement.appendAfter(newElement);
. Voyez ce que je veux dire à ce jsfiddle mis à jour .
insertAdjacentHTML
+ outerHTML
elementBefore.insertAdjacentHTML('afterEnd', elementAfter.outerHTML)
Avantages:
insertBefore
(seuil de rentabilité même si le nom de variable de nœud existant est long de 3 caractères)Inconvénients:
outerHTML
convertit l'élément en chaîne. Nous en avons besoin car il insertAdjacentHTML
ajoute du contenu à partir de chaînes plutôt que d'éléments..insertAdjacentElement()
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);
}
}
targetElement.nextSibling
retournera null
. Lorsque node.insertBefore
est appelé avec null
comme deuxième argument, il ajoutera le nœud à la fin de la collection. En d'autres termes, la if(parent.lastchild == targetElement) {
branche est superflue, car parent.insertBefore(newElement, targetElement.nextSibling);
elle traitera correctement tous les cas, même si elle peut sembler différente au premier abord. Beaucoup l'ont déjà souligné dans d'autres commentaires.
Cependant insertBefore()
(voir MDN ) est génial 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()
(voir MDN ) Cela vous permet de référencer n'importe quel élément et d'insérer l'élément à déplacer exactement 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); -->
D'autres à considérer pour des cas d'utilisation similaires: insertAdjacentHTML()
etinsertAdjacentText()
Références:
https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentElement https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML https: // developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentText
La méthode node.after
( doc ) insère un nœud après un autre nœud.
Pour deux nœuds DOM node1
et node2
,
node1.after(node2)
insère node2
aprèsnode1
.
Cette méthode n'est pas disponible dans les anciens navigateurs, donc généralement un polyfill est nécessaire.
Je sais que cette question est ancienne, mais pour tous les futurs utilisateurs, voici un prototype modifié, ce n'est qu'un micro-remplissage pour la fonction .insertAfter qui n'existe pas, ce prototype ajoute directement une nouvelle fonction baseElement.insertAfter(element);
au prototype Element:
Element.prototype.insertAfter = function(new) {
this.parentNode.insertBefore(new, this.nextSibling);
}
Une fois que vous avez placé le polyfill dans une bibliothèque, un résumé ou simplement dans votre code (ou n'importe où ailleurs où il peut être référencé) document.getElementById('foo').insertAfter(document.createElement('bar'));
Nouvelle édition: VOUS NE DEVEZ PAS UTILISER DE PROTOTYPES. Ils écrasent la base de code par défaut et ne sont pas très efficaces ou sûrs et peuvent provoquer des erreurs de compatibilité, mais si c'est pour des projets non commerciaux, cela ne devrait pas avoir d'importance. si vous voulez une fonction sûre pour une utilisation commerciale, utilisez simplement une fonction par défaut. ce n'est pas joli mais ça marche:
function insertAfter(el, newEl) {
el.parentNode.insertBefore(newEl, this.nextSibling);
}
// use
const el = document.body || document.querySelector("body");
// the || means "this OR that"
el.insertBefore(document.createElement("div"), el.nextSibling);
// Insert Before
insertAfter(el, document.createElement("div"));
// Insert After
Normes Web actuelles pour ChildNode: https://developer.mozilla.org/en-US/docs/Web/API/ChildNode
Son actuellement dans le niveau de vie et est sûr.
Pour les navigateurs non pris en charge, utilisez ce Polyfill: https://github.com/seznam/JAK/blob/master/lib/polyfills/childNode.js
Quelqu'un a mentionné que le Polyfill utilise Protos, quand j'ai dit que c'était une mauvaise pratique. Ils le sont, surtout lorsqu'ils sont mal utilisés, comme ma solution pour 2018. Cependant, ce polyfill est sur la documentation MDN et utilise une sorte d'initialisation et d'exécution qui est plus sûre. De plus, c'est pour la prise en charge de navigateurs plus anciens, à l'époque où l'écrasement de prototypes n'était pas si mal.
Comment utiliser la solution 2020:
const el = document.querySelector(".class");
// Create New Element
const newEl = document.createElement("div");
newEl.id = "foo";
// Insert New Element BEFORE
el.before(newEl);
// Insert New Element AFTER
el.after(newEl);
// Remove Element
el.remove();
// Remove Child
newEl.remove(); // This one wasnt tested but should work
Ou vous pouvez simplement faire:
referenceNode.parentNode.insertBefore( newNode, referenceNode )
referenceNode.parentNode.insertBefore( referenceNode, newNode )
Étape 1. Préparez 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);
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 .
Cependant, cet article a été écrit en 2010 et les choses pourraient être différentes maintenant. Alors décidez par vous-même.
Idéalement, il insertAfter
devrait fonctionner de manière similaire à insertBefore . Le code ci-dessous effectuera les opérations suivantes:
Node
est ajoutéNode
, le nouveau Node
est ajoutéNode
après la référence Node
, le nouveau Node
est ajoutéNode
a un frère après, le nouveau Node
est inséré avant ce frèreNode
Extension Node
Node.prototype.insertAfter = function(node, referenceNode) {
if (node)
this.insertBefore(node, referenceNode && referenceNode.nextSibling);
return node;
};
Un exemple courant
node.parentNode.insertAfter(newNode, node);
Voir le code en cours d'exécution
Je sais que cette question a déjà beaucoup trop de réponses, mais aucune ne répond à mes exigences exactes.
Je voulais une fonction qui a le comportement exactement opposé deparentNode.insertBefore
- c'est-à-dire qu'elle doit accepter un null referenceNode
(ce que la réponse acceptée ne fait pas) et où insertBefore
insérer à la fin des enfants celui-ci doit insérer au début , car sinon il ' d aucun moyen d'insérer à l'emplacement de départ avec cette fonction; la même raison insertBefore
insère à la fin.
Puisqu'un null referenceNode
vous oblige à localiser le parent, nous devons connaître le parent - insertBefore
est une méthode de laparentNode
, donc il a accès au parent de cette façon; notre fonction ne fonctionne pas, nous devons donc passer le parent comme paramètre.
La fonction résultante ressemble à ceci:
function insertAfter(parentNode, newNode, referenceNode) {
parentNode.insertBefore(
newNode,
referenceNode ? referenceNode.nextSibling : parentNode.firstChild
);
}
Ou (si vous le devez, je ne le recommande pas), vous pouvez bien sûr améliorer le Node
prototype:
if (! Node.prototype.insertAfter) {
Node.prototype.insertAfter = function(newNode, referenceNode) {
this.insertBefore(
newNode,
referenceNode ? referenceNode.nextSibling : this.firstChild
);
};
}
Ce code permet d'insérer un élément de lien juste après le dernier enfant existant pour insérer 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);
Vous pouvez utiliser appendChild
fonction pour insérer après un élément.
Référence: http://www.w3schools.com/jsref/met_node_appendchild.asp
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'."));
};
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);
}
if( !Element.prototype.insertAfter ) {
Element.prototype.insertAfter = function(item, reference) {
if( reference.nextSibling )
reference.parentNode.insertBefore(item, reference.nextSibling);
else
reference.parentNode.appendChild(item);
};
}
Vous pouvez en fait utiliser une méthode appelée after()
dans une version plus récente de Chrome, Firefox et Opera. L'inconvénient de cette méthode est qu'Internet Explorer ne la prend pas encore en charge.
Exemple:
// You could create a simple node
var node = document.createElement('p')
// And then get the node where you want to append the created node after
var existingNode = document.getElementById('id_of_the_element')
// Finally you can append the created node to the exisitingNode
existingNode.after(node)
Un code HTML simple à tester qui est:
<!DOCTYPE html>
<html>
<body>
<p id='up'>Up</p>
<p id="down">Down</p>
<button id="switchBtn" onclick="switch_place()">Switch place</button>
<script>
function switch_place(){
var downElement = document.getElementById("down")
var upElement = document.getElementById("up")
downElement.after(upElement);
document.getElementById('switchBtn').innerHTML = "Switched!"
}
</script>
</body>
</html>
Comme prévu, il déplace l'élément vers le haut après l'élément vers le bas