イベントの伝搬
【開発環境】
OS:Win11(64ビット)
VSCode1.72.2、
クロム
【イベントフェーズ】
この HTML ページの中の 'start' ボタンがクリックされたときに、クリックイベントがどのように発生し、どのように伝搬していくのかを理解する。
【フェーズの種類】
1、キャプチャリングフェーズ (Capturing phase)
2、ターゲットフェーズ(Target Phase)
3,バブリングフェーズ(Bubbling Phase)
【キャプチャリングフェーズ】
HTML ページの中の 'start' ボタンがクリックされると、一番最上位のオブジェクトである Window オブジェクトでまず click イベントを発生させ、その後 DOM ツリーの構造に沿って伝播する。Document オブジェクト→ html 要素→、 body 要素→ div 要素 →input要素へと、下に向かって行き、発生要素を見つけ出す。
但し、キャプチャリングフェーズの時に発生したイベントは、ほとんどの場合使用されません。要素の属性や要素のプロパティにイベントハンドラを登録した場合でも、addEventListener メソッドでイベントリスナーが登録され場合でも、イベントは実行されない。
【ターゲットフェーズ】
キャプチャリングフェーズのあと、実際にイベントが発生した要素で click イベントが発生する段階をターゲットフェーズと呼びます
ターゲットフェーズでイベントが発生すると、そのイベントに対して登録されたすべてのイベントハンドラやイベントリスナーが呼び出されます。
【バブリングフェーズ】
今度は逆にイベントが発生した要素の親要素である div 要素から、 body 要素、 html 要素、 Document オブジェクト、 Window オブジェクトまで DOM ツリーを上へ向かって順番に click イベントが発生していきます。
バブリングフェーズで発生したイベントも、ごく一部のイベントを除いてそのイベントに対して登録されたイベントハンドラやイベントリスナーが呼び出されます。 focus イベントや blur イベントは Event.bubbles プロパティが false となっているため、バブリングフェーズによるイベントの伝搬を行いません。
サンプルコード
フェーズ.html
外部css:フェーズ.css
外部js:フェーズ.js
それ以外の所をクリックすると、内側の div 要素のイベントリスナーが呼び出されたあと、親要素の外側の div 要素のイベントリスナーが呼び出されます
【キャプチャリングフェーズで発生したイベントでイベントリスナーを呼び出す】
button.addEventListener('click', butotnClick,true);
button.addEventListener('click', butotnClick, {capture: true});
キャプチャリングフェーズでのイベントでイベントリスナーを呼び出すように設定した場合、バブリングフェーズでのイベントではイベントリスナーが呼び出されなくなります。
外部JS:フェーズ2.js
赤字は更新した所
ブラウザを立ち上げ、ボタンをクリックする。
今回は addEventListener メソッドの 3 番目の引数に true を設定しているのでキャプチャリングフェーズのイベントが発生したときにイベントリスナーが呼び出されます。
最初に input 要素をクリックしてみます。すると、まず外側の div 要素、内側の div 要素、最後に実際にイベントが発生した input 要素のイベントリスナーが呼び出されます。
次に内側の div 要素をクリックしてみます。すると外側の div 要素のイベントリスナーが呼び出されたあと、実際にイベントが発生した内側の div 要素のイベントリスナーが呼び出されます。