在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.

其他回答

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

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

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()方法

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

我想要一个与parentNode行为完全相反的函数。insertBefore -也就是说,它必须接受一个空的referenceNode(接受的答案不接受),而insertBefore将插入在子节点的末尾,这个必须插入在开始,因为否则根本没有办法用这个函数插入到开始位置;同样的原因insertBefore插入在末尾。

因为null referenceNode需要你定位父节点,我们需要知道父节点——insertBefore是parentNode的一个方法,所以它可以通过这种方式访问父节点;我们的函数没有,所以我们需要将父参数作为参数传递。

得到的函数如下所示:

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
    );
  };
}
if( !Element.prototype.insertAfter ) {
    Element.prototype.insertAfter = function(item, reference) {
        if( reference.nextSibling )
            reference.parentNode.insertBefore(item, reference.nextSibling);
        else
            reference.parentNode.appendChild(item);
    };
}

我使用以下命令在选择的末尾插入选项。通过传递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);