これまでの記事を通して様々なDOM操作を学んできましたが、すべて既存の要素に対するものでした。
今回は「無から有を生み出す」、つまりDOMに存在していない新たなノードを作成する方法を学習します。
作成できるノードの種類
- 要素ノード
- テキストノード
- 属性ノード
- コメントノード
- フラグメントノード(DOMの部品、断片)
上記の内、本記事では「要素ノード」、「テキストノード」、「属性ノード」を対象として説明します。
要素ノードを新規作成する
DOMの要素ノードを新たに作成するには、createElementメソッドを使用します。
簡単なサンプルプログラムを作成してみましょう。
「作成」ボタンをクリックすると、divノードを作成する。
<!-- ここより上は省略 -->
<body>
<button>作成</button>
<script>
let button = document.querySelector("button");
button.addEventListener("click", function() {
document.createElement("div");
});
</script>
</body>
</html>
👆こちらのHTMLをブラウザで開き、「作成」ボタンをクリックしてみてください。
エラーも出ず、正常に動作しているようですが、新たなdivが作られているようには見えません。
divの内容が空だから表示されないだけなのか、デベロッパーツールのコンソールや要素タブで確認しても、やはり追加はされていないようです。
はい、この挙動は正しいです。
createElementメソッドでノードを作成するだけでは、DOMへの追加は行われません。
作成したノードをDOMに追加する
作成したノードをDOMに追加するには、次のメソッドを使用します。
- 対象ノード内にある子要素の末尾に追加する
- appendメソッド
- appendChildメソッド
- 対象ノード内にある子要素の先頭に追加する
- prependメソッド
早速、前項で作成したdivノードをbody内に追加してみましょう。
今回はappendメソッドを使用し、末尾に追加します。
<!-- ここより上は省略 -->
<body>
<button>作成</button>
<script>
let button = document.querySelector("button");
button.addEventListener("click", function() {
let div = document.createElement("div");
document.querySelector("body").append(div);
});
</script>
</body>
</html>
いかがでしょうか。
divの内容が空であるためブラウザの画面は何の変化も見られませんが、デベロッパーツールの要素タブを開いて「作成」ボタンをクリックすると、bodyの末尾にdivが追加されているはずです。
テキストノードを新規作成する
せっかくdivノードを作成しても、内容が空ではブラウザの画面で確認できず少々残念です。
そこで、テキストノードを作成し、divに追加してみましょう。
テキストノードを新たに作成するには、createTextNodeメソッドを使用します。
<!-- ここより上は省略 -->
<body>
<button>作成</button>
<script>
let button = document.querySelector("button");
button.addEventListener("click", function() {
// divノードの作成とbodyへの追加
let div = document.createElement("div");
document.querySelector("body").append(div);
// ここから下の2行を追加する
let txt = document.createTextNode("Hello!");
div.append(txt);
});
</script>
</body>
</html>
これで、デベロッパーツールを開かずとも、ブラウザの画面上で挙動を確認できるようになりました。
属性ノードの作成と追加
もう少しだけ実践的な内容に踏み込んでいきましょう。
作成したHTMLファイルに、次のCSSスタイルを組み込みます。
<style>
/* my-testというclassが付与された要素は文字色が緑 */
.my-text {
color: green;
}
</style>
このCSSスタイルを「属性ノード」としてJavaScriptで作成し、divに反映させます。
setAttributeメソッドを使用することで、対象要素に対して、属性ノードの作成と追加を一括で行うことができます。
<!-- ここより上は省略 -->
<body>
<button>作成</button>
<script>
let button = document.querySelector("button");
button.addEventListener("click", function() {
// divノードの作成とbodyへの追加
let div = document.createElement("div");
document.querySelector("body").append(div);
// テキストノードの作成とdivへの追加
let txt = document.createTextNode("Hello!");
div.append(txt);
// ここから下の1行を追加する
div.setAttribute("class", "my-text");
});
</script>
</body>
</html>
setAttributeメソッドが、属性を追加する対象の要素から直接呼び出されていることに注意してください。
メソッドに渡されている2つの引数はそれぞれ次の通りです。
- 第一引数
- 追加する属性の種類(今回は class)
- 第二引数
- 追加する属性の値
実践的な練習問題
次のような仕様を満たすよう、JavaScriptプログラムを作成してください。
- 「リスト作成」というボタンをクリックすると、既に用意されている<ul>の子要素として3つの li が追加される。
- 3つの li はループ処理を使用して作成すること。
- それぞれの li には、テキスト「Hello」を設定する。
- ノードの作成は別の関数で処理する。
- ノード作成関数は、li を新規で作成し、テキストノードを追加する。
- 処理結果をリターンする。
実践的で難易度の高い問題となっていますので、ヒントのコメント付きテンプレートを掲載しておきます。
<!-- ここより上は省略 -->
<body>
<button>リスト作成</button>
<ul></ul>
<script>
const button = document.querySelector("button");
button.addEventListener("click", function() {
// ul要素を取得する
// liの個数分、3回ループ
// ループ内で li作成用関数を呼び出し、戻り値を受け取る
// ループ内で ul に li を追加する
});
function createLi() {
// liノードを作成する
// テキストノードの作成と追加も行う
// 処理の最後に作成した li を返却(return)する
}
</script>
</body>
</html>
まとめ
本記事をもって、DOM操作の基本は修了です。
JavaScriptの最大の活躍の場はWebフロントエンドであり、中でもDOM操作はJavaScriptの最も得意とする分野です。
入門編の内容も併せて、実践に役立てていただければ幸いです。
本記事についての質問、誤りの指摘、ご意見ご感想などありましたら、ぜひコメント頂ければ幸いです。
最後までお読みいただき、ありがとうございます。

コメント