つくる ギャラリーをデータ駆動にする
このレッスンで分かること
- HTML に直接書いた一覧を、データから描く形に置きかえる手順
- 描き直す前に中身を空にする理由
- データの値で見た目を切り替える書き方
つくる ギャラリーをデータ駆動にする とは
作品ギャラリーを、HTML に書いた 3 枚から配列 1 本に置きかえる回です。作品を増やしたいときに直す場所が、データの 1 行だけになります。
ここまでで何ができるようになったか
第8章の 6 回でできるようになったことを並べます。
querySelectorとquerySelectorAllで、ほしい要素を掴めるようになったtextContentで、表示されている文字を差し替えられるようになったclassListで、CSS に用意した見た目を付け外しできるようになったcreateElementとappendで、HTML に無い要素をつくって足せるようになった- オブジェクトの配列と
forEachで、カードを必要なだけ量産できるようになった
今回はこれを全部つないで、作品ギャラリーを完全にデータ駆動にします。コースの看板である「DOM を操作してページを書き換えられる」が、ここで形になります。
いまのギャラリーは二重管理になっている
前回の時点で、作品ギャラリーには 5 枚のカードが並んでいます。しかしその出どころは 2 か所に分かれています。
| 出どころ | 枚数 | 直す場所 |
|---|---|---|
HTML に直接書いた article | 3 枚 | index.html |
配列から JavaScript が描いた article | 2 枚 | extraWorks の配列 |
作品を 1 つ増やしたいとき、どちらに足せばいいのでしょうか。どちらでも出せてしまいます。だから半年後の自分は迷いますし、表示の順番を変えたくなったときには、HTML と JavaScript の両方を見比べる必要が出ます。これが二重管理です。
答えは単純で、片方に寄せます。寄せる先は配列のほうです。データにしておけば、並べかえも絞り込みも、あとから来る機能を全部その 1 か所で受け止められます。
消す前に、同じ見た目をつくる
いきなり HTML の 3 枚を消すと、うまくいかなかったときに何が原因なのか分からなくなります。段取りを 2 つに分けます。
- まず配列に 3 枚ぶんのデータを足し、JavaScript が描いたカードがHTML の 3 枚と同じ見た目になることを確かめる
- 見た目がそろってから、HTML の
article3 つを消す
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 つです。
worksの配列を 6 件でつくる。HTML に書いてある 3 枚も、ここにデータとして入れるcreateWorkCardに、viewsが 100 以上ならfeaturedを付ける条件を足すrenderWorksを書く。最初に.work-listを空にしてから、公開ぶんだけを描く- 見た目がそろったのを確かめて、HTML の
article3 つを消し、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 から消した要素を掴んでいた古いコードが残っていると、null や undefined に対する操作でエラーになります。エラーが出た行より下は動かないので、「途中までしか描かれない」という症状になります。
const cards = document.querySelectorAll(".work-card"); // 空になった
cards[0].classList.add("featured"); // TypeError で止まるHTML に書いた見た目と、JS でつくる見た目がずれる
class の付け忘れがいちばん多い原因です。HTML では <article class="work-card"> なのに、JavaScript で card.className を書き忘れると、枠も余白も付かない裸の article が並びます。並べて見比べる段取りは、このずれを見つけるためのものです。
課題
worksに 6 件のオブジェクトを入れる。HTML に書いてあった 3 枚もデータとして入れ、「つくりかけの計算機」だけpublishedをfalseにするcreateWorkCard(work)の中で、work.viewsが 100 以上ならclassList.add("featured")を付けるrenderWorks(list)を書く。最初に.work-listをtextContent = ""で空にしてから、公開ぶんだけをappendするcardsを使っていた第58回から第60回の処理を消し、HTML パネルのarticle.work-card3 つも消す