- Day 39:イベントオブジェクト(前半)
- イベントオブジェクト event とは何か
- event.target とは何か
- 実践:クリックされた要素を判定する
- Step 1:HTMLを用意する
- Step 2:イベントオブジェクトを受け取る
- Step 3:event.target で「誰がクリックされたか」を知る
- Step 4:クリックされた要素がボタンかどうかを判定する
- Step 5:data属性から“ボタンの意味”を取り出す
- Step 6:クリックされたボタンに応じてメッセージを表示する
- 完成コード(コメント付き)
- event.target を使うメリット
- セキュリティ・安全性の観点からの補足
- Day 39 前半 練習用テンプレート
- Day 39 前半のまとめ
- Day 39:イベントオブジェクト(後半)
- イベント委譲という考え方
- 実践:イベント委譲でクリックされた要素を判定する
- ネストされた要素の中で event.target がどこを指すか
- 実践:closest() で「一番近い .card を探す」
- カードの情報を取り出してメッセージに表示する
- 完成コード(イベント委譲+closest+event.target)
- 条件付きクリック判定:特定のボタンだけ反応させる
- セキュリティ・安全性の観点からの補足
- Day 39 後半 練習用テンプレート
- Day 39 後半のまとめ
Day 39:イベントオブジェクト(前半)
「event と event.target で“誰がクリックされたか”を正しく理解する」
Day 39前半では、JavaScriptのイベント処理の中でもとても重要な イベントオブジェクト を扱います。 これまで addEventListener('click', ...) のようにイベントを使ってきましたが、 今日は一歩踏み込んで 「eventとは何か」「event.targetとは何か」 を理解していきます。
実践テーマは 「クリックされた要素を判定」 です。 複数の要素がある中で、「どの要素がクリックされたのか」をコードで判定できるようになることを目指します。
イベントオブジェクト event とは何か
イベントが起きたときに渡される“情報のかたまり”
addEventListener でイベント処理を書くとき、 次のような形をよく見かけると思います。
element.addEventListener('click', function (event) {
// ここで event を使う
});
JavaScriptこの event が イベントオブジェクト です。
イベントオブジェクトは、
「クリックされた」「キーが押された」「フォームが送信された」などの “イベントが起きたときの情報”をまとめて持っているオブジェクト
だとイメージすると分かりやすいです。
例えば、クリックイベントなら、
- どの要素がクリックされたか
- どの座標でクリックされたか
- どのボタン(左クリック・右クリックなど)だったか
といった情報が event の中に入っています。
イベントハンドラの引数として渡される
イベントオブジェクトは、 イベントハンドラ(イベントが起きたときに呼ばれる関数)の 引数 として渡されます。
element.addEventListener('click', function (event) {
console.log(event); // イベントオブジェクトの中身を確認できます
});
JavaScriptここで event という名前は慣例的なものなので、 e や ev など、別の名前にしても構いません。
element.addEventListener('click', function (e) {
console.log(e);
});
JavaScriptただし、初心者のうちは event という名前で統一しておく と、 「これはイベントオブジェクトだな」とすぐに分かるのでおすすめです。
event.target とは何か
「実際に操作された要素」を指すプロパティ
event の中でも、特に重要なのが event.target です。
event.target は、
「そのイベントを引き起こした“実際の要素”」
を指すプロパティです。
クリックイベントの場合、
- クリックされた要素そのもの
- つまり「どのタグがクリックされたか」を表す
という意味になります。
具体的なイメージ
例えば、次のようなHTMLがあるとします。
<button id="btn1">ボタン1</button>
<button id="btn2">ボタン2</button>
<button id="btn3">ボタン3</button>
これらをまとめてクリック判定したいとき、 それぞれにイベントを付ける代わりに、 親要素にイベントを付けて event.target で「どれがクリックされたか」を判定することができます。
document.addEventListener('click', function (event) {
console.log('クリックされた要素:', event.target);
});
JavaScriptこのとき、
- ボタン1をクリック →
event.targetは<button id="btn1">... - ボタン2をクリック →
event.targetは<button id="btn2">...
というように、 クリックされた要素そのもの が event.target に入ります。
実践:クリックされた要素を判定する
目標イメージ
- ページ上に複数のボタンやリンクがある。
- どれがクリックされたかを
event.targetで判定する。 - クリックされた要素に応じてメッセージを変える。
これを、ステップバイステップで作っていきます。
Step 1:HTMLを用意する
まずは、複数のボタンを用意します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Day 39 前半:イベントオブジェクトとクリック判定</title>
</head>
<body>
<h1>クリックされた要素を判定する</h1>
<section id="buttonArea">
<button data-name="apple">りんごボタン</button>
<button data-name="orange">みかんボタン</button>
<button data-name="banana">バナナボタン</button>
</section>
<p id="message">どのボタンがクリックされたか表示します。</p>
<script>
// ここにJavaScriptを書いていきます
</script>
</body>
</html>
ポイントは、
sectionにid="buttonArea"を付けて、 その中のボタンをまとめて扱えるようにしていること。- 各ボタンに
data-name属性を付けて、 「りんご」「みかん」「バナナ」といった識別情報を持たせていること。
data-* 属性は、 「HTML要素に任意のデータを持たせるための仕組み」 で、 JavaScriptから簡単に参照できます。
Step 2:イベントオブジェクトを受け取る
次に、buttonArea にクリックイベントを付けます。
// ▼ ボタンをまとめているエリアを取得します
const buttonAreaElement = document.getElementById('buttonArea');
// ▼ メッセージ表示用の<p>要素を取得します
const messageElement = document.getElementById('message');
// ▼ buttonArea内でクリックが起きたときの処理
buttonAreaElement.addEventListener('click', function (event) {
console.log('イベントオブジェクト:', event); // 中身を確認してみましょう
});
JavaScriptここで、イベントハンドラの引数 event が、 クリックイベントの情報を持つイベントオブジェクト です。
Step 3:event.target で「誰がクリックされたか」を知る
次に、event.target を使って、 「どの要素がクリックされたか」を判定します。
buttonAreaElement.addEventListener('click', function (event) {
// ▼ クリックされた“実際の要素”を取得します
const clickedElement = event.target;
console.log('クリックされた要素:', clickedElement);
});
JavaScriptここで clickedElement には、
- ボタンがクリックされた場合 → その
<button>要素 - もしボタンの中に別の要素があれば → その内側の要素
が入ります。
Step 4:クリックされた要素がボタンかどうかを判定する
buttonArea の中には、 将来的にボタン以外の要素が入る可能性もあります。
そこで、
「クリックされた要素が
<button>かどうか」
を判定してから処理するようにします。
buttonAreaElement.addEventListener('click', function (event) {
const clickedElement = event.target;
// ▼ クリックされた要素が<button>でなければ何もしません
if (clickedElement.tagName !== 'BUTTON') {
return;
}
console.log('ボタンがクリックされました:', clickedElement);
});
JavaScripttagName は、 要素のタグ名(BUTTON, DIV, SPAN など)を大文字で返すプロパティです。
Step 5:data属性から“ボタンの意味”を取り出す
各ボタンには、次のように data-name 属性を付けました。
<button data-name="apple">りんごボタン</button>
<button data-name="orange">みかんボタン</button>
<button data-name="banana">バナナボタン</button>
この data-name は、 JavaScriptから次のように取得できます。
const fruitName = clickedElement.dataset.name;
JavaScriptdataset は、
data-から始まる属性をまとめて扱うためのオブジェクト
で、
data-name→dataset.namedata-user-id→dataset.userId
というように変換されます。
Step 6:クリックされたボタンに応じてメッセージを表示する
ここまでを組み合わせて、 「どのボタンがクリックされたか」をメッセージに表示します。
buttonAreaElement.addEventListener('click', function (event) {
const clickedElement = event.target;
// ▼ ボタン以外がクリックされた場合は何もしません
if (clickedElement.tagName !== 'BUTTON') {
return;
}
// ▼ data-name 属性から“ボタンの意味”を取り出します
const fruitName = clickedElement.dataset.name;
// ▼ メッセージを更新します
messageElement.textContent = `「${fruitName}」ボタンがクリックされました。`;
});
JavaScript例えば、
- りんごボタン → 「appleボタンがクリックされました。」
- みかんボタン → 「orangeボタンがクリックされました。」
というように表示されます。
完成コード(コメント付き)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Day 39 前半:イベントオブジェクトとクリック判定</title>
</head>
<body>
<h1>クリックされた要素を判定する</h1>
<!-- ▼ ボタンをまとめているエリア -->
<section id="buttonArea">
<!-- data-name 属性でボタンの意味を持たせています -->
<button data-name="apple">りんごボタン</button>
<button data-name="orange">みかんボタン</button>
<button data-name="banana">バナナボタン</button>
</section>
<!-- ▼ メッセージ表示エリア -->
<p id="message">どのボタンがクリックされたか表示します。</p>
<script>
// ▼ ボタンエリアとメッセージ要素を取得します
const buttonAreaElement = document.getElementById('buttonArea');
const messageElement = document.getElementById('message');
// ▼ buttonArea内でクリックが起きたときの処理
buttonAreaElement.addEventListener('click', function (event) {
// event は「クリックイベントの情報が入ったオブジェクト」です
console.log('イベントオブジェクト:', event);
// ▼ 実際にクリックされた要素を取得します
const clickedElement = event.target;
console.log('クリックされた要素:', clickedElement);
// ▼ クリックされた要素が<button>でなければ何もしません
if (clickedElement.tagName !== 'BUTTON') {
return;
}
// ▼ data-name 属性からボタンの意味を取り出します
const fruitName = clickedElement.dataset.name;
// ▼ メッセージを更新します
messageElement.textContent = `「${fruitName}」ボタンがクリックされました。`;
});
</script>
</body>
</html>
event.target を使うメリット
1. コードがシンプルになる
それぞれのボタンに個別にイベントを付けることもできますが、 event.target を使うと、
- 親要素に1つだけイベントを付ける
- クリックされた要素を
event.targetで判定する
という書き方ができ、コードがシンプルになります。
これは イベント委譲(イベントデリゲーション) と呼ばれるテクニックで、 要素が増えてもイベント処理を増やさずに済むため、 大規模なUIでもよく使われます。
2. 動的に追加された要素にも対応しやすい
前のDayで学んだように、 createElement()+appendChild() で要素を追加することができます。
event.target を使った書き方なら、
- 後から追加されたボタンも
- 同じ親要素の中にあれば
同じイベント処理で扱うことができます。
これは、
「最初からある要素だけでなく、後から増える要素もまとめて扱いたい」
という場面で非常に役立ちます。
セキュリティ・安全性の観点からの補足
イベントオブジェクト自体は、 ブラウザが提供する安全な情報のかたまりです。
ただし、イベント処理の中で、
- ユーザー入力を扱う
- DOMを書き換える
といった操作を行う場合は、 次の点に注意する必要があります。
- ユーザー入力を画面に表示するときは、
textContentを使うinnerHTMLを使うと、入力された文字列がHTMLとして解釈されてしまい、<script>などが実行される危険があります。
event.targetから取得した要素に対して、 不必要にinnerHTMLを書き換えない。
今回のコードでは、 メッセージ表示に textContent を使っているため、 安全にテキストを扱うことができています。
Day 39 前半 練習用テンプレート
最後に、今日の内容をまとめて練習できるテンプレートを紹介します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Day 39 前半:イベントオブジェクト 練習テンプレート</title>
</head>
<body>
<h1>イベントオブジェクトと event.target 練習</h1>
<section id="buttonArea">
<button data-name="apple">りんご</button>
<button data-name="orange">みかん</button>
<button data-name="banana">バナナ</button>
</section>
<p id="message">クリックしたボタンの情報がここに表示されます。</p>
<script>
console.log('--- イベントオブジェクト 練習開始 ---');
const buttonAreaElement = document.getElementById('buttonArea');
const messageElement = document.getElementById('message');
buttonAreaElement.addEventListener('click', function (event) {
console.log('event:', event);
const clickedElement = event.target;
console.log('event.target:', clickedElement);
if (clickedElement.tagName !== 'BUTTON') {
console.log('ボタン以外がクリックされました。処理をスキップします。');
return;
}
const fruitName = clickedElement.dataset.name;
messageElement.textContent = `「${fruitName}」ボタンがクリックされました。`;
console.log('クリック判定結果:', fruitName);
});
console.log('--- イベントオブジェクト 練習テンプレートの準備が完了しました ---');
</script>
</body>
</html>
Day 39 前半のまとめ
Day 39前半では、
- イベントオブジェクト
eventが、 「イベントが起きたときの情報のかたまり」であること。 event.targetが、 「実際に操作された要素(クリックされた要素)」を指すプロパティであること。- 親要素に1つだけイベントを付けて、
event.targetで「どのボタンがクリックされたか」を判定するテクニックを学んだこと。 - ユーザー入力やDOM操作を行うときに、
textContentを使って安全性を意識すること。
を整理しました。
この「event と event.target を理解する」ステップは、 次のDayで学ぶ イベント伝播(バブリング・キャプチャ) や、 より高度なイベント設計の土台になります。
今日のコードを何度か書き直しながら、
「イベントが起きたとき、ブラウザはどんな情報を渡してくれているのか」
を意識して練習していくことで、 イベント処理を“感覚ではなく、構造として理解する”力が育っていきます。
Day 39:イベントオブジェクト(後半)
「event と event.target を“使いこなしている側”になるクリック判定の実践編」
Day 39後半では、前半で学んだ event と event.target を、 実際の現場でよく使われる形にまで育てていきます。
テーマは同じく 「クリックされた要素を判定」 ですが、 後半では次のようなポイントを意識して深掘りしていきます。
- 親要素に1つだけイベントを付ける「イベント委譲」
- ネストされた要素の中で、
event.targetがどこを指すか - クラス名や data 属性を使った「条件付きクリック判定」
「なんとなく動く」から一歩進んで、 「意図を持って設計されたイベント処理」 を書けるようになることを目指します。
イベント委譲という考え方
たくさんの要素にイベントを付けると何が起きるか
例えば、10個のボタンがあるとします。
<button>ボタン1</button>
<button>ボタン2</button>
...
<button>ボタン10</button>
これらすべてに対して、
button1.addEventListener('click', ...);
button2.addEventListener('click', ...);
// ...
button10.addEventListener('click', ...);
JavaScriptとイベントを付けていくと、
- コード量が増える
- 後からボタンが増えたときに、またイベントを追加しないといけない
- 管理が大変になる
という問題が出てきます。
親要素に1つだけイベントを付ける「イベント委譲」
そこで登場するのが イベント委譲(Event Delegation) です。
考え方はシンプルで、
「たくさんの子要素にイベントを付ける代わりに、 親要素に1つだけイベントを付けて、
event.targetで“どの子がクリックされたか”を判定する」
というものです。
これにより、
- イベントリスナーの数が減る
- 後から追加された子要素にも自動的に対応できる
- コードがシンプルになる
というメリットがあります。
実践:イベント委譲でクリックされた要素を判定する
HTML:カード一覧を用意する
ボタンではなく「カード」を例にしてみます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Day 39 後半:イベント委譲でクリック判定</title>
<style>
.card-list {
display: flex;
gap: 16px;
}
.card {
border: 1px solid #ccc;
padding: 8px;
width: 150px;
cursor: pointer;
}
.card-title {
font-weight: bold;
}
.card-body {
font-size: 14px;
}
</style>
</head>
<body>
<h1>カード一覧(クリックされたカードを判定)</h1>
<section id="cardList" class="card-list">
<article class="card" data-id="1">
<h2 class="card-title">カード1</h2>
<p class="card-body">これはカード1の説明です。</p>
</article>
<article class="card" data-id="2">
<h2 class="card-title">カード2</h2>
<p class="card-body">これはカード2の説明です。</p>
</article>
<article class="card" data-id="3">
<h2 class="card-title">カード3</h2>
<p class="card-body">これはカード3の説明です。</p>
</article>
</section>
<p id="message">クリックされたカードの情報をここに表示します。</p>
<script>
// ここにJavaScriptを書いていきます
</script>
</body>
</html>
ポイントは、
- 親要素として
id="cardList"を持つ<section>があること - 各カードが
.cardクラスを持つ<article>であること - 各カードに
data-id属性でIDを持たせていること
です。
JavaScript:親要素にだけイベントを付ける
// ▼ 親要素(カード一覧)を取得します
const cardListElement = document.getElementById('cardList');
// ▼ メッセージ表示用の<p>要素を取得します
const messageElement = document.getElementById('message');
// ▼ cardList内でクリックが起きたときの処理
cardListElement.addEventListener('click', function (event) {
// event は「クリックイベントの情報が入ったオブジェクト」です
console.log('event:', event);
// ▼ 実際にクリックされた要素を取得します
const clickedElement = event.target;
console.log('event.target:', clickedElement);
});
JavaScriptここまでは前半と同じですが、 後半ではここから 「カードを特定する」 ところまで踏み込みます。
ネストされた要素の中で event.target がどこを指すか
カードのどこをクリックしても「カード」として扱いたい
カードの中には、
- タイトル(
<h2>) - 説明文(
<p>)
など、複数の要素が入っています。
ユーザーがクリックする場所は、
- タイトル部分
- 説明文部分
- カードの余白部分
など、バラバラです。
しかし、アプリとしては、
「カードのどこをクリックしても、そのカードがクリックされた」
とみなしたいことが多いです。
event.target は「一番内側の要素」を指す
クリックイベントでは、
- タイトルをクリック →
event.targetは<h2 class="card-title">... - 説明文をクリック →
event.targetは<p class="card-body">... - カードの余白をクリック →
event.targetは<article class="card">...
というように、 「一番内側の要素」 が event.target になります。
そのため、
「クリックされたカード(
<article class="card">)を知りたい」
場合は、 event.target から親要素をたどっていく必要があります。
実践:closest() で「一番近い .card を探す」
closest() とは何か
closest() は、DOM要素のメソッドで、
「自分自身から親方向にたどっていき、 指定したセレクタにマッチする一番近い要素を返す」
というものです。
例えば、
const cardElement = clickedElement.closest('.card');
JavaScriptとすると、
clickedElementが.card自身なら → その要素clickedElementが.cardの中の<h2>や<p>なら → 親の.card要素.cardの外側なら →null
が返ってきます。
closest() を使って「クリックされたカード」を特定する
cardListElement.addEventListener('click', function (event) {
const clickedElement = event.target;
// ▼ クリックされた要素から、一番近い .card 要素を探します
const cardElement = clickedElement.closest('.card');
// ▼ .card の外側がクリックされた場合は何もしません
if (!cardElement) {
return;
}
console.log('クリックされたカード要素:', cardElement);
});
JavaScriptこれで、
- タイトルをクリックしても
- 説明文をクリックしても
- カードの余白をクリックしても
常に「そのカードの <article class="card">」を取得できます。
カードの情報を取り出してメッセージに表示する
data-id からカードIDを取得する
各カードには data-id 属性があります。
<article class="card" data-id="1">...</article>
これは、JavaScriptから次のように取得できます。
const cardId = cardElement.dataset.id;
JavaScriptカードタイトルを取得する
カードのタイトルは <h2 class="card-title"> です。
const titleElement = cardElement.querySelector('.card-title');
const titleText = titleElement.textContent;
JavaScriptquerySelector() は、
「その要素の中から、指定したCSSセレクタにマッチする最初の要素を返す」
メソッドです。
メッセージを更新する
これらを組み合わせて、 「どのカードがクリックされたか」をメッセージに表示します。
cardListElement.addEventListener('click', function (event) {
const clickedElement = event.target;
const cardElement = clickedElement.closest('.card');
if (!cardElement) {
return;
}
const cardId = cardElement.dataset.id;
const titleElement = cardElement.querySelector('.card-title');
const titleText = titleElement.textContent;
messageElement.textContent = `カードID: ${cardId}(${titleText})がクリックされました。`;
});
JavaScript完成コード(イベント委譲+closest+event.target)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Day 39 後半:イベント委譲でクリックされた要素を判定</title>
<style>
.card-list {
display: flex;
gap: 16px;
}
.card {
border: 1px solid #ccc;
padding: 8px;
width: 150px;
cursor: pointer;
}
.card-title {
font-weight: bold;
margin-bottom: 4px;
}
.card-body {
font-size: 14px;
}
</style>
</head>
<body>
<h1>カード一覧(クリックされたカードを判定)</h1>
<section id="cardList" class="card-list">
<article class="card" data-id="1">
<h2 class="card-title">カード1</h2>
<p class="card-body">これはカード1の説明です。</p>
</article>
<article class="card" data-id="2">
<h2 class="card-title">カード2</h2>
<p class="card-body">これはカード2の説明です。</p>
</article>
<article class="card" data-id="3">
<h2 class="card-title">カード3</h2>
<p class="card-body">これはカード3の説明です。</p>
</article>
</section>
<p id="message">クリックされたカードの情報をここに表示します。</p>
<script>
// ▼ 親要素(カード一覧)とメッセージ要素を取得します
const cardListElement = document.getElementById('cardList');
const messageElement = document.getElementById('message');
// ▼ cardList内でクリックが起きたときの処理
cardListElement.addEventListener('click', function (event) {
// event は「クリックイベントの情報が入ったオブジェクト」です
console.log('event:', event);
// ▼ 実際にクリックされた一番内側の要素
const clickedElement = event.target;
console.log('event.target:', clickedElement);
// ▼ クリックされた要素から、一番近い .card 要素を探します
const cardElement = clickedElement.closest('.card');
// ▼ .card の外側がクリックされた場合は何もしません
if (!cardElement) {
console.log('カード以外がクリックされました。処理をスキップします。');
return;
}
// ▼ カードIDとタイトルを取得します
const cardId = cardElement.dataset.id;
const titleElement = cardElement.querySelector('.card-title');
const titleText = titleElement.textContent;
// ▼ メッセージを更新します
messageElement.textContent = `カードID: ${cardId}(${titleText})がクリックされました。`;
console.log('クリックされたカード:', { id: cardId, title: titleText });
});
</script>
</body>
</html>
条件付きクリック判定:特定のボタンだけ反応させる
カードの中に「詳細ボタン」と「削除ボタン」がある場合
もう少し現場寄りの例として、 カードの中に「詳細を見る」ボタンと「削除」ボタンがあるケースを考えてみます。
<article class="card" data-id="1">
<h2 class="card-title">カード1</h2>
<p class="card-body">これはカード1の説明です。</p>
<button class="detail-button">詳細を見る</button>
<button class="delete-button">削除</button>
</article>
このとき、
- カードのどこをクリックしても「カードクリック」として扱いたい
- ただし、「削除」ボタンは別の処理をしたい
というように、 クリックされた要素の種類によって処理を変えたい 場面が出てきます。
className でクリックされた要素の種類を判定する
cardListElement.addEventListener('click', function (event) {
const clickedElement = event.target;
// ▼ 削除ボタンがクリックされた場合
if (clickedElement.classList.contains('delete-button')) {
const cardElement = clickedElement.closest('.card');
const cardId = cardElement.dataset.id;
alert(`カードID: ${cardId} を削除します。(仮)`);
return;
}
// ▼ 詳細ボタンがクリックされた場合
if (clickedElement.classList.contains('detail-button')) {
const cardElement = clickedElement.closest('.card');
const cardId = cardElement.dataset.id;
alert(`カードID: ${cardId} の詳細を表示します。(仮)`);
return;
}
// ▼ それ以外(カード本体のクリック)は、カードクリックとして扱う
const cardElement = clickedElement.closest('.card');
if (!cardElement) {
return;
}
const cardId = cardElement.dataset.id;
const titleText = cardElement.querySelector('.card-title').textContent;
messageElement.textContent = `カードID: ${cardId}(${titleText})がクリックされました。`;
});
JavaScriptここでは、
event.targetからクリックされた要素を取得classList.contains()でクラス名を判定- 要素の種類に応じて処理を分岐
という流れになっています。
セキュリティ・安全性の観点からの補足
イベントオブジェクトと event.target を使うと、 ユーザーの操作に応じて柔軟にDOMを操作できます。
ただし、その分だけ、
- ユーザー入力を画面に表示するとき
- DOMを書き換えるとき
には、次の点に注意する必要があります。
- ユーザー入力を表示するときは、必ず
textContentを使うinnerHTMLを使うと、入力された文字列がHTMLとして解釈されてしまい、<script>などが実行される危険があります。
event.targetから取得した要素に対して、 不必要にinnerHTMLを書き換えない。
今回のコードでは、 カードタイトルやメッセージ表示に textContent を使っているため、 安全にテキストを扱うことができています。
Day 39 後半 練習用テンプレート
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Day 39 後半:イベントオブジェクト 総合練習テンプレート</title>
<style>
.card-list {
display: flex;
gap: 16px;
}
.card {
border: 1px solid #ccc;
padding: 8px;
width: 180px;
cursor: pointer;
}
.card-title {
font-weight: bold;
margin-bottom: 4px;
}
.card-body {
font-size: 14px;
margin-bottom: 8px;
}
.detail-button,
.delete-button {
margin-right: 4px;
}
</style>
</head>
<body>
<h1>Day 39 後半:event と event.target 総合練習</h1>
<section id="cardList" class="card-list">
<article class="card" data-id="1">
<h2 class="card-title">カード1</h2>
<p class="card-body">カード1の説明テキストです。</p>
<button class="detail-button">詳細を見る</button>
<button class="delete-button">削除</button>
</article>
<article class="card" data-id="2">
<h2 class="card-title">カード2</h2>
<p class="card-body">カード2の説明テキストです。</p>
<button class="detail-button">詳細を見る</button>
<button class="delete-button">削除</button>
</article>
</section>
<p id="message">ここにクリック結果が表示されます。</p>
<script>
console.log('--- Day 39 後半 総合練習開始 ---');
const cardListElement = document.getElementById('cardList');
const messageElement = document.getElementById('message');
cardListElement.addEventListener('click', function (event) {
const clickedElement = event.target;
console.log('event.target:', clickedElement);
// ▼ 削除ボタンがクリックされた場合
if (clickedElement.classList.contains('delete-button')) {
const cardElement = clickedElement.closest('.card');
const cardId = cardElement.dataset.id;
alert(`カードID: ${cardId} を削除します。(仮処理)`);
console.log('削除ボタンがクリックされました:', cardId);
return;
}
// ▼ 詳細ボタンがクリックされた場合
if (clickedElement.classList.contains('detail-button')) {
const cardElement = clickedElement.closest('.card');
const cardId = cardElement.dataset.id;
alert(`カードID: ${cardId} の詳細を表示します。(仮処理)`);
console.log('詳細ボタンがクリックされました:', cardId);
return;
}
// ▼ それ以外はカードクリックとして扱います
const cardElement = clickedElement.closest('.card');
if (!cardElement) {
console.log('カード以外がクリックされました。処理をスキップします。');
return;
}
const cardId = cardElement.dataset.id;
const titleText = cardElement.querySelector('.card-title').textContent;
messageElement.textContent = `カードID: ${cardId}(${titleText})がクリックされました。`;
console.log('カードクリック:', { id: cardId, title: titleText });
});
console.log('--- Day 39 後半 総合練習テンプレートの準備が完了しました ---');
</script>
</body>
</html>
Day 39 後半のまとめ
Day 39後半では、
eventとevent.targetを使って、 親要素に1つだけイベントを付ける「イベント委譲」を体験したこと。- ネストされた要素の中で、
event.targetが「一番内側の要素」を指すことを理解し、closest()で「本当に扱いたい要素(カード)」を特定するテクニックを学んだこと。 - クラス名や data 属性を使って、 「クリックされた要素の種類に応じて処理を分岐する」設計を練習したこと。
- DOM操作とユーザー入力の扱いにおいて、
textContentを使って安全性を意識し続けたこと。
を整理しました。
この「event と event.target を意図を持って使いこなす」感覚は、 ボタン群、カード一覧、メニュー、タブUIなど、 多くのインタラクティブなUIでそのまま活かせます。
今日のコードを何度か書き直しながら、
「ユーザーがどこをクリックしたときに、どんな情報を取り出して、どんな処理をしたいのか」
を自分なりに言語化して設計していくことで、 イベント処理が“ただのテクニック”ではなく、 「ユーザー体験を形にする道具」として見えてくるようになります。
