Є 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>
Як очікувалося, він переміщує вгору елемент після елемента вниз