つくる ギャラリーをデータ駆動にする

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

  • HTML に直接書いた一覧を、データから描く形に置きかえる手順
  • 描き直す前に中身を空にする理由
  • データの値で見た目を切り替える書き方

つくる ギャラリーをデータ駆動にする とは

作品ギャラリーを、HTML に書いた 3 枚から配列 1 本に置きかえる回です。作品を増やしたいときに直す場所が、データの 1 行だけになります。

ここまでで何ができるようになったか

第8章の 6 回でできるようになったことを並べます。

  • querySelectorquerySelectorAll で、ほしい要素を掴めるようになった
  • textContent で、表示されている文字を差し替えられるようになった
  • classList で、CSS に用意した見た目を付け外しできるようになった
  • createElementappend で、HTML に無い要素をつくって足せるようになった
  • オブジェクトの配列と forEach で、カードを必要なだけ量産できるようになった

今回はこれを全部つないで、作品ギャラリーを完全にデータ駆動にします。コースの看板である「DOM を操作してページを書き換えられる」が、ここで形になります。

いまのギャラリーは二重管理になっている

前回の時点で、作品ギャラリーには 5 枚のカードが並んでいます。しかしその出どころは 2 か所に分かれています。

出どころ枚数直す場所
HTML に直接書いた article3 枚index.html
配列から JavaScript が描いた article2 枚extraWorks の配列

作品を 1 つ増やしたいとき、どちらに足せばいいのでしょうか。どちらでも出せてしまいます。だから半年後の自分は迷いますし、表示の順番を変えたくなったときには、HTML と JavaScript の両方を見比べる必要が出ます。これが二重管理です。

答えは単純で、片方に寄せます。寄せる先は配列のほうです。データにしておけば、並べかえも絞り込みも、あとから来る機能を全部その 1 か所で受け止められます。

消す前に、同じ見た目をつくる

いきなり HTML の 3 枚を消すと、うまくいかなかったときに何が原因なのか分からなくなります。段取りを 2 つに分けます。

  1. まず配列に 3 枚ぶんのデータを足し、JavaScript が描いたカードがHTML の 3 枚と同じ見た目になることを確かめる
  2. 見た目がそろってから、HTML の article 3 つを消す

1 の途中では、同じ作品のカードが 2 枚ずつ並びます。それでいいのです。左右に同じものが並んでいる状態で、文字の入り方や枠の付き方をよく見比べます。ここで違いに気づいておけば、消したあとに慌てずに済みます。

動いているものを置きかえるときは、いつでもこの順番が安全です。新しいほうを先につくり、両方が同じ結果になることを見てから、古いほうを外す。実務では並行稼働と呼ばれるやり方で、Web に限らずデータの移行でも使われます。

描き直す関数にする

配列を 1 本にまとめます。作品は 6 件で、うち 1 件は非公開です。

const works = [ { title: "プロフィールサイト", year: 2026, views: 120, published: true }, { title: "自己紹介カード", year: 2026, views: 48, published: true }, { title: "スキル一覧の表", year: 2026, views: 32, published: true }, { title: "JavaScript のメモ帳", year: 2026, views: 0, published: true }, { title: "クリックできるボタン", year: 2026, views: 8, published: true }, { title: "つくりかけの計算機", year: 2026, views: 3, published: false } ];

描く側も関数にします。前回は forEach を素で書きましたが、今回は renderWorks という関数で包みます。

function renderWorks(list) { const workList = document.querySelector(".work-list"); workList.textContent = ""; list.forEach((work) => { if (!work.published) { return; } workList.append(createWorkCard(work)); }); } renderWorks(works);

新しいのは workList.textContent = "" の 1 行です。描き始める前に、中身をいったん空にしています。

なぜ要るのでしょうか。append は足すだけで、前にあったものを消しません。空にしないまま renderWorks をもう一度呼ぶと、同じカードがもう一組ぶら下がります。第9章でボタンから呼べるようにすると、押すたびにカードが倍になっていきます。描き直す関数は、まず空にしてから描くと決めておくと、何度呼んでも結果が同じになります。

この 1 行があるおかげで、HTML に書いた 3 枚も消えます。つまり、消し忘れても画面は正しくなります。それでも HTML からは消してください。読む人が「この 3 枚はどこに出ているのだろう」と探すことになるからです。

データで見た目を切り替える

せっかくデータを持っているので、値によって見た目を変えてみます。よく見られている作品を目立たせます。

function createWorkCard(work) { const card = document.createElement("article"); card.className = "work-card"; if (work.views >= 100) { card.classList.add("featured"); } // … 見出しと補足を組み立てる return card; }

views が 100 以上なら featured を付けます。今回のデータでは「プロフィールサイト」だけが 120 なので、1 枚目だけ枠が青くなります。

ここが手で classList.add を書いていたときとの決定的な違いです。前は「1 枚目を強調する」と書いていました。いまは「よく見られているものを強調する」と書いてあります。データが変われば、強調される相手も勝手に変わります。第4章の条件分岐が、画面の見え方を決める道具になりました。

前回まで書いていた cards を使った処理は、もう消してください。HTML からカードが無くなると querySelectorAll(".work-card") は空になり、cards[0]undefined になります。そのまま classList を呼べばエラーで止まり、その下の処理も動かなくなります。使わなくなったコードを残さないのは、動かすためでもあります。

今回書くこと

やることは次の 4 つです。

  1. works の配列を 6 件でつくる。HTML に書いてある 3 枚も、ここにデータとして入れる
  2. createWorkCard に、views が 100 以上なら featured を付ける条件を足す
  3. renderWorks を書く。最初に .work-list を空にしてから、公開ぶんだけを描く
  4. 見た目がそろったのを確かめて、HTML の article 3 つを消し、cards を使っていた処理も消す

完成すると、作品ギャラリーには 5 枚のカードが並びます。1 枚目は青い枠で強調され、それぞれに「2026 年 / 120 回表示」のような補足が付きます。works の 1 行を書きかえるだけで、画面がそのとおりに変わることを確かめてください。

よくある間違い

空にせずに描いて、カードが倍になる

workList.textContent = "" が無いまま renderWorks を 2 回呼ぶと、10 枚並びます。描き直す関数の 1 行目を空にする、と覚えます。

function renderWorks(list) { const workList = document.querySelector(".work-list"); // workList.textContent = ""; を忘れると足されるだけになる }

消したはずの要素を掴んだままにする

HTML から消した要素を掴んでいた古いコードが残っていると、nullundefined に対する操作でエラーになります。エラーが出た行より下は動かないので、「途中までしか描かれない」という症状になります。

const cards = document.querySelectorAll(".work-card"); // 空になった cards[0].classList.add("featured"); // TypeError で止まる

HTML に書いた見た目と、JS でつくる見た目がずれる

class の付け忘れがいちばん多い原因です。HTML では <article class="work-card"> なのに、JavaScript で card.className を書き忘れると、枠も余白も付かない裸の article が並びます。並べて見比べる段取りは、このずれを見つけるためのものです。

課題

  1. works に 6 件のオブジェクトを入れる。HTML に書いてあった 3 枚もデータとして入れ、「つくりかけの計算機」だけ publishedfalse にする
  2. createWorkCard(work) の中で、work.views が 100 以上なら classList.add("featured") を付ける
  3. renderWorks(list) を書く。最初に .work-listtextContent = "" で空にしてから、公開ぶんだけを append する
  4. cards を使っていた第58回から第60回の処理を消し、HTML パネルの article.work-card 3 つも消す

ヒント

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

できているか

  • 作品カードが 5 枚描かれる
  • 1 枚目が配列の 1 件目になる
  • views が 100 以上の作品が強調される
  • 2 枚目の補足行が配列の値から描かれる
  • 非公開の作品は描かれない
  • 5 枚すべてに補足行がある