C'è insertBefore()
in JavaScript, ma come posso inserire un elemento dopo un altro elemento senza usare jQuery o un'altra libreria?
C'è insertBefore()
in JavaScript, ma come posso inserire un elemento dopo un altro elemento senza usare jQuery o un'altra libreria?
Risposte:
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
Dov'è referenceNode
il nodo che vuoi mettere newNode
dopo. Se referenceNode
è l'ultimo figlio all'interno del suo elemento genitore, va bene, perché referenceNode.nextSibling
lo sarànull
e insertBefore
gestirà quel caso aggiungendolo alla fine dell'elenco.
Così:
function insertAfter(newNode, referenceNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
Puoi testarlo utilizzando il seguente frammento:
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()
funziona con nodi di testo. Perché vuoi insertAfter()
essere diverso? È necessario creare una coppia separata di funzioni denominate insertBeforeElement()
e insertAfterElement()
per questo.
Aggiungi prima:
element.parentNode.insertBefore(newElement, element);
Aggiungi dopo:
element.parentNode.insertBefore(newElement, element.nextSibling);
Creando i seguenti prototipi, sarai in grado di chiamare queste funzioni direttamente dagli elementi appena creati.
newElement.appendBefore(element);
newElement.appendAfter(element);
.appendBefore (element) Prototype
Element.prototype.appendBefore = function (element) {
element.parentNode.insertBefore(this, element);
},false;
.appendAfter (element) Prototype
Element.prototype.appendAfter = function (element) {
element.parentNode.insertBefore(this, element.nextSibling);
},false;
existingElement.appendAfter(newElement);
. Vedi cosa intendo in questo jsfiddle aggiornato .
insertAdjacentHTML
+ outerHTML
elementBefore.insertAdjacentHTML('afterEnd', elementAfter.outerHTML)
upsides:
insertBefore
(interrompi anche se il nome della variabile nodo esistente è lungo 3 caratteri)Svantaggi:
outerHTML
converte l'elemento in una stringa. Ne abbiamo bisogno perché insertAdjacentHTML
aggiunge contenuto dalle stringhe anziché dagli elementi..insertAdjacentElement()
Una rapida ricerca su Google rivela questo 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
tornerà null
. Quando node.insertBefore
viene chiamato con null
come secondo argomento, aggiungerà il nodo alla fine della raccolta. In altre parole, il if(parent.lastchild == targetElement) {
ramo è superfluo, perché parent.insertBefore(newElement, targetElement.nextSibling);
affronterà correttamente tutti i casi, anche se all'inizio potrebbe apparire diversamente. Molti lo hanno già sottolineato in altri commenti.
Anche se insertBefore()
(vedi MDN ) è fantastico e indicato dalla maggior parte delle risposte qui. Per una maggiore flessibilità e per essere un po 'più esplicito, puoi usare:
insertAdjacentElement()
(vedi MDN ) Ciò ti consente di fare riferimento a qualsiasi elemento e inserire l'elemento da spostare esattamente dove vuoi:
<!-- refElem.insertAdjacentElement('beforebegin', moveMeElem); -->
<p id="refElem">
<!-- refElem.insertAdjacentElement('afterbegin', moveMeElem); -->
... content ...
<!-- refElem.insertAdjacentElement('beforeend', moveMeElem); -->
</p>
<!-- refElem.insertAdjacentElement('afterend', moveMeElem); -->
Altri da considerare per casi d'uso simili: insertAdjacentHTML()
einsertAdjacentText()
Riferimenti:
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
Il metodo node.after
( doc ) inserisce un nodo dopo un altro nodo.
Per due nodi DOM node1
e node2
,
node1.after(node2)
inserti node2
dopo node1
.
Questo metodo non è disponibile nei browser più vecchi, quindi di solito è necessario un polyfill.
So che questa domanda è antica, ma per tutti i futuri utenti, ecco un prototipo modificato, questo è solo un micro-riempimento per la funzione .insertAfter che non esiste questo prototipo aggiunge direttamente una nuova funzione baseElement.insertAfter(element);
al prototipo Element:
Element.prototype.insertAfter = function(new) {
this.parentNode.insertBefore(new, this.nextSibling);
}
Dopo aver inserito il polyfill in una libreria, gist o semplicemente nel tuo codice (o in qualsiasi altro luogo in cui è possibile fare riferimento) Basta scrivere document.getElementById('foo').insertAfter(document.createElement('bar'));
Nuova modifica: NON DOVREI UTILIZZARE I PROTOTIPI. Sovrascrivono la base di codice predefinita e non sono molto efficienti o sicuri e possono causare errori di compatibilità, ma se è per progetti non commerciali, non dovrebbe importare. se si desidera una funzione sicura per uso commerciale, utilizzare semplicemente una funzione predefinita. non è carino ma funziona:
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
Standard Web attuali per ChildNode: https://developer.mozilla.org/en-US/docs/Web/API/ChildNode
Attualmente è nel Living Standards ed è SICURO.
Per i browser non supportati, utilizzare questo Polyfill: https://github.com/seznam/JAK/blob/master/lib/polyfills/childNode.js
Qualcuno ha detto che il Polyfill usa Protos, quando ho detto che erano cattive pratiche. Sono, specialmente se usati in modo errato, come la mia soluzione per il 2018. Tuttavia, polyfill si trova nella documentazione MDN e utilizza una sorta di inizializzazione ed esecuzione più sicura. Inoltre, è per il supporto del browser più vecchio, nel giorno e nell'età in cui la sovrascrittura del prototipo non era così male.
Come utilizzare la soluzione 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
Oppure puoi semplicemente fare:
referenceNode.parentNode.insertBefore( newNode, referenceNode )
referenceNode.parentNode.insertBefore( referenceNode, newNode )
Passaggio 1. Preparare gli elementi:
var element = document.getElementById('ElementToAppendAfter');
var newElement = document.createElement('div');
var elementParent = element.parentNode;
Passaggio 2. Aggiungi dopo:
elementParent.insertBefore(newElement, element.nextSibling);
Il metodo insertBefore () è usato come parentNode.insertBefore()
. Quindi per imitare questo e creare un metodo parentNode.insertAfter()
possiamo scrivere il seguente codice.
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>
Nota che l'estensione del DOM potrebbe non essere la soluzione giusta per te come indicato in questo articolo .
Hovewer, questo articolo è stato scritto nel 2010 e ora le cose potrebbero essere diverse. Quindi decidi da solo.
Idealmente insertAfter
dovrebbe funzionare in modo simile a insertBefore . Il codice seguente eseguirà le seguenti operazioni:
Node
viene aggiuntoNode
, Node
viene aggiunto il nuovoNode
dopo il riferimento Node
, il nuovo Node
viene aggiuntoNode
ha un fratello dopo, il nuovo Node
viene inserito prima di quel fratelloNode
Estensione Node
Node.prototype.insertAfter = function(node, referenceNode) {
if (node)
this.insertBefore(node, referenceNode && referenceNode.nextSibling);
return node;
};
Un esempio comune
node.parentNode.insertAfter(newNode, node);
Vedi il codice in esecuzione
So che questa domanda ha già troppe risposte, ma nessuna di esse ha soddisfatto i miei esatti requisiti.
Volevo una funzione che ha il comportamento esattamente opposto diparentNode.insertBefore
- cioè, deve accettare un valore nullo referenceNode
(che la risposta accettata non ha) e dove insertBefore
inserire alla fine dei bambini questo deve inserire all'inizio , poiché altrimenti ci ' d non essere assolutamente possibile inserire nella posizione iniziale con questa funzione; lo stesso motivo si insertBefore
inserisce alla fine.
Poiché un null referenceNode
richiede di individuare il genitore, dobbiamo conoscere il genitore - insertBefore
è un metodo di parentNode
, quindi ha accesso al genitore in quel modo; la nostra funzione no, quindi dovremo passare il genitore come parametro.
La funzione risultante è simile al seguente:
function insertAfter(parentNode, newNode, referenceNode) {
parentNode.insertBefore(
newNode,
referenceNode ? referenceNode.nextSibling : parentNode.firstChild
);
}
Oppure (se è necessario, non lo consiglio) puoi ovviamente migliorare il Node
prototipo:
if (! Node.prototype.insertAfter) {
Node.prototype.insertAfter = function(newNode, referenceNode) {
this.insertBefore(
newNode,
referenceNode ? referenceNode.nextSibling : this.firstChild
);
};
}
Questo codice funziona per inserire un elemento di collegamento subito dopo l'ultimo figlio esistente per incorporare un piccolo file 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);
È possibile utilizzare la appendChild
funzione per inserire dopo un elemento.
Riferimento: http://www.w3schools.com/jsref/met_node_appendchild.asp
una solida implementazione di 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'."));
};
Gestiamo tutti gli scenari
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);
};
}
Puoi effettivamente un metodo chiamato after()
nella versione più recente di Chrome, Firefox e Opera. L'aspetto negativo di questo metodo è che Internet Explorer non lo supporta ancora.
Esempio:
// 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 semplice codice HTML per testare che è:
<!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>
Come previsto, sposta l'elemento verso l'alto dopo l'elemento verso il basso