[JavaScript]イベントバッファ&キャプチャ(Capturing)


Eventを勉強している間に、BubblingとCaptureという概念が出てきたので、整理することにしました.

キャプチャ


ウィンドウからイベントが発生した要素にイベントを伝播します.すなわち,イベントがサブ要素に伝播する段階である.実際のコードではあまり使われていませんが、概念的に理解すればいいだけです.

バブル(Bubbling)


イベントが発生した要素からウィンドウにイベントを伝播します.エレメントにイベントが発生すると、エレメントに割り当てられたハンドラが操作され、親エレメントのハンドラが操作されます.このプロシージャは、最上位レベルの親要素に遭遇する前に繰り返し、各要素に割り当てられたハンドルによって操作されます.

発泡現象の例


FORM>DIV>P形式のオーバーラップ構造で、各要素にハンドルが割り当てられています.
<style>
  body * {
    margin: 10px;
    border: 1px solid blue;
  }
</style>

<form onclick="alert('form')">FORM
  <div onclick="alert('div')">DIV
    <p onclick="alert('p')">P</p>
  </div>
</form>
一番奥の<p>をクリックすると、次のようになります.
動作は、
  • <p>に割り当てられたonclickハンドルで行います.
  • 動作は
  • 外面<div>に割り当てられたハンドルで行う.
  • その外部<form>に割り当てられたハンドルで動作します.
  • ドキュメントオブジェクトに遭遇する前に、各要素に割り当てられたonclickプロセッサが操作を実行します.

    ほとんどの活動がバブルになります。


    ここでのキーワードは「ほぼ」です.Focusイベントのように泡立たないイベントもあります.

    event.target


    イベントが正確にどこで発生したかなどの情報を得ることができる.イベント発生の一番奥の要素はtarget要素と呼ばれ、event.targetアクセス可能です.

    event.CurrentTargetとevent。target

  • event.target実際の活動開始の「目標」要素です.泡化しても変わらない.
  • event.currentTargetは現在の要素であり、現在実行中のHandlerが割り当てた要素を参照する.
  • <body>
      <div class="outer">
          <button>Click Me</button>
      </div>
      <script>
        const outer = document.querySelector('.outer');![]
        const button = document.querySelector('button');
    
        outer.addEventListener('click', event => {
          console.log(`outer: ${event.currentTarget}, ${event.target}`);
        });
        button.addEventListener('click', event => {
          console.log(`button1 ${event.currentTarget}, ${event.target}`);
        });
      </script>
    </body>
    上のコードでbuttonをクリックします.コンソールは次のようになります.

    イベントですtarget(すなわち、イベント開始のターゲット要素はHTML ButtonElement)である.CurrentTargetには、.outerのHTML DivElementとHTML ButtonElementが表示されます.

    発泡を止める


    デフォルトでは、イベントオブジェクトのメソッドはイベントであることがわかります.stopPropagation()を使用する方法.

    event.stopPropagation()


    上のコードのbutton to event.stopPropagation()を追加した場合、bundlingはbuttonでのみ発生します.
    button.addEventListener('click', event => {
          console.log(`button1 ${event.currentTarget}, ${event.target}`);
      	  event.stopPropagation()
        });

    event.stopImmediatePropagation()


    event.stopPropagation()は上向きの気泡を止めることができますが、他のハンドルの動きを止めることはできません.
        button.addEventListener('click', event => {
          console.log(`button ${event.currentTarget}, ${event.target}`);
          event.stopPropagation()
        });
        button.addEventListener('click', event => {
          console.log(`button2 ${event.currentTarget}, ${event.target}`);
        });
    同じボタンに適用されるハンドル(コードなど)が上にある場合event.stopPropagation()のみでは動作を停止できません.このときはeventを使用します.stopImmediatePropagation().この方法を使用すると、発泡を停止し、要素に割り当てられた他のプロセッサの動作を阻止できます.

    でも!event.stopPropagation()とevent。stopImmediatePropagation()の使用は危険です。


    もし私が勝手に活動をキャンセルしたら、他の部分は活動を通じてもっと意味のあることをするかもしれないし、他の機能を追加するかもしれないからです.大規模なプロジェクトなどで発生するエラーが発生する可能性があります.したがって,条件文を用いて気泡を防止する方法が望ましい.

    条件文を使用してbundlingを停止する

        outer.addEventListener('click', event => {
          if (event.target !== event.currentTarget) {
            return;
          }
        });
    上のコードのようにeventtargetとevent.currentTargetを使用して条件文を作成すればよい.

    コメントサイトとクラス


    モダンJavaScriptチュートリアル
    Dream Coding Ellyフロントエンド必須ブラウザ101レッスン