在JavaScript中有insertBefore(),但如何在不使用jQuery或其他库的情况下在另一个元素之后插入一个元素?
当前回答
2022解决方案-元素
编辑:从2021年起,ChildNode已被合并到Element中。我把这个答案改成这样。
新文档:https://developer.mozilla.org/en-US/docs/Web/API/Element
这与ChildNode完全相同。“before”,“after”和“remove”属性现在只是普通元素api的一部分。
// Parent
const el = document.body;
// New Element
const newEl = document.createElement("div");
// Insert Before Element
el.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 DOM
el.remove();
newEl.remove();
2019年解决方案(过时)
我不推荐使用这个解决方案,但为了“历史”起见,我会把它保留在这里。
这比使用polyfill类型的原型重写更安全,它只是一个基本的功能。当然它不是很漂亮,但它是有效的。
// Parent
const el = document.body;
// New Element
const newEl = document.createElement("div");
// Function You Need
function insertAfter(el0, el1) {
el0.parentNode.insertBefore(el1, el0.nextSibling);
}
// Insert Before Element
el.insertBefore(newEl);
// Insert After Element
insertAfter(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.
原始解决方案(不良做法)
我不建议使用这个解决方案,这是我最初在发布这个答案时使用的解决方案。为了“历史”,我把它留在这里
这只是一个不存在的. insertafter函数的填充。这个原型直接添加了函数HTMLElement.insertAfter(element);到HTMLElement原型:
// Parent
const el = document.body;
// New Element
const newEl = document.createElement("div");
// Custom Method
Element.prototype.insertAfter = function(new) {
this.parentNode.insertBefore(new, this.nextSibling);
}
// Insert Before Element
el.insertBefore(newEl)
// Insert After Element
el.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.
其他回答
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年,现在的情况可能有所不同。所以你自己决定吧。
多面体JavaScript()方法
这段代码是为了在最后一个现有的子文件之后插入一个链接项,以内联一个小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);
理想情况下,insertAfter应该类似于insertBefore。下面的代码将执行以下操作:
如果没有子节点,则追加新的Node 如果没有引用节点,则追加新节点 如果引用节点后没有节点,则追加新节点 如果引用节点后面有一个兄弟节点,那么新节点将被插入到那个兄弟节点之前 返回新节点
扩展节点
Node.prototype.insertAfter = function(node, referenceNode) {
if (node)
this.insertBefore(node, referenceNode && referenceNode.nextSibling);
return node;
};
一个常见的例子
node.parentNode.insertAfter(newNode, node);
查看代码的运行情况
// 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); <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>
这是使用普通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
输入随身的“强暴”
elementBefore.insertAdjacentHTML('afterEnd', elementAfter.outerHTML)
好处:
烘干机:你不需要将before节点存储在变量中并使用它两次。如果重命名变量,就少发生修改。 golfs比insertBefore更好(如果现有的节点变量名是3个字符长,则打破平衡)
缺点:
较低的浏览器支持,因为更新:https://caniuse.com/#feat=insert-adjacent 将丢失元素的属性,例如事件,因为outerHTML将元素转换为字符串。我们需要它是因为insertAdjacentHTML从字符串而不是元素中添加内容。
推荐文章
- 在React Native中使用Fetch授权头
- 为什么我的球(物体)没有缩小/消失?
- 如何使用jQuery检测页面的滚动位置
- if(key in object)或者if(object. hasownproperty (key)
- 一元加/数字(x)和parseFloat(x)之间的区别是什么?
- angularjs中的compile函数和link函数有什么区别
- 删除绑定中添加的事件监听器
- 很好的初学者教程socket.io?
- HtmlSpecialChars在JavaScript中等价于什么?
- React: 'Redirect'没有从' React -router-dom'中导出
- 如何在React中使用钩子强制组件重新渲染?
- 我如何使用Jest模拟JavaScript的“窗口”对象?
- 我如何等待一个承诺完成之前返回一个函数的变量?
- 在JavaScript中根据键值查找和删除数组中的对象
- 使嵌套JavaScript对象平放/不平放的最快方法