Есть 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
Element.prototype.appendBefore = function (element) {
element.parentNode.insertBefore(this, element);
},false;
.appendAfter (element) Прототип
Element.prototype.appendAfter = function (element) {
element.parentNode.insertBefore(this, element.nextSibling);
},false;
existingElement.appendAfter(newElement);
. Посмотрите, что я имею в виду в этом обновленном jsfiddle .
insertAdjacentHTML
+ outerHTML
elementBefore.insertAdjacentHTML('afterEnd', elementAfter.outerHTML)
расквитаться:
insertBefore
(безубыточность, если имя переменной существующего узла составляет 3 символа)Недостатки:
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. Тем не менее, этот polyfill находится в Документации MDN и использует своего рода инициализацию и выполнение, которые более безопасны. Кроме того, это для поддержки старых браузеров, в те времена, когда Prototype Overwriting была не так уж и плоха.
Как использовать решение 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
должно работать аналогично insertBefore . Код ниже будет выполнять следующее:
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
бы вставлять в конце дочерние элементы, этот должен вставлять в начале , так как в противном случае не было никакой возможности вставить в начальное местоположение с этой функцией вообще; та же самая причина 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);
}
if( !Element.prototype.insertAfter ) {
Element.prototype.insertAfter = function(item, reference) {
if( reference.nextSibling )
reference.parentNode.insertBefore(item, reference.nextSibling);
else
reference.parentNode.appendChild(item);
};
}
На самом деле вы можете вызвать метод 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>
Как и ожидалось, он перемещает элемент вверх после элемента вниз