How to insert an element after another element in JavaScript without using a library?
在JavaScript中有
1 | referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); |
其中
所以:
1 2 3 | function insertAfter(newNode, referenceNode) { referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); } |
在这里试试吧。
直截了当的JavaScript将是以下:
追加之前:
1 | element.parentNode.insertBefore(newElement, element); |
追加后:
1 | element.parentNode.insertBefore(newElement, element.nextSibling); |
但是,在那里折腾一些原型以便于使用
通过构建以下原型,您将能够直接从新创建的元素中调用这些函数。
-
newElement.appendBefore(element); -
newElement.appendAfter(element);
.appendBefore(element)原型
1 2 3 | Element.prototype.appendBefore = function (element) { element.parentNode.insertBefore(this, element); },false; |
.appendAfter(element)原型
1 2 3 | Element.prototype.appendAfter = function (element) { element.parentNode.insertBefore(this, element.nextSibling); },false; |
并且,要查看所有操作,请运行以下代码段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* 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')); |
1 2 3 4 5 6 7 8 9 | div { text-align: center; } #Neighborhood { color: brown; } #NewElement { color: green; } |
1 2 3 | Neighbor 1 Neighbor 2 Neighbor 3 |
在JSFiddle上运行它
1 | elementBefore.insertAdjacentHTML('afterEnd', elementAfter.outerHTML) |
上升空间:
- DRYer:您不必将before节点存储在变量中并使用它两次。如果重命名变量,则在较少的情况下进行修改。
-
高尔夫球比
insertBefore 更好(即使现有节点变量名称为3个字符长也会中断)
缺点:
- 更新浏览器支持:https://caniuse.com/#feat=insert-adjacent
-
将丢失元素的属性,例如事件,因为
outerHTML 将元素转换为字符串。我们需要它,因为insertAdjacentHTML 从字符串而不是元素添加内容。
快速Google搜索会显示此脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // 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); } } |
虽然
1 2 3 4 5 6 7 8 | <!-- refElem.insertAdjacentElement('beforebegin', moveMeElem); --> <p id="refElem"> <!-- refElem.insertAdjacentElement('afterbegin', moveMeElem); --> ... content ... <!-- refElem.insertAdjacentElement('beforeend', moveMeElem); --> </p> <!-- refElem.insertAdjacentElement('afterend', moveMeElem); --> |
其他考虑类似用例:
参考文献:
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
其中node1和node2是DOM节点。
旧浏览器[1]不支持
或者你可以简单地做:
1 2 | referenceNode.parentNode.insertBefore( newNode, referenceNode ) referenceNode.parentNode.insertBefore( referenceNode, newNode ) |
Step 1. Prepare Elements :
1 2 3 | var element = document.getElementById('ElementToAppendAfter'); var newElement = document.createElement('div'); var elementParent = element.parentNode; |
Step 2. Append after :
1 | elementParent.insertBefore(newElement, element.nextSibling); |
insertBefore()方法与
因此,为了模仿这个并创建方法
JavaScript的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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
1 2 3 4 | <p id="pOne">paragraph one </p> <p id="pTwo">paragraph two </p> |
请注意,如本文所述,扩展DOM可能不适合您。
Hovewer,这篇文章写于2010年,现在情况可能有所不同。所以决定你自己。
JavaScript DOM insertAfter()方法@ jsfiddle.net
理想情况下,
-
如果没有孩子,则附加新的
Node -
如果没有引用
Node ,则追加新的Node -
如果在引用
Node 之后没有Node ,则追加新的Node -
如果引用
Node 之后有一个兄弟,则在该兄弟之前插入新的Node -
返回新的
Node
扩展
1 2 3 4 5 6 7 | Node.prototype.insertAfter = function(node, referenceNode) { if (node) this.insertBefore(node, referenceNode && referenceNode.nextSibling); return node; }; |
一个常见的例子
1 | node.parentNode.insertAfter(newNode, node); |
查看正在运行的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | // 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); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <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> |
我知道这个问题已经有太多的答案,但它们都没有达到我的确切要求。
我想要一个与
由于null
结果函数如下所示:
1 2 3 4 5 6 | function insertAfter(parentNode, newNode, referenceNode) { parentNode.insertBefore( newNode, referenceNode ? referenceNode.nextSibling : parentNode.firstChild ); } |
或者(如果你必须,我不推荐它)你当然可以增强
1 2 3 4 5 6 7 8 | if (! Node.prototype.insertAfter) { Node.prototype.insertAfter = function(newNode, referenceNode) { this.insertBefore( newNode, referenceNode ? referenceNode.nextSibling : this.firstChild ); }; } |
您可以使用
参考:http://www.w3schools.com/jsref/met_node_appendchild.asp
insertAfter的强大实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | // 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'.")); |
};
此代码用于在最后一个现有子项之后插入链接项以内联小型css文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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); |
让我们处理所有场景
1 2 3 4 5 6 7 8 9 10 11 | 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); } |
1 2 3 4 5 6 7 8 | if( !Element.prototype.insertAfter ) { Element.prototype.insertAfter = function(item, reference) { if( reference.nextSibling ) reference.parentNode.insertBefore(item, reference.nextSibling); else reference.parentNode.appendChild(item); }; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <!DOCTYPE html> <html lang="ca"> <head> <meta charset="UTF-8"> Document function createDiv(){ var newDiv = document.createElement("div"); var txt = document.createTextNode("I'm the second div"); newDiv.appendChild(txt); var x = document.getElementsByTagName("BODY")[0]; x.insertBefore(newDiv, third); } </head> <body> <p> I'm the first div </p> <p> I'm the third div </p> <button type=" button" name=" button" onclick =" createDiv()"> Create the second Div </button> </body> </html> |