dom - Hvordan sette inn et element etter et annet element i JavaScript uten å bruke et bibliotek?


Det finnes insertBefore() i JavaScript, men hvordan kan jeg sette inn et element etter et annet element uten å bruke jQuery eller et annet bibliotek?

Svar #1

referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);

Der referenceNode er noden du vil sette newNode etter. Hvis referenceNode er det siste barnet i foreldrelementet sitt, er det greit, fordi referenceNode.nextSibling vil være null og insertBefore håndterer det tilfellet ved å legge til på slutten av listen.

Så :

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

Du kan teste det ved å bruke følgende kodebit:

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>

Svar #2

insertBefore() er flott og referert til av de fleste svarene her. For ekstra fleksibilitet, og for å være litt mer eksplisitt, kan du bruke insertAdjacentElement() slik:

refElem.insertAdjacentElement(position, newElem)

Det lar deg referere til et hvilket som helst element, og sette inn elementet som skal flyttes akkurat der du vil. Posisjonen kan være en av: 'beforebegin', 'afterbegin', 'beforeend', 'afterend') som vist her:

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

Andre alternativer å vurdere for lignende bruksområder er insertAdjacentHTML() og insertAdjacentText()

Referanser:

  • MDN: Element.insertAdjacentElement()
  • MDN: Element.insertAdjacentHTML()
  • MDN: Element.insertAdjacentText()

Svar #3

Enkel JavaScript ville være følgende:

Sett inn før:

element.parentNode.insertBefore(newElement, element);

Sett inn etter:

element.parentNode.insertBefore(newElement, element.nextSibling);

Men kast noen prototyper inn der for enkel bruk:

Ved å bygge følgende prototyper, vil du kunne kalle disse funksjonene direkte fra nylig opprettede elementer.

  • 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;

Kodebit for å se det hele i aksjon:

/* Adds Element BEFORE NeighborElement */
Element.prototype.appendBefore = function(element) {
  element.parentNode.insertBefore(this, element);
}, false;

/* Adds Element AFTER NeighborElement */
Element.prototype.appendAfter = function(element) {
  element.parentNode.insertBefore(this, element.nextSibling);
}, false;


/* Typical Creation and Setup A New Orphaned Element Object */
var NewElement = document.createElement('div');
NewElement.innerHTML = 'New Element';
NewElement.id = 'NewElement';


/* Add NewElement BEFORE -OR- AFTER Using the Aforementioned Prototypes */
NewElement.appendAfter(document.getElementById('Neighbor2'));
div {
  text-align: center;
}
#Neighborhood {
  color: brown;
}
#NewElement {
  color: green;
}
<div id="Neighborhood">
  <div id="Neighbor1">Neighbor 1</div>
  <div id="Neighbor2">Neighbor 2</div>
  <div id="Neighbor3">Neighbor 3</div>
</div>

Kjør det på JSFiddle

Svar #4

2022 Løsning - Element

REDIGER: Fra og med 2021 og fremover har ChildNode blitt slått sammen med Element. Jeg endrer dette svaret deretter.

Ny dokumentasjon: https://developer.mozilla.org/en-US/docs/Web/API/Element

Dette er nøyaktig det samme som ChildNode. Egenskapene "before", "after" og "remove" er nå bare en del av det vanlige element-APIet.

// Parent 
const el = document.body;
// New Element
const newEl = document.createElement("div");

// Insert Before Element
el.before(newEl);

// Insert After Element
// Technically this would be invalid because 
// I already inserted newEl before el.
// newEl changed location and is no longer a floating element.
// You cant insert one element in two places at once.
el.after(newEl);

// Another extra feature originally added with ChildNode is the .remove() method,
// which deletes the element from the DOM
el.remove();
newEl.remove();


2019-løsning (utdatert)

Jeg anbefaler ikke å bruke denne løsningen, men jeg beholder den her for "historiens" skyld

Dette er tryggere enn å bruke en polyfill-type prototype-overskriving, det er bare en grunnleggende funksjon. Selvfølgelig er det ikke veldig pent, men det fungerer.

// Parent
const el = document.body;
// New Element
const newEl = document.createElement("div");

// Function You Need
function insertAfter(el0, el1) {
    el0.parentNode.insertBefore(el1, el0.nextSibling);
}

// Insert Before Element
el.insertBefore(newEl);

// Insert After Element
insertAfter(el, newEl);

// Just remember you cant use insertAfter() or .insertBefore()
// on newEl more than once.
// You cant insert one element in two places at once.

Opprinnelig løsning (dårlig praksis)

Jeg anbefaler ikke å bruke denne løsningen, det var den jeg opprinnelig brukte da jeg publiserte dette svaret. Jeg lar den stå her for "historikkens" skyld

Dette er bare en polyfill for .insertAfter-funksjonen som ikke eksisterer. Dette prototype legger direkte til funksjonen HTMLElement.insertAfter(element); til HTMLElement-prototypen:

// Parent
const el = document.body;
// New Element
const newEl = document.createElement("div");

// Custom Method
Element.prototype.insertAfter = function(new) {
    this.parentNode.insertBefore(new, this.nextSibling);
}

// Insert Before Element
el.insertBefore(newEl)

// Insert After Element
el.insertAfter(newEl);

// Just remember you cant use .insertAfter() or .insertBefore() 
// on newEl more than once.
// You cant insert one element in two places at once.

Svar #5

insertAdjacentHTML + outerHTML

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

Fordeler :

  • DRYer: du trenger ikke å lagre forrige node i en variabel og bruke den to ganger. Hvis du gir variabelen nytt navn, er det én forekomst mindre å endre.
  • golfs bedre enn insertBefore (bryter selv om den eksisterende nodens variabelnavn er 3 tegn langt)

Ulemper:

  • lavere nettleserstøtte siden nyere: https://caniuse.com/#feat=insert-adjacent
  • vil miste egenskaper til elementet som hendelser fordi outerHTML konverterer elementet til en streng. Vi trenger det fordi insertAdjacentHTML legger til innhold fra strenger i stedet for elementer.

Svar #6

Et raskt Google-søk avslører dette skriptet

// 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);
    }
}

Svar #7

Metoden node.after (doc) setter inn en node etter en annen node.

For to DOM-noder node1 og node2,

node1.after(node2) setter inn node2 etter node1.

Denne metoden er ikke tilgjengelig i eldre nettlesere, så vanligvis trengs en polyfill.

Relaterte artikler