【Javascript】 HTMLの要素の作成と追加削除の方法
ここでは, DOMの操作の続きを紹介していきます。先程はテキスト取得や置換を行いましたが、ここではDOM要素を追加したりする方法を学びましょう。
要素の取得に関しては下の記事を参考にしてください。
目次
要素の作成
HTMLのままではDOMの操作には利用できない場面がほとんどです。DOMの要素として作成する必要があります。
そのためには、createElement
します。
const p = document.createElement("p"); p.textContent = "p tag text";
p
タグの要素を作成しています。つまり、<p></p>
を作ったということです。そのままでは何もテキストが無いため、textContent
やinnerHTML
に代入して表示できるようにします。
しかし、作成しただけではまだ表示されません。作成したものは表示されるよう、DOMに追加する必要があります。
DOMへの追加
追加したい場所の要素を取得してから、そこに対して操作を行います。
要素の取得は、getElementById
などで取得したElementです。
最後の子要素として追加(appendChild)
ある要素の最後の子要素として追加するには、appendChild
を利用します。
See the Pen DOM2 add dom by Totori (@souki202) on CodePen.
作成したli
の要素を、querySelector
で取得したul
の子要素として追加しています。
一度追加した要素を追加しようとしても失敗するので注意が必要です。
これは、同じノードであれば追加ではなく移動するためです。
取得した要素を追加に回すと?
上では新規作成した要素を追加しましたが、取得した要素を追加の要素として利用したらどうなるでしょうか。
See the Pen DOM2 add dom2 by Totori (@souki202) on CodePen.
.nav-top
の要素を追加に回してみました。これを見ると、取得した要素(一番上)が最後尾に回っただけです。すでにDOMに存在する要素だった場合、要素はコピーされるのではなく、移動しているということです。
すでにある要素というのは、中身のHTMLが同じというものではなく、内部の識別用IDのようなものが同じであるもの、ということです。
最初の子要素として追加
直接的なメソッドはないため, 代替手段としてinsertBefore
を使い、1番目の要素の手前に挿入します。
See the Pen DOM2 add dom4 by Totori (@souki202) on CodePen.
insertBefore
は、親ノード.insertBefore(追加ノード, 参照ノード);
という呼び出し方です。追加したノードが戻り値になります。
参照ノードというのは、このノードの手前に追加ノードを追加する、という意味です。そして参照ノードは親ノードの子に含んでいる必要があります。
今回は、親ノードがul
、参照ノードにはul
の最初の子要素を指定します。追加ノードはその最初の子要素の手前に挿入されます。
指定した要素の直後に追加
insertAfter
は無いため、insertBefore
とNode.nextSibling
を使用します。
See the Pen DOM2 add dom5 by Totori (@souki202) on CodePen.
これは商品一覧の次に追加するコードです。商品一覧をul.children[1]
で取得し、その次のノードは、ul.children[1].nextSibling
で取得できます。
つまり、あるノードの次に追加 = 次のノードの手前に追加 ということです。
DOMのノード削除
一口に削除と言っても、特定の子要素だけ削除するのか、子要素全部削除するのか、削除するのは自分自身なのかで変わってきます。
自分自身を削除
取得した要素でremove()
を呼びます。
See the Pen DOM2 del dom1 by Totori (@souki202) on CodePen.
リストの一番上の要素を削除しています。
要素を取得したら、要素.remove()
で削除します。
子要素を全て削除
2通りあります。1つは全ての子要素をremoveChild
で消す方法、もう一つはtextContent
かinnerHTML
を空にする方法です。
See the Pen DOM2 del dom2 by Totori (@souki202) on CodePen.
See the Pen DOM2 del dom3 by Totori (@souki202) on CodePen.
1つ目は、要素の中身を空のテキストにすることで子要素をまるごと消しています。この場合、子要素以外のテキストもまるごと消えます。
例えば、
<p>aaa<span>bbb</span></p>
の場合、p
のtextContent
を空にするので、
<p></p>
になります。
2つ目は、removeChild
を使用して1つ1つ子要素を削除しています。そのため、1個目とは違い指定した要素の直下にあるテキストは残ります。
<p>aaa<span>bbb</span></p>
の場合、p
の子要素であるspan
が削除されるので、
<p>aaa</p>
になります。ネイティブの操作をすることはあまりないと思いますが、違いがあるというのを把握しておくとバグの回避になると思います。
2つ目でfor-ofなどではなくwhileしているのは、要素数が動的に変わってうまくforできないためです。for文を回している最中に配列自体の要素数が減っていくので、中途半端にしか消えません。
まとめ
DOMの追加では、同じノードを追加しようとしてもコピーではなく移動になる、というのを知っておく必要があります。
削除は、自分自身を消すだけなら要素.remove()
とするだけで削除できます。
