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?
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>
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
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.
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);
}
}
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
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.
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();
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 )
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);
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.
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
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
, NoweNode
jest dołączane - jeśli nie ma
Node
po referencjiNode
, dopisuje się noweNode
- jeśli tam odniesienie
Node
ma rodzeństwo po, to noweNode
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>
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
);
};
}
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ół
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);
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
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);
}
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);
};
}
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'."));
};
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