コース一覧
JavaScriptでWebページを動かす
つくる ひとことメモウィジェット

JavaScriptでWebページを動かす

DOM から要素を取得・更新・追加し、クリック・入力・フォーム送信に反応する処理を作る全 20 レッスン(411 分)のコースです。タイマーと localStorage も使い、最後は入力を保存できるひとことメモを仕上げます。用意された HTML/CSS を使うため、学習の中心は JavaScript です。

1
DOM のきほん
01. DOM とは何か15分
02. 要素を取得する20分
03. テキストを書き換える20分
04. class を付け外しする20分
05. 要素を作って追加する20分
06. 配列から一覧を描画する25分
07. つくる ギャラリーをデータ駆動にする30分
08. 第1章まとめクイズ10分
2
イベント処理
01. クリックに反応する18分
02. event オブジェクト20分
03. 入力欄の値を取る18分
04. フォーム送信を制御する20分
05. つくる ダークモード切替25分
06. つくる フォームの入力チェック25分
07. 第2章まとめクイズ10分
3
タイマーと総合制作
01. setTimeout と setInterval20分
02. localStorage で保存する20分
03. つくる ひとことメモウィジェット30分
04. 自由拡張30分
05. 完成と次のステップ15分

つくる ひとことメモウィジェット

解説

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

  • 追加も削除も、まず配列を変えてから一覧をまるごと描き直します
  • 配列を変えた場所すべてで保存すると、メモがリロードをまたいで残ります

2 件目を消したはずが、3 件目が消える

削除ボタンを作るとき、押された li をその場で画面から取り除く書き方を思い付きます。1 件だけなら動きます。ところが 2 件目を消したあと、残った 3 件目のボタンを押すと、まるで違うものが消えます。ボタンが覚えている番号は作ったときのままなのに、画面の並びだけが 1 つ詰まったからです。

画面を直接いじって帳尻を合わせようとすると、件数の表示も、削除ボタンの番号も、すぐにずれます。逃げ道は 1 つです。本物は配列のほうで、画面はそれを写したものと決めてしまいます。追加でも削除でも、やることは「配列を変える」「配列から一覧を作り直す」の 2 手だけになります。

今回はこの形でひとことメモのウィジェットを作ります。新しい文法はほとんど足しません。第5章の配列、第6章の関数、第8章の組み立て、第9章のイベント、前回の保存を 1 か所に合流させるだけです。決まりは次のとおりです。

  • 作品とお問い合わせのあいだにメモの section を足し、入力欄・追加ボタン・案内文・一覧・件数を id で用意する
  • メモの配列を持ち、読み込み時に保存から読み戻す。読めないときや保存が無いときは空の配列にする
  • 一覧を作り直す関数を 1 本用意し、1 件ごとに li と削除ボタンを作って件数も入れる
  • 追加ボタンは入力欄の値を trim() して配列に足し、入力欄を空にする。空のときは追加せず案内文を出す
  • 追加と削除のどちらでも、配列を変えたあとに保存する

描き直しは、先に空にしてから

描き直す関数は、いちばん最初に中身を捨てるところから始めます。ここを忘れると、呼ぶたびに古い一覧の下へ積み上がっていきます。

JavaScript

const tags = ["HTML", "CSS", "JavaScript"]; tagList.textContent = ""; tags.forEach(function (tag, index) { const item = document.createElement("li"); item.textContent = index + " 番目 " + tag; tagList.appendChild(item); });

forEach の第 2 引数 index が、その要素が配列の何番目かです。削除ボタンをこの中で作れば、ボタンの処理から index を見られます。関数の中から外側の変数を見られるのは、第6章でやったとおり、関数が書かれた場所の変数を覚えているからです。

配列から 1 件だけ抜くのは splice です。第 2 引数を省くと、その位置から後ろが全部消えてしまうので必ず 2 つ書きます。

JavaScript

tags.splice(1, 1); console.log(tags); // ["HTML", "JavaScript"]

抜いたあとに描き直す関数をもう一度呼べば、番号は振り直され、残ったボタンは正しい番号を持ち直します。冒頭の「3 件目が消える」が起きなくなるのは、この一手のおかげです。

配列を変えたら、その場で保存する

保存は前回と同じ形です。配列はそのままでは入らないので JSON.stringify を通し、読むときに JSON.parse で戻します。読めなかったときに空の配列を返しておけば、以降の処理は「まだ 1 件も無い」ときと同じに書けます。

JavaScript

try { const saved = localStorage.getItem("tags"); const parsed = saved === null ? [] : JSON.parse(saved); console.log(Array.isArray(parsed) ? parsed : []); } catch (error) { console.log([]); }

Array.isArray で確かめているのは、保存された文字列が壊れていたり、別の形が入っていたときの用心です。

呼ぶ順番は、読み出してから描く、です。配列を先に用意し、最後に描き直す関数を 1 回呼べば、前回のメモが並んだ状態でページが始まります。配列を受ける変数は const でかまいません。push や splice で中身は変えても、入れ物そのものを別の配列に取り替えることはないからです。

よくある間違い

  • 保存を書き忘れる場所がある — 追加のときだけ保存して削除で忘れると、消したはずのメモがリロードで復活します。配列を変える行の直後は必ず保存、と手癖にしてください
  • 描き直す前に空にし忘れる — 追加するたびに一覧が二重、三重に増えていきます。関数の 1 行目で textContent を空にします
  • 空のまま追加できてしまう — trim() を通さないと、スペースだけのメモが作れてしまいます。読んだ直後に落とします

課題

  1. 作品とお問い合わせのあいだにメモの section を足す。入力欄 memo-input、追加ボタン memo-add、案内文 memo-message、一覧 memo-list、件数 memo-count を id で用意する
  2. メモの配列を持ち、loadMemos で localStorage から読み戻す。読めないときや保存が無いときは空の配列にする
  3. renderMemos 関数で一覧を作り直す。1 件ごとに li と削除ボタンを作り、memo-count に件数を入れる。削除ボタンは splice で 1 件だけ抜く
  4. 追加ボタンを押したら入力欄の値を trim して配列に足し、入力欄を空にして描き直す。空のときは追加せず memo-message に入力をうながす文を出す
  5. 追加と削除のどちらでも、配列を変えたあとに JSON.stringify で保存する

ヒント

描き直しの最初に `memoList.textContent = "";` を書きます。これが無いと呼ぶたびに一覧が下へ増えていきます

forEach の第 2 引数が配列の何番目かです。削除ボタンの中でその番号を使い、`splice(index, 1)` で 1 件だけ抜きます

件数の表示は `memos.length` から作ります。手で数字を書くと必ずずれます

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

できているか

  • 入力欄 #memo-input がある
  • 一覧 #memo-list がある
  • 空のまま追加すると案内が出る
  • 入力して追加すると一覧に 1 件出る
  • もう 1 件追加すると 2 件になる
  • 削除ボタンを押すと 1 件目だけ消える
  • 残りも消すと 0 件になる
エディタを読み込んでいます