[JS]イベントBubbling、キャプチャ、委任


イベントバッファ


イベント・バッファは、特定のイベントが発生すると、そのイベントが親要素に渡されることを意味します.
  • html
  • <div class="div1">
      <div class="div2">
        <div class="div3">click me</div>
      </div>
    </div>
  • js
  • let divs = document.querySelectorAll("div");
    
    divs.forEach((d) => {
      d.addEventListener("click", popUp);
    });
    
    function popUp(event) {
      alert(event.currentTarget.className);
    }
    
    
    すべてのdivにイベントを登録し、divをクリックしてalertウィンドウにクラス名を表示します.click meボタンをクリックすると、div3というalertウィンドウがポップアップするだけかもしれませんが、実際にボタンをクリックすると、
    div3 div2 div1
    3つのalertウィンドウが表示されます.

    どうしてこんなことが起こったの?

  • をクリックしてmeボタンをクリックすると
  • が表示されます.
  • ブラウザはdiv 3に登録されたイベントのコールバック関数を実行します.
  • ブラウザでは、親要素も同じイベント(この例ではclickイベント)に登録されているかどうかを確認します.
  • 同じアクティビティがあれば、そのアクティビティも実行されます.
  • したがって、上記の3つのalertウィンドウが表示されます.
    ここで同じイベントは、実行する動作(コールバック関数)が同じでなければならないというわけではありません.クリックするとイベントがクリックされ、スクロールするとイベントのようなイベントが親要素にスクロールされます.
    これにより、イベントが親要素に渡されることをイベントbublingと呼びます.
    イベントbundlingはDOMがイベントを処理するポーリング方式で、単独で処理しなくても自動的にイベントbundlingが発生します.

    イベントのキャプチャ


    アクティブなスクリーンショットはBubblingとは逆と考えられます.
    親要素から実際のイベントが発生したtargetに移動します.
    divs.forEach((d) => {
      d.addEventListener("click", popUp, true);
    });
    
    上記のコードでは、イベントをクリックするオプションをtrueに設定します.
    (falseエラー)
    [私をクリック]をクリックします.
    div1 div2 div3
    alertウィンドウが順番に表示されます.

    event.StopPropagation()

    event.StopPropagation()という名前のWeb APIを使用すると、イベント伝播は発生せず、イベントが発生する関連要素のイベントのみが発生します.
    function popUp(event) {
      event.stopPropagation();
      alert(event.currentTarget.className);
    }

    委任イベント


    同じイベントが複数のサブエレメントで発生した場合.
    各サブエレメントにイベントを登録するのではなく、親エレメントにイベントを登録します.
    イベント伝播が発生し、サブエレメントにもイベントが発生します.

    リファレンス


    イベント・バッファ、イベントのキャプチャ、およびイベントの委任
    👩🏻‍💻 Event Bubbling & e.stopPropagation() in Javascript, React