问答中心分类: JAVASCRIPT如何在不使用库的情况下在 JavaScript 中的另一个元素之后插入一个元素?
0
匿名用户 提问 42分钟 前

insertBefore()在 JavaScript 中,但是如何插入元素不使用 jQuery 或其他库的另一个元素?

user1637281 回复 42分钟 前

如果您需要最后一个子节点的特定情况 –stackoverflow.com/questions/5173545/…

user1637281 回复 42分钟 前

@AlanLarimer 太好了。谢谢。你知道 insertAdjacentElement 是什么时候引入的吗?

user1637281 回复 42分钟 前

根据 MDN,IE8 和 Firefox 48(2016 年 8 月 8 日)支持它。追踪:bugzilla.mozilla.org/show_bug.cgi?id=811259–>w3.org/Bugs/Public/show_bug.cgi?id=19962(2016 年 3 月 14 日)

18 Answers
0
Armando 回答 42分钟 前

简单的 JavaScript 如下:
之前附加:

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;

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

/* 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 上运行它

stomtech 回复 42分钟 前

扩大函数名称具有误导性。它认为它应该被称为 appendMeBefore 和 appendMeAfter。我以为它被用作appendChild() 方法,例如existingElement.appendAfter(newElement);.看看我在这个更新的意思jsfiddle.

Stefan Steiger 回复 42分钟 前

Append After 有效,因为如果 element.nextSibling 没有下一个兄弟,nextSibling 为 NULL,然后它会在末尾追加。

caston 回复 42分钟 前

我在 jslint 中收到警告:预期的 ‘;’而是看到’,’。 }, 错误的;

0
Modular 回答 42分钟 前

尽管插入前()很棒,这里的大多数答案都引用了它。为了增加灵活性,并且更明确一点,您可以使用:
插入相邻元素()作为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/insertAdjacentElement
https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML
https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentText

serraosays 回复 42分钟 前

真的应该给这个答案一些爱,这是快速接近 2020 年代的现代方法。

Qwerty 回复 42分钟 前

这个答案怎么埋得这么深?我将奖励它一些分数以引起更多关注。

Lajos Mészáros 回复 42分钟 前

一点旁注,它不适用于文档片段。

user924 回复 42分钟 前

beforebegin它是什么? ID?姓名?你应该更具体…

0
Ciro Santilli OurBigBook.com 回答 42分钟 前

insertAdjacentHTML+outerHTML

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

优点:

  • DRYer:您不必将前节点存储在变量中并使用它两次。如果您重命名变量,则修改次数较少。
  • 高尔夫比insertBefore(即使现有的节点变量名是 3 个字符长也能中断)

缺点:

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

如果您已经构建了元素,则可以使用.insertAdjacentElement()

madannes 回复 42分钟 前

截至 2018 年,浏览器支持看起来相当稳固:caniuse.com/#feat=插入相邻

Mehregan Rahmani 回复 42分钟 前

这是一个很好的解决方案,我建议每个人都阅读这个xahlee.info/js/js_insert_after.html

0
Mister SirCode 回答 42分钟 前

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 函数的 polyfill。这个原型直接添加了功能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.
izogfif 回复 42分钟 前

关于“2020解决方案”:beforeafter在 MDN 页面上都标记为“实验性”:Experimental. Expect behavior to change in the future.

Mister SirCode 回复 42分钟 前

@izogfif 好吧,考虑到它刚刚进入生活水平,这是意料之中的。我非常怀疑他们会显着改变该方法的行为以适应新标准。如果他们这样做,我将编辑答案。 MDN 文档上的唯一原因很可能是因为它最近被添加到生活标准中,所以它仍然是“实验性的”,即使它稳定并且在当前版本中

Mircea 回复 42分钟 前

它运行良好。完全支持除 IE。

Mister SirCode 回复 42分钟 前

@Mircea 如果您希望它在 IE 上运行,请使用我的回答中建议的 polyfill。 (虽然老实说,我怀疑有人真的关心 IE 了,我个人不再支持它了)

Optimae 回复 42分钟 前

beforeafter在 MDN 页面上不再标记为“实验性”:developer.mozilla.org/en-US/docs/Web/API/Element/before developer.mozilla.org/en-US/docs/Web/API/Element/after

0
James Long 回答 42分钟 前

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

// 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);
    }
}
James Long 回复 42分钟 前

对于偶然发现此脚本的任何人,我不建议使用它。它试图解决@karim79 的本机解决方案已经解决的问题。他的脚本更快、更高效——我强烈建议使用该脚本而不是这个脚本。

dvdchr 回复 42分钟 前

为什么?这只是几行,添加了最后一个子边缘情况处理的条件。其他一切都完全一样。

James Long 回复 42分钟 前

作为 JavaScript 中的一般经验法则,浏览器可以比您编写的任何内容更快地完成任务。虽然这两种解决方案在功能上是相同的,但我的 JavaScript 解决方案需要先被浏览器读取并理解才能使用,并且每次执行时都需要额外检查。 karim79 提供的解决方案将在内部完成所有这些工作,从而节省这些步骤。差异充其量是微不足道的,但他的解决方案是更好的解决方案。

1j01 回复 42分钟 前

换句话说,它试图解决一个不存在的问题。额外检查本身并没有错,但我认为它并没有传播对这些方法的最佳理解

James Long 回复 42分钟 前

差不多。我将脚本留在这里是因为这是我以前写的那种东西,但公认的答案更好,显示对方法的更好理解并且速度更快。没有理由改用这个答案 – 我什至不确定为什么它仍然会得到支持

Rolf 回复 42分钟 前

如果 targetElement 是其兄弟元素中的最后一个元素,则targetElement.nextSibling将返回null.什么时候node.insertBefore被称为null作为第二个参数,它将在集合的末尾添加节点。换句话说if(parent.lastchild == targetElement) {分支是多余的,因为parent.insertBefore(newElement, targetElement.nextSibling);将正确处理所有情况,即使起初可能看起来不是这样。许多人已经在其他评论中指出了这一点。

James Long 回复 42分钟 前

@Rolf – 是的,这就是为什么我不建议使用这个脚本并说最好使用接受的答案