要素を作って追加する

このレッスンで分かること

  • createElement で新しい要素をつくる書き方
  • つくった要素にテキストと class を設定する順番
  • appendappendChild の違い

要素を作って追加する とは

HTML に書いていない要素を JavaScript でつくり、DOM の木に足す操作です。作品カードが 1 枚、JavaScript の力で増えます。

HTML に無いものを出す

ここまでは、HTML にすでにある要素を掴んで書きかえてきました。今回はその一歩先で、もともと無かった要素をつくって足します。ページを開いた瞬間に作品カードが 4 枚になる、という状態をつくります。

手順は 3 つに分かれます。この順番を体で覚えると、あとの回が楽になります。

  1. つくる … document.createElement("article")
  2. ととのえる … classNametextContent を設定する
  3. 木に足す … 親.append(つくったもの)

3 番目をやるまで、つくった要素は画面に出ません。変数の中に浮いているだけで、まだどの親にも属していないからです。ここが最初のつまずきどころです。

つくる

document.createElementタグ名を渡すと、そのタグの要素が 1 つできます。渡すのはタグ名だけで、<> は書きません。

const newCard = document.createElement("article"); console.log(newCard); // <article></article>

できたばかりの要素は、中身も class も何もない空っぽの状態です。ここに設定を足していきます。

newCard.className = "work-card"; const newHeading = document.createElement("h3"); newHeading.textContent = "JavaScript のメモ帳"; const newMeta = document.createElement("p"); newMeta.className = "work-meta"; newMeta.textContent = "2026 年 / 0 回表示";

className を使っているのは、まだ何の class も付いていない新品だからです。前回話したとおり、既存の要素をいじるときは classList を使い、新品に最初の class を与えるときは className が素直です。

文字を入れるのは textContent です。前々回に学んだとおり、ここで innerHTML を使う理由はありません。

createElement でつくれるのは要素だけです。文字だけのノードが欲しいときは document.createTextNode("文字") がありますが、textContent に代入すれば同じことができるので、実際に書く場面はほとんどありません。

木に足す

親になる要素を掴んで、append を呼びます。渡したものが、その親のいちばん最後の子として入ります。

const workList = document.querySelector(".work-list"); newCard.append(newHeading, newMeta); // カードの中に見出しと本文を入れる workList.append(newCard); // ギャラリーの最後にカードを足す

上の 2 行で、次の HTML を書いたのと同じ形が DOM にできあがります。

<article class="work-card"> <h3>JavaScript のメモ帳</h3> <p class="work-meta">2026 年 / 0 回表示</p> </article>

組み立ての順番は自由です。先に中身を入れてから親に足しても、先に親へ足してから中身を入れても、結果は同じになります。ただし、先に中身を組み立ててから最後に 1 回だけ親へ足す書き方のほうが、ブラウザが画面を描き直す回数が減ります。要素の数が多くなるほど差が出るので、この順番を習慣にしておくと得です。

append と appendChild

要素を足す書き方は 2 つあります。似ていますが、できることが違います。

書き方渡せるもの一度に渡せる数返り値
append要素と文字列何個でもなし (undefined)
appendChild要素だけ1 つだけ足した要素

append は新しいほうで、使い勝手がよくなっています。文字列をそのまま渡せますし、複数をまとめて渡せます。

newCard.append(newHeading, newMeta); // 2 つまとめて workList.append("おしらせ"); // 文字列も渡せる (テキストノードになる)

appendChild は古くからある書き方です。1 つずつしか渡せず、文字列を渡すとエラーになります。

newCard.appendChild(newHeading); newCard.appendChild(newMeta); newCard.appendChild("文字"); // TypeError

古い記事では appendChild をよく見ますが、いま新しく書くなら append で構いません。返り値が要らないのであれば、こちらのほうが行数も減ります。

置き場所を細かく決めたいときは、次のものもあります。名前だけ知っておけば、必要になったときに調べられます。

  • prepend … 先頭の子として入れる
  • before / after … その要素の前 / うしろの兄弟として入れる
  • remove … その要素を木から外す

同じ要素を 2 つの親に append すると、コピーはされません。元の場所から引っこ抜かれて移動します。1 つの要素は木の 1 か所にしか存在できないためです。同じ見た目を 2 か所に出したいときは、createElement からもう 1 つつくります。

今回書くこと

前回までのコードの下に、4 枚目の作品カードをつくって足す処理を書きます。中身は次のとおりです。

  • article をつくり、class を work-card にする
  • h3 をつくり、文字を「JavaScript のメモ帳」にする
  • p をつくり、class を work-meta、文字を「2026 年 / 0 回表示」にする
  • h3p をカードに入れ、カードを .work-list に足す

work-meta は CSS に用意ずみの class で、文字を少し小さくして灰色にします。作品の補足を出す行に使います。

プレビューでは、ギャラリーに 4 枚目のカードが現れます。検証ツールで見ると、HTML には書いていない article が DOM に増えているのが分かります。ソースの表示のほうには出てきません。これが第57回で話した「HTML と DOM は別物」ということです。

ここで少し立ち止まって考えてみてください。もし作品が 10 個あったら、この 10 行を 10 回書くことになります。変数名も newCard2 newCard3 と増えていきます。明らかに無理があります。次の回では、この組み立てを関数にまとめ、作品の配列からまわして量産します。今回書くコードは、その関数の中身の下書きにあたります。

よくある間違い

append を忘れる

いちばん多い間違いです。エラーは出ません。何も起きないだけです。

const card = document.createElement("article"); card.textContent = "つくったよ"; // workList.append(card) を書き忘れると画面に出ない

「動かない」ではなく「出てこない」ときは、まず append の行があるかを見ます。

タグ名にかっこや記号を付ける

createElement に渡すのはタグ名だけです。

document.createElement("<article>"); // 不正なタグ名でエラー document.createElement(".work-card"); // これもエラー document.createElement("article"); // 正しい

class を付ける先を間違える

見た目が当たらないときは、class を付けた要素と、CSS が狙っている要素がずれていることがよくあります。.work-card の指定は article に付けないと効きません。中の h3 に付けても何も起きません。

課題

  1. document.createElement("article") でカードをつくり、className"work-card" にする
  2. h3 をつくり、textContent"JavaScript のメモ帳" にする
  3. p をつくり、className"work-meta"textContent"2026 年 / 0 回表示" にする
  4. h3p をカードに入れ、.work-list にカードを append する

ヒント

index.html
style.css
script.js
プレビュー

できているか

  • 作品カードが 4 枚になる
  • 4 枚目の見出しが入る
  • 4 枚目に work-meta の補足行がある
  • 補足行がカードの中に入っている
  • 前回の featured が残っている