Є insertBefore()
в JavaScript, але як я можу вставити елемент за іншим елементом без використання jQuery чи іншої бібліотеки?
Є insertBefore()
в JavaScript, але як я можу вставити елемент за іншим елементом без використання jQuery чи іншої бібліотеки?
Відповіді:
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
Де referenceNode
знаходиться вузол, який ви хочете поставити newNode
. Якщо referenceNode
останній дочірній елемент в його батьківському елементі, це добре, тому що referenceNode.nextSibling
буде null
і insertBefore
обробляє цей випадок, додаючи до кінця списку.
Тому:
function insertAfter(newNode, referenceNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
Ви можете перевірити його за допомогою наступного фрагмента:
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()
працює з текстовими вузлами. Чому ти хочеш insertAfter()
бути іншим? Вам слід створити окрему пару функцій, названих insertBeforeElement()
і insertAfterElement()
для цього.
Додати до:
element.parentNode.insertBefore(newElement, element);
Додавати після:
element.parentNode.insertBefore(newElement, element.nextSibling);
Побудувавши такі прототипи, ви зможете викликати ці функції безпосередньо з новостворених елементів.
newElement.appendBefore(element);
newElement.appendAfter(element);
.appendBefore (елемент) Прототип
Element.prototype.appendBefore = function (element) {
element.parentNode.insertBefore(this, element);
},false;
.appendAfter (елемент) Прототип
Element.prototype.appendAfter = function (element) {
element.parentNode.insertBefore(this, element.nextSibling);
},false;
existingElement.appendAfter(newElement);
. Подивіться, що я маю на увазі в цій оновленій jsfiddle .
insertAdjacentHTML
+ outerHTML
elementBefore.insertAdjacentHTML('afterEnd', elementAfter.outerHTML)
Вгору:
insertBefore
(перерва, навіть якщо назва існуючої змінної вузла три символи)Недоліки:
outerHTML
перетворює елемент у рядок. Він потрібен тому, що insertAdjacentHTML
додає вміст із рядків, а не елементів..insertAdjacentElement()
Швидкий пошук Google виявляє цей сценарій
// 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
повернеться null
. Коли node.insertBefore
буде викликано, null
як це другий аргумент, то він додасть вузол в кінці колекції. Іншими словами, if(parent.lastchild == targetElement) {
галузь зайва, тому що parent.insertBefore(newElement, targetElement.nextSibling);
буде справлятися належним чином у всіх випадках, навіть якщо спочатку це може з’явитися інакше. Багато хто вже вказував на це в інших коментарях.
Хоча insertBefore()
(див. MDN ) чудово і на нього посилається більшість відповідей тут. Для додаткової гнучкості та для більш явного вибору ви можете використовувати:
insertAdjacentElement()
(див. MDN ) Це дозволяє вам посилатися на будь-який елемент і вставляти елемент, що переміщується, саме там, де ви хочете:
<!-- refElem.insertAdjacentElement('beforebegin', moveMeElem); -->
<p id="refElem">
<!-- refElem.insertAdjacentElement('afterbegin', moveMeElem); -->
... content ...
<!-- refElem.insertAdjacentElement('beforeend', moveMeElem); -->
</p>
<!-- refElem.insertAdjacentElement('afterend', moveMeElem); -->
Інші, що розглядаються для подібних випадків використання: insertAdjacentHTML()
таinsertAdjacentText()
Список літератури:
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
Метод node.after
( doc ) вставляє вузол за іншим вузлом.
Для двох вузлів DOM node1
і node2
,
node1.after(node2)
вставки node2
після node1
.
Цей спосіб недоступний у старих веб-переглядачах, тому зазвичай потрібен поліфайл.
Я знаю, що це питання є стародавнім, але для будь-яких майбутніх користувачів є модифікований прототип, це лише мікрополіфа для функції .insertAfter, яка не існує цього прототипу, безпосередньо додає нову функцію baseElement.insertAfter(element);
до прототипу Element:
Element.prototype.insertAfter = function(new) {
this.parentNode.insertBefore(new, this.nextSibling);
}
Після того як ви розмістили поліфайл у бібліотеці, суті або просто у своєму коді (або в будь-якому іншому місці, де на нього можна посилатися) Просто напишіть document.getElementById('foo').insertAfter(document.createElement('bar'));
Нова редакція: НЕ ВИКОРИСТОВУєте ПРОТОТИПИ. Вони перезаписують базові коди за замовчуванням і не є дуже ефективними або безпечними і можуть спричинити помилки сумісності, але якщо це не для комерційних проектів, це не повинно мати значення. якщо ви хочете отримати безпечну функцію для комерційного використання, просто використовуйте функцію за замовчуванням. це не дуже, але це працює:
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
Поточні веб-стандарти для ChildNode: https://developer.mozilla.org/en-US/docs/Web/API/ChildNode
Наразі воно є життєвим рівнем і БЕЗКОШТОВНО.
Для непідтримуваних браузерів використовуйте цей Polyfill: https://github.com/seznam/JAK/blob/master/lib/polyfills/childNode.js
Хтось згадав, що Polyfill використовує Protos, коли я сказав, що це погана практика. Вони є, особливо при неправильному використанні, як моє рішення на 2018 рік. Однак поліфіл є в документації MDN і використовує безпечніший вид ініціалізації та виконання. Плюс - це для підтримки старих браузерів, у той день і вік, коли прототипи прототипу були не такими поганими.
Як використовувати рішення 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
Або ви можете просто зробити:
referenceNode.parentNode.insertBefore( newNode, referenceNode )
referenceNode.parentNode.insertBefore( referenceNode, newNode )
Крок 1. Підготуйте елементи:
var element = document.getElementById('ElementToAppendAfter');
var newElement = document.createElement('div');
var elementParent = element.parentNode;
Крок 2. Додайте після:
elementParent.insertBefore(newElement, element.nextSibling);
Метод insertBefore () використовується як parentNode.insertBefore()
. Отже, щоб наслідувати це та зробити метод, parentNode.insertAfter()
ми можемо написати наступний код.
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>
Зауважте, що розширення DOM може бути не правильним рішенням для Вас, як зазначено в цій статті .
Говевер, ця стаття була написана в 2010 році і зараз може бути інакше. Тож вирішуйте самостійно.
В ідеалі insertAfter
має працювати аналогічно вставці перед . У наведеному нижче коді буде виконано наступне:
Node
додається новеNode
, Node
додається новеNode
після посилання немає Node
, нове Node
додаєтьсяNode
має побратима після, то Node
перед цим братом вставляється новийNode
Розширення Node
Node.prototype.insertAfter = function(node, referenceNode) {
if (node)
this.insertBefore(node, referenceNode && referenceNode.nextSibling);
return node;
};
Один поширений приклад
node.parentNode.insertAfter(newNode, node);
Дивіться код, що працює
Я знаю, що на це питання вже надто багато відповідей, але жоден з них не відповідав моїм точним вимогам.
Я хотів, щоб функція мала протилежну поведінкуparentNode.insertBefore
- тобто вона повинна приймати нуль referenceNode
(на що не приймається відповідь ), і де вона insertBefore
буде вставлена в кінці дітей, яку потрібно вставити на початку , оскільки в іншому випадку є ' d взагалі не має можливості вставляти в початкове місце цю функцію; з тієї ж причини insertBefore
вставляється в кінці.
Оскільки нуль referenceNode
вимагає, щоб ви знайшли батьків, нам потрібно знати, що батьків - insertBefore
це метод parentNode
, тому він має доступ до батьків таким чином; наша функція не відповідає, тому нам потрібно передати батьківський параметр як параметр.
Отримана функція виглядає приблизно так:
function insertAfter(parentNode, newNode, referenceNode) {
parentNode.insertBefore(
newNode,
referenceNode ? referenceNode.nextSibling : parentNode.firstChild
);
}
Або (якщо потрібно, я не рекомендую), звичайно, ви можете покращити Node
прототип:
if (! Node.prototype.insertAfter) {
Node.prototype.insertAfter = function(newNode, referenceNode) {
this.insertBefore(
newNode,
referenceNode ? referenceNode.nextSibling : this.firstChild
);
};
}
Цей код працює над тим, щоб вставити елемент посилання відразу після останнього існуючого дочірнього списку до вбудованого невеликого файлу 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);
Ви можете використовувати appendChild
функцію для вставки після елемента.
Довідка: http://www.w3schools.com/jsref/met_node_appendchild.asp
надійна реалізація 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'."));
};
Дозволяє обробляти всі сценарії
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);
}
Ви можете насправді називатися методом after()
у новішій версії Chrome, Firefox та Opera. Мінусом цього методу є те, що Internet Explorer ще не підтримує його.
Приклад:
// 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)
Простий HTML-код для перевірки:
<!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>
Як очікувалося, він переміщує вгору елемент після елемента вниз