DOMイベントの基本~addEventListenerとイベント伝播
by Natsumi Chiba
このページでは、JavaScript のイベント処理の基本である 「addEventListener の仕組み」「イベントの流れ(伝播)」についてまとめています。
イベントは、ユーザーがボタンをクリックしたり、 ページをスクロールしたりしたときに発生します。
JavaScript のイベント理解の土台となる重要な内容です。
【内容】
- addEventListener の仕組み
- 第3引数(capture と bubble)
- イベント伝播
- キャプチャリング
- ターゲットフェーズ
- バブリング
- オプションオブジェクトの紹介({ capture: true })
- getElementById で一度だけDOM検索した方が良い理由
■ document.addEventListener()とは
特定の要素に対して特定のイベントが起こったときに、特定の動作(関数)を行うようにする
対象要素.addEventListener( 種類, 関数, false )
- 第1引数:イベントの種類
- 第2引数:実行させる関数
- 第3引数:falseはイベントの順番を決めるもの。trueかfalseがあるが、通常はfalse。
■ addEventListener の仕組み
【どんなときに使う?】 ・クリックしたとき ・読み込みが終わったとき ・スクロールしたとき など、特定の出来事(イベント)が起きたときに処理を実行したいとき。
【何ができる?】 ・特定の要素にイベントを登録して、反応させることができる。
【書き方】
element.addEventListener("click", function() {
console.log("クリックされました");
});
【特徴】 ・イベント名(click など)、実行する関数、オプション(第3引数)を指定する。
■ 第3引数(capture と bubble)
【どんなときに関係する?】 ・要素が入れ子になっているとき(親と子がある時) ・クリックやイベントの順序が重要なとき
【書き方】
element.addEventListener("click", handler, { capture: true });
【何ができる?】 ・イベントが「どのタイミング」で実行されるかを制御できる。
■ イベント伝播(イベントが伝わる順番)
クリックなどのイベントが、HTMLの階層(親子関係)を上や下へ移動しながら伝わっていく仕組みのこと
イベントは、次の3つの段階を通って実行されます。
- キャプチャリングフェーズ(外側 → 内側)
- ターゲットフェーズ(イベントが発生した要素)
- バブリングフェーズ(内側 → 外側)
ブラウザはこの順番でイベントを伝えていきます。
■ キャプチャリングフェーズ(外 → 内)
【どんなときに使う?】 ・外側の要素で早めに処理したいとき ・イベントの流れをコントロールしたいとき
【説明】 イベントはまずドキュメント(document)から始まり、 html → body → 親 → 子 の順に下へ進んでいきます。
【書き方(capture を true にする)】
element.addEventListener("click", handler, { capture: true });
■ ターゲットフェーズ(イベント発生地点)
【説明】 実際にクリックされた要素(ターゲット)でイベントが実行される瞬間。
例: button をクリックしたら、その button がターゲットになる。
【書き方】
button.addEventListener("click", function() {
console.log("ボタンがクリックされた時の処理");
});
■ バブリングフェーズ(内 → 外)
【どんなときに使う?】 ・親要素でイベントをまとめて管理したいとき ・1つ上の階層に処理を渡したいとき
【説明】 イベントは子 → 親 → body → html → document のように「上」へ戻る。
【書き方】
element.addEventListener("click", handler); // 👈🏻JavaScript のイベントは 基本はバブリング
■ addEventListener のオプションオブジェクト
新しい書き方では、第3引数に true/false ではなく オプションオブジェクトを使うことが推奨されている。
【書き方】
element.addEventListener("click", handler, {
capture: true,
once: false,
passive: false
});
【説明】 ・capture: true → キャプチャリングで実行 ・once: true → 1回だけ実行して自動解除 ・passive: true → スクロールなどで処理を軽くできる
■ getElementById で一度だけ DOM を検索したほうが良い理由
【理由1:処理が速くなる】 DOM を探す処理はコストがあるため、何度も行うと遅くなる。
【理由2:コードの見通しが良くなる】 先に変数に入れておくほうが、何を使っているかわかりやすい。
【理由3:保守しやすい】 同じ要素を何度も検索せずに済むため、修正時の手間が減る。
【例】
const button = document.getElementById("btn");
button.addEventListener("click", function() {
console.log("クリック");
});
■ HTML 要素を使うときの注意点
document.getElementById() で変数に入れてから使うのが良い
→なぜなら、DOM を1回しか探しに行かないので処理が速くなり、読みやすいコードになるから
スクロールやクリックで実行したい処理は関数にして渡しましょう!