[javascript]イベントバッファ、イベントキャプチャ、およびイベント委任


イベントバッファ


一部のスクリーン要素でイベントが発生した場合.
イベントをより上位レベルのスクリーン要素に転送するプロパティ
<body>
  <div class="one">
    <div class="two">
      <div class="three">
      </div>
    </div>
  </div>
</body>
var divs = document.querySelectorAll('div');
divs.forEach(div => {
  div.addEventListener('click', (event) => {
    console.log(event.currentTarget.className);
  });
});
上記のコードの最低divタグ<div class="three"></div>をクリックします.
three
two
one
次の結果を実行します.
スクリーン要素にイベントが発生すると、ブラウザはイベントの上部にあるスクリーン要素にイベントを伝播します.したがって、クラス3をクリックすると、イベントは3-2-1の順序で伝播します.
同様に、イベントが子要素から親要素に伝播する方法をイベントBubblingと呼ぶ.

イベントのキャプチャ


一部のスクリーン要素でイベントが発生した場合.
イベントのトップレベルのタグから、より下位レベルのスクリーン要素に渡されるプロパティ.
<body>
  <div class="one">
    <div class="two">
      <div class="three">
      </div>
    </div>
  </div>
</body>
var divs = document.querySelectorAll('div');
divs.forEach(div => {
  div.addEventListener('click', (event) => {
    console.log(event.currentTarget.className);
  }, { capture: true });
});
アクティブスクリーンショットは、addEventListener()の3番目のオプション値であり、capture: trueに設定されています.
default値はfalseなので、オプションをtrueに設定してこそ、イベントスクリーンショットが開始されます.
上記のコードの最低divタグ<div class="three"></div>をクリックします.
one
two
three
次の結果を実行します.
3番目のクラスをクリックしましたが、イベントキャプチャは一番上のbodyラベルに表示されます.したがって,イベントはbody−1〜2〜3の順に上から下へ伝播する.

event.stopPropagation( )


イベントbubbling、スクリーンショットは使用せず、スクリーン要素のイベントのみを使用します.stopPropagation()を使用すると、上のコードを基準に<div class="three"></div>をクリックすると、3、1が撮れます.

var divs = document.querySelectorAll('div');
divs.forEach(div => {
  div.addEventListener('click', (event) => {
    event.stopPropagation();
    console.log(event.currentTarget.className);   // three
  });
});
var divs = document.querySelectorAll('div');
divs.forEach(div => {
  div.addEventListener('click', (event) => {
    event.stopPropagation();
    console.log(event.currentTarget.className);   // one
  }, { capture: true });
});

委任イベント


親要素の各サブ要素のイベントを制御し、各サブ要素にイベントを貼り付けません.
<h1>점심 추천 리스트</h1>
<ul class="lunchList">
  <li>
    <input type="checkbox" id="lunch1">
    <label for="lunch1">떡볶이</label>
  </li>
  <li>
    <input type="checkbox" id="lunch2">
    <label for="lunch2">짜파게티</label>
  </li>
</ul>
var inputs = document.querySelectorAll('input');
inputs.forEach(input => {
  input.addEventListener('click', (event) => {
    console.log('check!');
  })
});

上のコードの各項目チェックボックスをクリックするたびに、「クリック!」コンソールが撮れます
では、ここでJavaScriptコードを使ってリストアイテムを追加します.
var lunchList = document.querySelector('.lunchList');

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', 'lunch3');
label.setAttribute('for', 'lunch3');
label.appendChild(labelText);
li.appendChild(input);
li.appendChild(label);
lunchList.appendChild(li);

新しく追加された「サムギョプサル」リストには、イベントリスナーがクリックされていません.
理由はinput boxでクリックイベントを追加した場合、リスト項目に「トッポッキ」「ジャージャー麺」の2つがあります.そのため、新しく追加されたリスト項目にはクリックイベントリスナーが登録されていません.
リストアイテムが増えると、各アイテムにイベントリスナーを追加するのは面倒です.
親要素から子要素のイベントを制御するには、イベント委任を使用します.
var lunchList = document.querySelector('.lunchList');
lunchList.addEventListener('click', (event) => {	// Event Delegation
  console.log('check!');
});

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', 'lunch3');
label.setAttribute('for', 'lunch3');
label.appendChild(labelText);
li.appendChild(input);
li.appendChild(label);
lunchList.appendChild(li);

イベントリスナーを最上位のulラベルに追加し、サブエレメントで発生したクリックイベントを検出します.
これは上で学んだ「イベントBubbling」と関係があります.

コメントサイト


https://joshua1988.github.io/web-development/javascript/event-propagation-delegation/