解説
ボタン内の文字を押すと別の要素になる?event.targetとcurrentTargetを比べよう
ボタンのクリックを処理しているのに、取得した要素が内側の文字だった。イベントが起きた対象と、今処理を受け取っている要素を分けてみよう。

ボタンのクリックを処理しているのに、取得した要素が内側の文字だった。イベントが起きた対象と、今処理を受け取っている要素を分けてみよう。
この記事では、ボタンの中にspanを置き、その外側にも枠を用意する。作例はページ内で動き、送信や外部APIへのアクセスは行わないよ。
targetとcurrentTargetの役割
event.targetはイベントの対象となった要素などを表し、currentTargetはそのイベントリスナーが現在取り付けられている対象を表す。単純なクリックでも、内側の要素を押すと同じ値とは限らない。
<div id="panel">
<button id="action" type="button">
<span id="label">ここを押す</span>
</button>
</div>
この例でspanを押すと、targetはlabelになる。一方、buttonに付けたリスナーの中では、currentTargetはactionになるよ。
作例で、文字と余白を押し分ける
- ボタンの中央にある「ここを押す」の文字を押す。
- ボタンのリスナーが表示するtargetとcurrentTargetを見る。
- 文字から離れた、ボタン自身の余白を押す。
- targetがactionへ変わる一方、ボタン側のcurrentTargetはactionのままか確認する。
- リセットで記録を消す。
編集部では、この二つの押し方で、対象がlabel・actionと変わることをブラウザで確認した。作例の黄色い文字欄と、その外の余白を見分けて押してみてね。
外側の枠も受け取るのは、伝わっているから
通常のclickイベントは、対象から祖先へ伝わる段階を持つ。これをバブリングと呼ぶ。作例ではpanelにもリスナーを置いているので、同じ操作の記録が二つ表示される。
| 処理を受け取る場所 | 文字を押したときのtarget | currentTarget |
|---|---|---|
| ボタン | label | action |
| 外側の枠 | label | panel |
同じクリックが伝わっていても、現在処理しているリスナーの場所が違う。すべてのイベントが同じようにバブリングするわけではないので、別の種類へ使うときは仕様を確認しよう。
ボタン自身を使いたいときの例
button.addEventListener('click', (event) => {
const buttonElement = event.currentTarget;
console.log(buttonElement.id);
});
「このボタンを無効にする」など、そのリスナーを付けた要素を扱う意図なら、currentTargetを使うと条件を読みやすくできる。targetが偶然ボタンと同じだった場合だけで、確認を終えないようにしよう。
一方、多数の子要素をまとめて扱うイベント委譲では、targetから意図した対象を探す設計もある。targetを一律にcurrentTargetへ置き換えればよい、という話ではないよ。
リスナーの外へ持ち出すとき
MDNは、currentTargetがイベントハンドラーの呼び出し中に利用できる値であることも説明している。あとで使うなら、必要な要素を処理中に変数へ取り出す。非同期の処理でevent.currentTargetをそのまま読み直す設計には注意したいね。
動かしてみよう:クリックの対象と受け取る場所
文字とボタンの余白を押し分け、二つのリスナーの記録を比べよう。

みんなのコメント 0
感想や、試してみたことを聞かせてね。コメント・返信は承認後に公開されます。
最初のコメントをどうぞ。