10-2. 演習問題
問題1:選択問題
Section titled “問題1:選択問題”1-1. JavaScript で document.querySelector('#book-form') を使う主な目的として最も適切なのはどれか。
- A. HTML 上のフォーム要素を取得して操作するため
- B. CSS ファイルを自動生成するため
- C. ブラウザを自動で再起動するため
解答と解説
正解:A. HTML 上のフォーム要素を取得して操作するため
- A が正しい。
querySelectorは CSS セレクタで要素を取得するための基本メソッドである。 - B は誤り。CSS 自動生成の機能ではない。
- C は誤り。ブラウザ再起動のような役割は持たない。
DOM 操作は「まず要素をつかむ」ことから始まる。
1-2. submit イベントで event.preventDefault() を呼ぶ主な理由として最も適切なのはどれか。
- A. フォーム送信によるページ再読み込みを止め、JavaScript だけで画面更新したいから
- B. 文字列を自動で数値に変換するため
- C. 削除ボタンの色を変えるため
解答と解説
正解:A. フォーム送信によるページ再読み込みを止め、JavaScript だけで画面更新したいから
- A が正しい。フォームはそのままだと再読み込みされるため、SPA 的な振る舞いをしたいときは止める必要がある。
- B は誤り。数値変換は
Number()など別の処理で行う。 - C は誤り。ボタンの色は CSS の役割である。
再読み込みが起きると、せっかく追加した state も消えてしまう。
1-3. state.books のような配列を持つ主な利点として最も適切なのはどれか。
- A. 画面の元になる正しいデータを 1 か所にまとめられること
- B. CSS を短くできること
- C. HTML を書かなくてよくなること
解答と解説
正解:A. 画面の元になる正しいデータを 1 か所にまとめられること
- A が正しい。state は UI の元データを一元管理する考え方である。
- B は誤り。CSS の短さとは関係しない。
- C は誤り。HTML は依然として必要である。
state があると、表示がおかしいときも「まずデータを見る」という調べ方ができる。
1-4. 削除ボタンに data-book-id="b1" と書いたとき、JavaScript 側で値を読む書き方として最も適切なのはどれか。
- A.
target.dataset.bookId - B.
target.style.bookId - C.
target.className.bookId
解答と解説
正解:A. target.dataset.bookId
- A が正しい。
data-book-idは JavaScript ではdataset.bookIdになる。 - B は誤り。
styleは CSS 情報を扱う場所である。 - C は誤り。
classNameはクラス名文字列であり、data-*属性の読み取りには使わない。
HTML の属性名と JavaScript での読み方の対応を覚えると、イベント処理が書きやすくなる。
1-5. 一覧の行を再描画するたびにイベント設定をやり直したくないときに向いている考え方はどれか。
- A. イベント委譲
- B. メディアクエリ
- C. Flexbox
解答と解説
正解:A. イベント委譲
- A が正しい。親要素に 1 つイベントを置き、押された対象を判定する方法である。
- B は誤り。メディアクエリはレスポンシブ対応の仕組みであり、イベントとは無関係である。
- C は誤り。Flexbox はレイアウト用であり、イベント設定の考え方ではない。
一覧を再描画する UI では、イベント委譲が特に有効である。
1-6. elements.price.value をそのまま使うのではなく Number(elements.price.value) にする主な理由として最も適切なのはどれか。
- A. 価格を文字列ではなく数値として扱いたいから
- B. ボタンをクリック可能にするため
- C. HTML の構造を確認するため
解答と解説
正解:A. 価格を文字列ではなく数値として扱いたいから
- A が正しい。フォーム値は基本的に文字列なので、計算や比較に使うなら数値へ直す必要がある。
- B は誤り。ボタン操作とは関係しない。
- C は誤り。HTML 構造確認は Elements の役割である。
"2800" と 2800 は見た目が似ていても別物であり、型の違いを意識することが重要である。
問題2:穴埋め問題
Section titled “問題2:穴埋め問題”次の文章の空欄を埋めてください。
- JavaScript で画面の元になるデータをまとめて持つ考え方を ( ) と呼ぶことが多い。
- HTML 要素を取得する代表的なメソッドは
document.**( )**である。 - フォーム送信時の標準動作を止めるメソッドは
event.**( )**()である。 data-book-idの値は JavaScript ではdataset.**( )**として読める。- 画面を state から描き直す関数としてよく使う名前は ( ) である。
2800のような価格を計算しやすくするには、文字列から ( ) へ変換する必要がある。
解答と解説
- state
- querySelector
- preventDefault
- bookId
- render
- 数値
- state は画面の元になるデータの置き場である。
querySelectorは要素取得の基本である。preventDefaultは submit の既定動作を止める。data-book-idはdataset.bookIdと対応する。renderという名前は「描き直す関数」であることを読み手へ伝えやすい。- 数値変換は集計や比較の正しさに直結する。
問題3:記述問題
Section titled “問題3:記述問題”3-1. 「ユーザー操作 → state 更新 → render()」という流れが、なぜ DOM 操作の学習で重要なのか説明してください。
解答と解説
3-1. 例
ユーザー操作のたびにいきなり DOM を直接触るだけだと、現在の正しいデータがどこにあるか分からなくなる。そこで、まず state を更新し、その state を元に render() で画面を描き直すようにすると、データと表示の関係が明確になる。これにより、バグが起きたときも「state が壊れているのか」「描画処理が壊れているのか」を切り分けやすい。
3-2. フォームの値を読み取る関数と、DOM を描画する関数を分ける利点を説明してください。
解答と解説
3-2. 例
フォーム値を読む関数と描画関数を分けると、役割が整理される。読み取り関数は「入力欄から値を集めること」、描画関数は「state を画面へ反映すること」に集中できるため、修正箇所が分かりやすい。また、同じ描画処理を submit 後や削除後など複数の場面から再利用しやすくなる。
3-3. 一覧の削除ボタンでイベント委譲を使うと、なぜ再描画に強い実装になるのか説明してください。
解答と解説
3-3. 例
一覧のボタンは render() のたびに作り直されることがある。そのため、各ボタンへ個別にイベントを付けると、再描画後にイベントが消えやすい。親の tbody に 1 つだけ click を置き、押された要素が .delete-button かどうかを判定するイベント委譲を使えば、行が描き直されても同じロジックが使える。これが再描画に強い理由である。
3-4. 「一覧に行が増えない」という不具合が起きたとき、Console と Elements をどう使って切り分けるか説明してください。
解答と解説
3-4. 例
まず Console で console.table(state.books) を実行し、追加したい本が state に入っているかを確認する。state に入っているのに画面へ出ていなければ、次に Elements で #book-table-body の中を見て tr が作られているか確認する。DOM にも行がないなら render 処理の問題、DOM はあるのに見た目が変なら CSS 側の問題と切り分けられる。
問題4:ハンズオン
Section titled “問題4:ハンズオン”プレイグラウンドで、state / render / 追加 / 削除 のつながりを確認してみましょう。
DOM を使わず、関数を直接呼び出して console.log で state の変化を観察します。
TODO を 1 つ埋めるたびに実行し、どの段階で出力が変わったかを順番に確認してください。
TODO 1を埋めて実行し、初期データ 1 件がコンソールに出ることを確認するTODO 2を埋めて実行し、追加後に件数が 2 件になりJavaScript入門が先頭に出ることを確認するTODO 3を埋めて実行し、削除後に件数が 1 件に戻ることを確認する
期待する出力例
Section titled “期待する出力例”--- 初期表示 ---登録冊数: 1 - Git実践入門 読了--- TODO 2: 追加後 ---登録冊数: 2 - JavaScript入門 未読 - Git実践入門 読了--- TODO 3: 削除後 ---登録冊数: 1 - JavaScript入門 未読TODO 1〜3 を埋めたら実行して出力を確認しよう解答と解説
TODO 1: render() の考え方
function render() { console.log("登録冊数:", state.books.length); state.books.forEach(b => console.log(" -", b.title, b.status));}render() の役割は state の内容を外へ写し直すことである。件数と一覧を 1 箇所でまとめて出力する形にしておくと、TODO 2・3 で state が変わったときに両方がそろって変化する。
TODO 2: 追加する
state.books.unshift({ id: "b2", title: "JavaScript入門", author: "山田太郎", category: "フロントエンド", price: 2800, status: "未読", memo: "DOM の章を読む" });render();state を先に更新し、そのあとで render() を呼ぶ。これにより「件数だけ増えたが一覧が変わらない」「一覧は変わったが件数が古い」といったズレを防ぎやすい。
TODO 3: 削除する
state.books = state.books.filter(b => b.id !== "b1");render();filter() で「残したい本だけを集め直す」形で削除を書ける。削除後に render() を呼ぶことで、件数と一覧が state と同じ状態にそろう。