イベントの伝播って?

JavaScript

なんかいまいち理解があいまいだったので、イベントの伝播とキャプチャリングフェーズ、ターゲットフェーズ、バブリングフェーズについてまとめてみました。

イベントの伝播とは

childでなんかしらのイベントが発火した場合、イベントが要素間を伝番していきます。すごいテキトーですが↓の画像みたいな感じで。

これをイベントの伝播といい、キャプチャリングフェーズ、ターゲットフェーズ、バブリングフェーズの3つのフェーズに分けることができます。

キャプチャリングフェーズ

キャプチャリングフェーズでは、イベントの伝播が最上位のwindowオブジェクトから順に子要素を伝搬していき、イベントが発生した要素まで同じイベントが順番に伝わっていきます。

ちなみにですが、キャプチャリングフェーズではイベントハンドラやイベントリスナで登録したものに関しては実行されないそうです。

ただ、イベントリスナで登録する際の引数で、 { capture: true }を指定するとキャプチャリングフェーズで実行されます。

ターゲットフェーズ

ここではじめて目的の要素(上記の図の例だとchild)でのイベントが発火します。

バブリングフェーズ

今度はターゲットフェーズで発火した要素から最上位のwindowに向かって同じイベントが発火していきます。{ capture: true }を指定していなければ通常このフェーズで実行されます。逆に{ capture: true }を指定していればこのフェーズでは実行されません。

コード見てみる

キャプチャリングフェーズ

こんな感じのコードでボタンをクリックすると、コンソールには子(ターゲット)以外も出力されると思います。

  <div id="parent">
    親要素(div)
    <button id="child">子要素(button)</button>
  </div>

  <script>
  const parent = document.getElementById('parent');
  const child = document.getElementById('child');

  window.addEventListener('click', () => {
    console.log('window(キャプチャリング)');
  }, { capture: true });

  parent.addEventListener('click', () => {
    console.log('親(キャプチャリング)');
  }, { capture: true });

  child.addEventListener('click', () => {
    console.log('子(ターゲット)');
  });
  </script>

バブリングフェーズ

DOM要素は同じでJSだけ変えたコードです。

  const parent = document.getElementById('parent');
  const child = document.getElementById('child');

  child.addEventListener('click', () => {
    console.log('子(ターゲット)');
  });

  parent.addEventListener('click', () => {
    console.log('親(バブリング)');
  });

  window.addEventListener('click', () => {
    console.log('window(バブリング)');
  });

キャプチャリングフェーズとは違って、ターゲットから最上位のwindowに向かって伝播していくのが分かると思います。

まあ中にはmouseleaveやfocusとか、バブリングが発生しないものもあるそうです。そういうのはキャプチャリングフェーズで終了するみたいです。

コメント

タイトルとURLをコピーしました