还有insertBefore()
在JavaScript,但我怎么能插入一个元素后,另一种元素,而不使用jQuery或其他库?
还有insertBefore()
在JavaScript,但我怎么能插入一个元素后,另一种元素,而不使用jQuery或其他库?
Answers:
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
referenceNode
您要放置的节点在哪里newNode
。If 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)原型
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/zh-CN/docs/Web/API/Element/insertAdjacentElement https://developer.mozilla.org/zh-CN/docs/Web/API/Element/insertAdjacentHTML https:// developer.mozilla.org/zh-CN/docs/Web/API/Element/insertAdjacentText
方法node.after
(doc)在另一个节点之后插入一个节点。
对于两个DOM节点node1
和node2
,
node1.after(node2)
node2
在之后插入node1
。
此方法在较旧的浏览器中不可用,因此通常需要一个polyfill。
我知道这个问题很古老,但是对于任何将来的用户来说,这是一个经过修改的原型,这只是.insertAfter函数的微型填充,该函数不存在,该原型直接baseElement.insertAfter(element);
向Element原型添加了一个新功能:
Element.prototype.insertAfter = function(new) {
this.parentNode.insertBefore(new, this.nextSibling);
}
将polyfill放在库,要旨中或仅在代码中(或其他可以引用它的地方)后,只需编写 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的Web标准:https : //developer.mozilla.org/en-US/docs/Web/API/ChildNode
目前在生活标准中,并且是SAFE。
对于不受支持的浏览器,请使用以下Polyfill:https : //github.com/seznam/JAK/blob/master/lib/polyfills/childNode.js
有人提到,Polyfill使用Protos,这是我的不当做法。它们是特别是在不正确使用它们的情况下,例如我在2018年提出的解决方案。但是,该polyfill在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
步骤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可能不适合你的解决方案中所述这篇文章。
Hovewer,这篇文章写于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
-也就是说,它必须接受null referenceNode
(接受的答案不接受),并且insertBefore
必须在子项的末尾插入,该子项必须在开始处插入,否则会出现这种情况。 d根本无法使用此功能插入起始位置;insertBefore
在末尾插入相同的原因。
由于null referenceNode
需要您定位父对象,因此我们需要知道父对象- insertBefore
是的方法parentNode
,因此它可以通过这种方式访问父对象;我们的函数没有,所以我们需要将parent作为参数传递。
结果函数如下所示:
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>
不出所料,它将up元素移到down元素之后