イベントの動きを正確に制御するには、ブラウザ内部で発生している「3つの伝播フェーズ」を理解する必要があります。W3C標準仕様によるDOMイベントフローの詳細まとめは、以下のステップで厳密に実行されます。
- キャプチャリングフェーズ(捕捉段階):最上位のWindowオブジェクトから出発し、document、html、bodyを経て、イベントが発生したターゲット要素の直前までツリーを垂直に下降していきます。
- ターゲットフェーズ(到達段階):実際にクリックされた要素そのものにイベントが到達し、その要素に直接設定されたハンドラが呼び出されます。
- バブリングフェーズ(浮上段階):ターゲット要素から反転し、親要素、祖父要素へとツリーを駆け上がり、最終的に再びWindowまで到達します。
日常の開発で「親要素の処理が先に動いた」「ボタンの処理が後回しになった」と混乱する根本原因は、イベントリスナーの登録と発火順序の指定にあります。通常の addEventListener('click', handler) は、第3引数を省略するか false を渡しているため、デフォルトでは「バブリングフェーズ」でのみ発火します。もし親要素側で { capture: true } を指定していると、ボタンに到達する前のキャプチャリングフェーズで親の処理が先に実行されます。
両者の境界線を視覚的・論理的に区別しておくことが、意図しない実行順序のバグを根絶する第一歩です。キャプチャリングとの決定的な違いは、「深海へ潜る下降経路」で捕まえるか、「水面へ浮上する上昇経路」で捕まえるかというフェーズの違いに集約されます。