[Javascript]イベントのバッファリングとキャプチャ

17068 ワード

イベントバッファ


  • 要素にイベントが発生すると、その要素に割り当てられたハンドラが操作され、次に親要素のハンドラが操作され、最上位の親要素に遭遇するまでハンドラが操作されます.この現象をイベントバッファと呼びます.
  • 、すなわち、特定のスクリーン要素でイベントが発生すると、そのイベントはより高度なスクリーン要素に渡される.
  • 次のコードを見てもっと詳しく知ることができます.
    <body>
    	<div class="one">
    		<div class="two">
    			<div class="three">
    			</div>
    		</div>
    	</div>
    </body>
    var divs = document.querySelectorAll('div');
    divs.forEach(function(div) {
    	div.addEventListener('click', logEvent);
    });
    function logEvent(event) {
    	console.log(event.currentTarget.className);
    }
    3つのdivタグにはclickイベントが登録されており、クリックするとlogEvent関数のコードが実行されます.
    上図に示すように、最低divラベル
    <div class="three"> </div>
    クリックすると、次の結果が得られます.
    three
    two
    one

    なぜdivラベルを1つクリックしただけで3つのイベントが発生したのですか?


    これは、ブラウザがイベントを検出する方法のためです.
    イベントが特定のスクリーン要素で発生すると、ブラウザはイベントを上部のスクリーン要素に伝播します.
    したがって、divラベルに登録されたイベントは、クラス3->two->の順序で実行されます.
    各タグにはイベントが登録されているため、イベントが親要素に転送されたと判断できます.
    ただし、イベントが特定のdivラベルにのみ依存する場合、上記の操作結果は決定されません.

    イベントのキャプチャ



    これは、
  • イベントBubblingとは逆方向のイベント伝播方式である.
  • 特定のイベントが発生した場合、最上位要素bodyラベルでラベルが検索されます.
  • 下部のコードからイベントbundlingとは異なる場所が見つかります.
    var divs = document.querySelectorAll('div');
    divs.forEach(function(div) {
    	div.addEventListener('click', logEvent, {
    		capture: true // default 값은 false
    	});
    });
    function logEvent(event) {
    	console.log(event.currentTarget.className);
    }
    addEventListener()APIでオプションオブジェクトのcapture:trueを設定すると、イベントbundlingと逆方向に移動してイベントが検出されます.
    この場合divラベルが最も低い
    <div class="three"> </div>
    クリックすると、次の結果が得られます.
    one
    two
    three

    イベントをブロックする方法e.stopPropagation()を使用!


    e.stopPropagation()を使用すると、ターゲットをクリックする
  • のイベントのみが発生し、親要素にイベントが伝播することを防止できます.
  • イベントbublingの場合:クリック要素のイベントのみが励起され、イベントの親要素への転送が妨げられます.
  • イベント取得の場合:クリック要素の最上位要素のイベントのみを有効にし、サブ要素にイベントを転送しません.
  • 委任活動も知らなければならない。

  • スクリーンショットとBubblingを利用して、親内部のサブエレメント(複数のエレメント)にそれぞれイベントリスナーを追加するのではなく、共通の親にイベントリスナーを登録してサブエレメントのリスナーを制御する方法.
  • 次のコードで理解してください.
    <h1>오늘의 할 일</h1>
    <ul class="itemList">
    	<li>
    		<input type="checkbox" id="item1">
    		<label for="item1">이벤트 버블링 학습</label>
    	</li>
    	<li>
    		<input type="checkbox" id="item2">
    		<label for="item2">이벤트 캡쳐 학습</label>
    	</li>
    </ul>
    var inputs = document.querySelectorAll('input');
    inputs.forEach(function(input) {
    	input.addEventListener('click', function(event) {
    		alert('clicked');
    	});
    });
    querySelector All()を使用して、画面に存在するすべての入力ボックス要素をインポートし、各入力ボックスの要素にクリックイベントリスナーを追加します.
    ->画面が実行されたら、各リスト項目の入力ボックス(チェックボックス)をクリックすると、警告ウィンドウが表示されます.
    新しいリストアイテムを追加する場合?
    var itemList = document.querySelector('.itemList');
    var li = document.createElement('li');
    var input = document.createElement('input');
    var label = document.createElement('label');
    var labelText = document.createTextNode('이벤트 위임 학습');
    input.setAttribute('type', 'checkbox');
    input.setAttribute('id', 'item3');
    label.setAttribute('for', 'item3');
    label.appendChild(labelText);
    li.appendChild(input);
    li.appendChild(label);
    itemList.appendChild(li);
    新しく追加したリストアイテムの場合、[イベントリスナー]をクリックしても機能しません.クリックイベントリスナーが追加されていないためです.
    では、新しく追加されたリスト項目ごとにアクティビティレンタルを追加しますか?それも違います.
    var itemList = document.querySelector('.itemList');
    itemList.addEventListener('click', function(event) {
    	alert('clicked');
    });
    イベントリスナーを画面上のすべての入力ボックスに追加するのではなく、ボックスの親要素ulラベルを入力します.itemListにイベントリスナーを追加し、サブアイテムで発生したクリックイベント(=イベントbubling)を検出します.
    コードを追加して実行すると、各アイテムをクリックするたびに警告ウィンドウが表示されます(イベントをクリック).
    そのため、リスト項目を追加するたびに、クリック活動の苦労はなくなります.
    出典:板橋隊長yesdoingブログ