ライブラリを使用せずにJavaScriptで別の要素の後に要素を挿入する方法は?


757

ありますinsertBefore()JavaScriptで、どのように私は、要素を挿入することができた後、 jQueryのまたは別のライブラリを使用せずに別の要素?


4
-あなたは非常に最後の子ノードの特定のケースが必要な場合stackoverflow.com/questions/5173545/...


2
@AlanLarimerいいね。ありがとう。insertAdjacentElementがいつ導入されたか知っていますか?
Xah Lee 2017

1
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日)
Alan Larimer

回答:


1276
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);

referenceNode置したいノードはどこですかnewNodereferenceNodeがその親要素内の最後の子である場合は問題ありreferenceNode.nextSiblingません。なぜなら、はリストの最後に追加することによってそのケースnullinsertBefore処理し、処理するからです。

そう:

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>


8
すばらしい答えをありがとう、しかし引数リストでreferenceNodeとnewNodeを入れ替えるのは混乱しませんか?insertBefore構文に準拠しないのはなぜですか?
GijsjanB 2013年

9
referenceNodeがappendChildを追加する必要がある最後の子である場合、このコードスニペットは処理しません。
Brad Vogel

72
MDNによれば、要素が最後の場合(したがってnextSiblingがnullの場合)、newNodeは期待どおりに追加されます
electroCutie

9
referenceNode.nextElementSiblingを使用することをお
勧め

8
@BhumiSinghal:不正解です。insertBefore()テキストノードで動作します。なぜあなたはinsertAfter()違う人になりたいのですか?名前付き関数の別のペアを作成する必要がありinsertBeforeElement()かつinsertAfterElement()そのために。
7vujy0f0hy 2017年

116

簡単な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;

そして、すべての動作を確認するには、次のコードスニペットを実行します

JSFiddleで実行します


4
拡張機能名が誤解されています。それはむしろappendMeBeforeとappendMeAfterと呼ばれるべきだと思います。私はそれのように使用したと思ったのappendChild()メソッドなど、existingElement.appendAfter(newElement);。この更新されたjsfiddleで私が何を意味するかを参照してください。
stomtech 2017年

2
Append Afterは機能します。これは、element.nextSiblingに次の兄弟がない場合、nextSiblingがNULLであり、最後に追加されるためです。
Stefan Steiger

45

insertAdjacentHTML + outerHTML

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

利点:

  • DRYer:beforeノードを変数に格納して2回使用する必要はありません。変数の名前を変更すると、変更する頻度が少なくなります。
  • ゴルフよりも優れているinsertBefore(既存のノード変数名が3文字であっても壊れる)

欠点:

  • 新しいものからのブラウザサポートの低下:https : //caniuse.com/#feat=insert-adjacent
  • outerHTML要素を文字列に変換するため、イベントなどの要素のプロパティが失われます。insertAdjacentHTML要素ではなく文字列からコンテンツを追加するために必要です。

12
既に要素を構築している場合は、次の.insertAdjacentElement()
コマンド

6
2018年現在、ブラウザのサポートはかなり堅固に見えます:caniuse.com/#feat=insert-adjacent
madannes

これは良い解決策でした。eveyoneがこのxahlee.info/js/js_insert_after.htmlを
Mehregan Rahmani

37

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

29
このスクリプトを偶然見つけた人には、このスクリプトの使用をお勧めしません。@ karim79のネイティブソリューションがすでに解決している問題を解決しようとします。彼のスクリプトはより高速で効率的です。このスクリプトの代わりにそのスクリプトを使用することを強くお勧めします。
James Long

10
JavaScriptの一般的な経験則として、ブラウザーは、ユーザーが記述できるものよりも速くタスクを実行できます。2つのソリューションは機能的には同じですが、JavaScriptソリューションを使用するには、ブラウザーが理解できるようにしておく必要があり、実行するたびに追加のチェックが必要です。karim79が提供するソリューションは、これらすべてを内部で実行し、それらの手順を節約します。違いはせいぜい些細なことですが、彼の解決策はより良いものです。
James Long

3
つまり、存在しない問題を解決しようとしているのです。追加のチェックについて本質的に問題はありませんが、これらのメソッドの理解を深めることはできていません
1j01

3
かなり。私が以前スクリプトを書いていたようなものなので、ここにスクリプトを残しますが、受け入れられた答えはより良いものであり、メソッドのより良い理解を示し、より高速です。代わりにこの回答を使用する理由はありません-なぜそれがまだ賛成票を獲得するのかさえわかりません
James Long

3
targetElementが兄弟の最後の要素である場合は、targetElement.nextSiblingが返されnullます。ときnode.insertBeforeに呼ばれてnull、それの2番目の引数として、それは、コレクションの末尾にノードを追加します。言い換えると、最初は別の方法で表示される場合でも、if(parent.lastchild == targetElement) {ブランチはparent.insertBefore(newElement, targetElement.nextSibling);すべてのケースを適切に処理するため、不要です。多くの人がすでに他のコメントでそれを指摘しています。
2016年

26

けれども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/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


本当にこの答えに愛を与えるべきです、それはすぐに近づいている2020年代のための現代的なアプローチです。
serraosays

1
なぜこの答えはそれほど深く埋まっているのですか?私はそれにもっと注目を集めるためにいくつかのポイントを報います。
Qwerty

16

メソッドnode.afterdoc)は、ノードを別のノードの後に​​挿入します。

2つのDOMノードの場合node1node2

node1.after(node2)node2後に挿入しnode1ます。

このメソッドは古いブラウザでは使用できないため、通常はポリフィルが必要です。


ただし、機能するinsertAfterとして実装するには少し手作業が必要なため、残念ながらこれが正しく機能するとは思わない。
ミスターSirCode

6

2018ソリューション(悪い習慣、2020年まで)

私はこの質問が古代であることを知っていますが、今後のユーザーのために、変更されたプロトタイプは、存在しない.insertAfter関数のマイクロポリフィルにすぎません。このプロトタイプは、新しい関数baseElement.insertAfter(element);をElementプロトタイプに直接追加します。

Element.prototype.insertAfter = function(new) {
    this.parentNode.insertBefore(new, this.nextSibling);
}

ライブラリ、要旨、またはコード内(または参照可能な他の場所)にポリフィルを配置したら、次のように記述します document.getElementById('foo').insertAfter(document.createElement('bar'));


2019ソリューション(醜い、2020に進む)

新しい編集:プロトタイプは使用しないでください。これらはデフォルトのコードベースを上書きし、非常に効率的または安全でなく、互換性エラーを引き起こす可能性がありますが、非営利プロジェクトの場合は問題になりません。 商用利用に安全な機能が必要な場合は、デフォルトの機能を使用してください。それはきれいではありませんが、うまくいきます:

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 


2020ソリューション

ChildNodeの現在のWeb標準:https ://developer.mozilla.org/en-US/docs/Web/API/ChildNode

現在は生活基準にあり、安全です。

サポートされていないブラウザの場合は、このポリフィルを使用してください:https : //github.com/seznam/JAK/blob/master/lib/polyfills/childNode.js

ポリフィルがプロトスを使用していると誰かが言ったとき、私はそれらが悪い習慣だと言った。それらは、特に2018年の私のソリューションのように、正しく使用されていない場合に使用されます。ただし、そのポリフィルは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

5

または、単に次のようにすることもできます。

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

私はそのアプローチを考えていなかっただろう。@ karim79のより直接的な回答を使用したいと思いますが、覚えておくと良いでしょう。
ベンJ

5

ステップ1.要素を準備する:

var element = document.getElementById('ElementToAppendAfter');
var newElement = document.createElement('div');
var elementParent = element.parentNode;

ステップ2.後に追加:

elementParent.insertBefore(newElement, element.nextSibling);

3

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 DOMのinsertAfter()メソッド@ jsfiddle.net


2

理想的に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;
};

一般的な例の1つ

node.parentNode.insertAfter(newNode, node);

実行中のコードを確認する


2

この質問にはすでに回答が多すぎることはわかっていますが、私の正確な要件を満たしているものはありません。

私は正反対の挙動を有する機能たかったparentNode.insertBeforeですが、それがnullを受け入れる必要があります- referenceNode(これは受け入れられた答えはありません)、どこinsertBeforeに挿入する最後の子供たちのこの1をで挿入する必要があります開始「そうでない場合があることから、 dこの関数では、開始位置に挿入する方法はまったくありません。同じ理由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
    );
  };
}

0

このコードは、最後の既存の子の直後にリンク項目を挿入して小さな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);


0

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'."));

};


現在の問題を修正する方法で、この答えのヘルプOPのための答えを持ついくつかの説明を追加
ρяσѕρєяK

上記のコードを実行すると、指定したreferenceNodeの後にnewNodeを挿入できます。
jszhou 2017年

0

すべてのシナリオを処理できます

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

0
if( !Element.prototype.insertAfter ) {
    Element.prototype.insertAfter = function(item, reference) {
        if( reference.nextSibling )
            reference.parentNode.insertBefore(item, reference.nextSibling);
        else
            reference.parentNode.appendChild(item);
    };
}

0

実際には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>

予想通り、上要素を下要素の後に移動します

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.