Jak wstawić element po innym elemencie w JavaScript bez użycia biblioteki?

Jest insertBefore()w JavaScript, ale jak mogę wstawić element po inny element bez użycia jQuery lub innej biblioteki?

Author: Edwin Pratt, 2011-01-25

19 answers

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

Gdzie referenceNode jest węzłem, który chcesz umieścić newNode po. Jeśli referenceNode jest ostatnim dzieckiem w elemencie nadrzędnym, to w porządku, ponieważ {[7] } będzie null i insertBefore obsługuje tę sprawę, dodając do końca listy.

Więc:

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

Możesz przetestować go za pomocą następującego fragmentu:

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>
 1395
Author: karim79,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-25 21:28:20

Prosty JavaScript będzie następujący:

Dołącz Przed:

element.parentNode.insertBefore(newElement, element);

Dołącz Po:

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

Ale wrzuć tam kilka prototypów dla łatwości użycia

Budując następujące prototypy, będziesz mógł wywoływać te funkcje bezpośrednio z nowo utworzonych elementów.

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

Aby zobaczyć to wszystko w akcji, Uruchom poniższy fragment kodu

/* 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>

Uruchom go na JSFiddle

 133
Author: Armando,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-21 08:48:32

insertAdjacentHTML + outerHTML

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

Upsy:

  • DRYer: nie musisz przechowywać węzła before w zmiennej i używać go dwa razy. Jeśli zmienisz nazwę zmiennej, w przypadku wystąpienia mniej Modyfikuj.
  • golfs lepszy niż insertBefore (break even if the existing node variable name is 3 chars long)

Wady:

  • niższe wsparcie dla przeglądarek od nowszych: https://caniuse.com/#feat=insert-adjacent
  • straci właściwości element taki jak events, ponieważ outerHTML konwertuje element na łańcuch znaków. Potrzebujemy go, ponieważ insertAdjacentHTML dodaje zawartość z łańcuchów, a nie elementów.
 53
Author: Ciro Santilli TRUMP BAN IS BAD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-30 15:33:10

Szybkie wyszukiwanie w Google ujawnia Ten skrypt

// 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);
    }
}
 38
Author: James Long,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-12 16:39:52

Chociaż insertBefore() (patrz MDN) jest świetny i odnosi się do większości odpowiedzi tutaj. Aby zwiększyć elastyczność i być nieco bardziej wyraźnym, możesz użyć:

insertAdjacentElement() (Zobacz MDN ) pozwala to odwołać się do dowolnego elementu i wstawić element, który ma zostać przeniesiony dokładnie tam, gdzie chcesz:

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

Inne do rozważenia dla podobnych przypadków użycia: insertAdjacentHTML() i insertAdjacentText()

Bibliografia:

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

 38
Author: bit-less,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-05 05:40:33

Metoda node.after (doc ) wstawia węzeł za innym węzłem.

Dla dwóch węzłów DOM node1 i node2,

node1.after(node2) wstawia node2 po node1.

Ta metoda nie jest dostępna w starszych przeglądarkach, więc zwykle potrzebny jest polyfill.

 19
Author: golopot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-08 12:08:46

Rozwiązanie 2018 (zła praktyka, przejdź do 2020) Wiem, że to pytanie jest starożytne, ale dla przyszłych użytkowników, heres zmodyfikowany prototyp to tylko mikro polyfill dla .funkcja insertAfter, która nie istnieje ten prototyp bezpośrednio dodaje nową funkcję baseElement.insertAfter(element); do prototypu elementu:

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

Po umieszczeniu polyfill w bibliotece, gist lub po prostu w kodzie (lub gdziekolwiek indziej, gdzie można go odwołać) Wystarczy napisać document.getElementById('foo').insertAfter(document.createElement('bar'));


2019 rozwiązanie (brzydki, przejdź do 2020)

Nie należy używać prototypów. Nadpisują domyślną bazę kodową i nie są bardzo wydajne lub bezpieczne i mogą powodować błędy zgodności, ale jeśli jej dla projektów niekomercyjnych, nie powinno to mieć znaczenia. jeśli chcesz mieć bezpieczną funkcję do użytku komercyjnego, po prostu użyj funkcji domyślnej. nie jest ładny, ale działa:

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 

Rozwiązanie 2020

Aktualne standardy sieciowe dla ChildNode: https://developer.mozilla.org/en-US/docs/Web/API/ChildNode

Jest obecnie w standardzie życia i jest bezpieczny.

Dla nieobsługiwanych przeglądarek, użyj tego Polyfill: https://github.com/seznam/JAK/blob/master/lib/polyfills/childNode.js

Ktoś wspomniał, że Polyfill używa Proto, kiedy powiedziałem, że to zła praktyka. Są, zwłaszcza gdy są używane na ślepo i nadpisywane, jak w przypadku mojego rozwiązania 2018. jednak, że polyfill jest na dokumentacja MDN i wykorzystuje rodzaj inicjalizacji i wykonywania, które jest bezpieczniejsze.

Jak korzystać z rozwiązania 2020:
// Parent Element
const el = document.querySelector(".class");

// Create New Element
const newEl = document.createElement("div");
newEl.id = "foo";

// Insert New Element BEFORE an Element
el.before(newEl);

// Insert New Element AFTER an Element
el.after(newEl);

// Remove an Element
el.remove();

// Even though it’s a created element,
// newEl is still a reference to the HTML,
// so using .remove() on it should work
// if you have already appended it somewhere
newEl.remove();
 19
Author: Mister SirCode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-01 02:51:52

Lub możesz po prostu zrobić:

referenceNode.parentNode.insertBefore( newNode, referenceNode )
referenceNode.parentNode.insertBefore( referenceNode, newNode )
 5
Author: olvlvl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-02 19:40:01

Punkt 1. Przygotowanie Elementów:

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

Punkt 2. Dołącz po :

elementParent.insertBefore(newElement, element.nextSibling);
 5
Author: Malik Khalil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-03 20:14:37

Metoda InsertBefore () jest używana tak jak parentNode.insertBefore(). Aby to naśladować i stworzyć metodę parentNode.insertAfter() możemy napisać następujący kod.

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>

Zauważ, że rozszerzenie DOM może nie być właściwym rozwiązaniem dla ciebie, jak wspomniano w w tym artykule .

Hovewer, ten artykuł został napisany w 2010 roku i teraz może być inaczej. Więc zdecyduj sam.

Metoda JavaScript DOM insertAfter () @ jsfiddle.net

 3
Author: Dmytro Dzyubak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-07 10:06:56

Jest to najprostszy sposób, w jaki możemy dodać element po innym za pomocą vanilla javascript

var d1 = document.getElementById('one');
d1.insertAdjacentHTML('afterend', '<div id="two">two</div>');

Odniesienie: https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML

 3
Author: Payel Dutta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-12 20:00:16

Najlepiej insertAfter powinno działać podobnie do insertBefore. Poniższy kod wykona następujące czynności:

  • jeśli nie ma dzieci, Nowy Node jest dołączany
  • jeśli nie ma odniesienia Node, Nowe Node jest dołączane
  • jeśli nie ma Node po referencji Node, dopisuje się nowe Node
  • jeśli tam odniesienie Node ma rodzeństwo po, to nowe Node jest wstawiane przed tym rodzeństwem
  • zwraca nowy Node

Rozszerzanie Node

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

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

    return node;
};

Jeden wspólny przykład

node.parentNode.insertAfter(newNode, node);

Zobacz kod uruchamiający

// 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>
 2
Author: Darlesson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-16 19:42:55

Wiem, że to pytanie ma już zbyt wiele odpowiedzi, ale żadna z nich nie spełniła moich dokładnych wymagań.

Chciałem funkcji, która ma dokładnie odwrotne zachowanie parentNode.insertBefore - oznacza to, że musi ona zaakceptować null referenceNode (którego zaakceptowana odpowiedź nie ma) i gdzie insertBefore wstawia się na koniec dzieci, które musi wstawić na początek , ponieważ w przeciwnym razie nie byłoby możliwości wstawienia w miejscu startu z tą funkcją w ogóle; z tego samego powodu insertBefore wstawia się na końcu.

Ponieważ null referenceNode wymaga zlokalizowania rodzica, musimy wiedzieć, że rodzic - insertBefore jest metodą parentNode, więc ma dostęp do rodzica w ten sposób; nasza funkcja nie ma, więc będziemy musieli przekazać rodzica jako parametr.

Funkcja wynikowa wygląda następująco:

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

Lub (jeśli musisz, nie polecam) możesz oczywiście ulepszyć Node prototyp:

if (! Node.prototype.insertAfter) {
  Node.prototype.insertAfter = function(newNode, referenceNode) {
    this.insertBefore(
      newNode,
      referenceNode ? referenceNode.nextSibling : this.firstChild
    );
  };
}
 2
Author: mindplay.dk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-20 07:17:39

W nowszych wersjach Chrome, Firefox i opery można użyć metody o nazwie after(). Minusem tej metody jest to, że Internet Explorer nie obsługuje go jeszcze.

Przykład:

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

Prosty kod HTML do przetestowania, który jest:

<!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>

Zgodnie z oczekiwaniami przesuwa element w górę po elemencie w dół

 2
Author: Anime no Sekai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-26 17:31:12

Ten kod polega na wstawieniu elementu linku zaraz po ostatnim istniejącym potomku do inlining małego pliku 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
Author: Chetabahana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-09 07:27:04

Możesz użyć funkcji appendChild do wstawiania po elemencie.

Odniesienie: http://www.w3schools.com/jsref/met_node_appendchild.asp

 0
Author: Doug LN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-14 12:14:29

Pozwala obsłużyć wszystkie scenariusze

 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
Author: Sami,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-11 10:13:48
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
Author: yavuzkavus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-13 14:06:23

Solidna implementacja 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
Author: jszhou,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-18 15:50:48