如何在不使用库的情况下在JavaScript中的另一个元素之后插入一个元素?

JavaScript中有insertBefore(),但我如何在不使用jQuery或其他库的情况下将元素之后插入另一个元素?

819497 次浏览
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>

快速谷歌搜索显示这个脚本

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

insertAdjacentHTML+outerHTML

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

缺点:

  • DRYer:您不必将前节点存储在变量中并使用两次。如果您重命名变量,修改的发生次数就会减少。
  • Golfs比insertBefore更好(即使现有节点变量名称长3个字符也会中断)

缺点:

  • 较低的浏览器支持,因为更新:https://caniuse.com/#feat=insert-adjacent
  • 将丢失元素的属性,例如事件,因为outerHTML将元素转换为字符串。我们需要它,因为insertAdjacentHTML从字符串而不是元素添加内容。

parentNode.insertBefore()类似地使用INTLEWER()方法。所以为了模仿这个并制作一个方法parentNode.insertAfter(),我们可以编写以下代码。

javascript

Node.prototype.insertAfter = function(newNode, referenceNode) {return referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); // based on karim79's solution};
// getting required handlesvar 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);

超文本标记语言

<div id="divOne"><p id="pOne">paragraph one</p><p id="pTwo">paragraph two</p></div>

请注意,扩展DOM可能不是这篇文章中所述的正确解决方案。

Hovewer,这篇文章写于2010年,现在情况可能不同了。所以你自己决定吧。

JavaScript DOM插入后()方法@jsfiddle.net

这段代码的工作是在最后一个现有子项之后插入一个链接项到内联一个小css文件

var raf, cb=function(){//create newnodevar link=document.createElement('link');link.rel='stylesheet';link.type='text/css';link.href='css/style.css';
//insert after the lastnodevar nodes=document.getElementsByTagName('link'); //existing nodesvar lastnode=document.getElementsByTagName('link')[nodes.length-1];lastnode.parentNode.insertBefore(link, lastnode.nextSibling);};
//check before inserttry {raf=requestAnimationFrame||mozRequestAnimationFrame||webkitRequestAnimationFrame||msRequestAnimationFrame;}catch(err){raf=false;}
if (raf)raf(cb); else window.addEventListener('load',cb);

或者你可以简单地做:

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

简单的JavaScript如下:

之前追加:

element.parentNode.insertBefore(newElement, element);

追加后:

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

但是为了方便使用,在那里扔一些原型

通过构建以下原型,您将能够直接从新创建的元素调用这些函数。

  • newElement.appendBefore(element);

  • newElement.appendAfter(element);

. append之前(元素)原型

Element.prototype.appendBefore = function (element) {element.parentNode.insertBefore(this, element);},false;

. appendAfter(元素)原型

Element.prototype.appendAfter = function (element) {element.parentNode.insertBefore(this, element.nextSibling);},false;

代码片段以查看所有操作:

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

在JSFiddle上运行它

方法node.afterdoc)在另一个节点之后插入一个节点。

对于两个DOM节点node1node2

node1.after(node2)node1之后插入node2

此方法在较旧的浏览器中不可用,因此通常需要一个Poly填充。

步骤一:准备要素:

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

步骤2.附加在:

elementParent.insertBefore(newElement, element.nextSibling);

您可以使用appendChild函数在元素后插入。

参考:http://www.w3schools.com/jsref/met_node_appendchild.asp

理想情况下,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);

查看正在运行的代码

// First extendNode.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>

插入后的健壮实现。

// source: https://github.com/jserz/domPlus/blob/master/src/insertAfter()/insertAfter.jsNode.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);elsereferenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);}

虽然//插入之前很棒,并且被这里的大多数答案引用。为了增加灵活性,并且更明确一点,你可以使用:

插入相邻元素()作为refElem.insertAdjacentElement(position, newElem)允许您引用任何元素,并将要移动的元素插入您想要的位置(位置可以是:'beforebegin''afterbegin''beforeend''afterend'之一),如下所示:

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

其他类似用例需要考虑的:insertAdjacentHTML()insertAdjacentText()

参考文献:

https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentElementhttps://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTMLhttps://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentText

if( !Element.prototype.insertAfter ) {Element.prototype.insertAfter = function(item, reference) {if( reference.nextSibling )reference.parentNode.insertBefore(item, reference.nextSibling);elsereference.parentNode.appendChild(item);};}

我知道这个问题已经有太多答案了,但没有一个符合我的确切要求。

我想要一个与#0行为完全相反的函数-也就是说,它必须接受一个nullreferenceNode接受的答案不接受),并且insertBefore将插入结束的子节点,这个子节点必须插入开始,因为否则就没有办法在开始位置插入这个函数;同样的原因insertBefore在末尾插入。

由于nullreferenceNode需要您找到父级,我们需要知道父级-insertBeforeparentNode的方法,因此它可以以这种方式访问父级;我们的函数没有,所以我们需要将父级作为参数传递。

结果函数看起来像这样:

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);};}

2022解决方案-元素

编辑:从2021年及以后,ChildNode已合并到Element。我正在改变这个答案。

新留档:https://developer.mozilla.org/en-US/docs/Web/API/Element

这与ChildNode完全相同。“之前”、“之后”和“删除”属性现在只是普通元素api的一部分。

// Parentconst el = document.body;// New Elementconst newEl = document.createElement("div");
// Insert Before Elementel.before(newEl);
// Insert After Element// Technically this would be invalid because// I already inserted newEl before el.// newEl changed location and is no longer a floating element.// You cant insert one element in two places at once.el.after(newEl);
// Another extra feature originally added with ChildNode is the .remove() method,// which deletes the element from the DOMel.remove();newEl.remove();

2019解决方案(已过时)

我不推荐使用这个解决方案,但为了“历史”,我会把它保留在这里

这是更安全的,然后使用一个polfill-type原型覆盖,这只是一个基本的功能。当然它不是很漂亮,但它的工作原理。

// Parentconst el = document.body;// New Elementconst newEl = document.createElement("div");
// Function You Needfunction insertAfter(el0, el1) {el0.parentNode.insertBefore(el1, el0.nextSibling);}
// Insert Before Elementel.insertBefore(newEl);
// Insert After ElementinsertAfter(el, newEl);
// Just remember you cant use insertAfter() or .insertBefore()// on newEl more than once.// You cant insert one element in two places at once.

原始解决方案(不良做法)

我不推荐使用这个解决方案,这是我最初发布这个答案时使用的解决方案。为了“历史”的缘故,我会把它保留在这里

这只是一个不存在的.插入后函数的多边形填充。这个原型直接将函数HTMLElement.insertAfter(element);添加到HTMLElement原型中:

// Parentconst el = document.body;// New Elementconst newEl = document.createElement("div");
// Custom MethodElement.prototype.insertAfter = function(new) {this.parentNode.insertBefore(new, this.nextSibling);}
// Insert Before Elementel.insertBefore(newEl)
// Insert After Elementel.insertAfter(newEl);
// Just remember you cant use .insertAfter() or .insertBefore()// on newEl more than once.// You cant insert one element in two places at once.

实际上,你可以在Chrome、Firefox和Opera的新版本中使用after()方法。这种方法的缺点是Internet Explorer还不支持它。

示例:

// You could create a simple nodevar node = document.createElement('p')
// And then get the node where you want to append the created node aftervar existingNode = document.getElementById('id_of_the_element')
// Finally you can append the created node to the exisitingNodeexistingNode.after(node)

一个简单的超文本标记语言代码来测试:

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

正如预期的那样,它将向上元素移动到向下元素之后

这是我们可以使用vanilla javascript添加一个又一个元素的最简单方法

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

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

我使用以下内容在选择末尾插入选项。通过仅传递null作为第二个参数。我不确定这是否是“选择”元素的异常,因为我从未在其他任何东西上尝试过,但如果有人来这里寻找这个可能会有所帮助。在IE上也有效(令人惊讶)。:)

            var x = document.getElementById("SELECT_LIST");var boption = document.createElement("option");boption.text = "SOME TEXT";boption.value = "SOME VALUE";x.insertBefore(boption, null);