在JavaScript中有insertBefore(),但如何在不使用jQuery或其他库的情况下在另一个元素之后插入一个元素?


当前回答

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

我想要一个与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
    );
  };
}

其他回答

输入随身的“强暴”

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

好处:

烘干机:你不需要将before节点存储在变量中并使用它两次。如果重命名变量,就少发生修改。 golfs比insertBefore更好(如果现有的节点变量名是3个字符长,则打破平衡)

缺点:

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

让我们来处理所有的情况

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

或者你可以简单地这样做:

referenceNode.parentNode.insertBefore( newNode, referenceNode )
referenceNode.parentNode.insertBefore( referenceNode, newNode )

这是使用普通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

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

我想要一个与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
    );
  };
}