要素を作って追加する
このレッスンで分かること
createElementで新しい要素をつくる書き方- つくった要素にテキストと class を設定する順番
appendとappendChildの違い
要素を作って追加する とは
HTML に書いていない要素を JavaScript でつくり、DOM の木に足す操作です。作品カードが 1 枚、JavaScript の力で増えます。
HTML に無いものを出す
ここまでは、HTML にすでにある要素を掴んで書きかえてきました。今回はその一歩先で、もともと無かった要素をつくって足します。ページを開いた瞬間に作品カードが 4 枚になる、という状態をつくります。
手順は 3 つに分かれます。この順番を体で覚えると、あとの回が楽になります。
- つくる …
document.createElement("article") - ととのえる …
classNameやtextContentを設定する - 木に足す …
親.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 回表示」にするh3とpをカードに入れ、カードを.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 に付けても何も起きません。
課題
document.createElement("article")でカードをつくり、classNameを"work-card"にするh3をつくり、textContentを"JavaScript のメモ帳"にするpをつくり、classNameを"work-meta"、textContentを"2026 年 / 0 回表示"にするh3とpをカードに入れ、.work-listにカードをappendする