ホームページ  >  記事  >  ウェブフロントエンド  >  JS におけるイベント委任の詳細な分析

JS におけるイベント委任の詳細な分析

青灯夜游
青灯夜游転載
2021-02-01 17:50:341765ブラウズ

JS におけるイベント委任の詳細な分析

イベント委任を実行する必要があるのはなぜですか?

最初に小さな関数を実装します。HTML ボタンをクリックした後、メッセージをコンソールに出力します。

この小さな関数を実装するには、ボタンを選択し、addEventListener() メソッドを使用してイベント リスナーをアタッチする必要があります。

<button id="buttonId">Click me</button>

<script>
  document.getElementById(&#39;buttonId&#39;)
    .addEventListener(&#39;click&#39;, () => console.log(&#39;Clicked!&#39;));
</script>

上記単一の要素 (特にボタン上でイベントが実行される方法) をリッスンすることです。

複数のボタンのイベントをリッスンする必要がある場合はどうすればよいでしょうか?可能な実装は次のとおりです:

<div id="buttons">
  <button class="buttonClass">Click me</button>
  <button class="buttonClass">Click me</button>
  <!-- buttons... -->
  <button class="buttonClass">Click me</button>
</div>

<script>
  const buttons = document.getElementsByClassName(&#39;buttonClass&#39;);
  for (const button of buttons) {
    button.addEventListener(&#39;click&#39;, () => console.log(&#39;Clicked!&#39;));
  }
</script>

Codesandbox で どのように動作するかを確認できます

ボタン リストは for (ボタンの定数ボタン) として反復され、新しいリスナーが各ボタンにアタッチされます。さらに、ボタンをリストに追加またはリストから削除した後は、イベント リスナーも手動で削除またはアタッチする必要があります。

もっと良い方法はありますか?

幸いなことに、「イベント委任」パターンを使用すると、複数の要素のイベントをリッスンするのに必要なイベント リスナーは 1 つだけです。

イベント委任によって使用される イベント伝播 メカニズムの詳細。イベント委任がどのように機能するかを理解するには、まずイベント伝播とは何かを理解する必要があります。

イベントの伝播

以下の HTML のボタンをクリックすると:

<html>
  <body>
    <div id="buttons">
      <button class="buttonClass">Click me</button>
    </div>
  </body>
</html>

クリック イベントはいくつの要素で発生しますか?間違いなく、ボタン自体がクリック イベントを受け取ります。そして、すべてのボタンの祖先、document オブジェクトや window オブジェクトも受信されます。

クリック イベントの伝播は 3 つのステージに分かれています:

  • キャプチャ ステージ —— window から、document ルート要素から始まり、イベントはターゲット要素の祖先まで伝播します

  • ターゲット フェーズ - イベントは要素でトリガーされますユーザーによってクリックされました

  • バブリング フェーズ - 最後に、イベントはターゲット要素の先祖を介してルート要素に至るまでバブリングします documentウィンドウ

JS におけるイベント委任の詳細な分析

JS におけるイベント委任の詳細な分析

addEventListener メソッドの 3 番目のパラメータ captureOrOptions :

element.addEventListener(eventType, handler[, captureOrOptions]);

を使用すると、さまざまなステージからイベントをキャプチャできます。

  • リスナーは #captureOrOptions パラメータが欠落しているか、false または {capture:false} ##Events の場合にキャプチャします。ターゲット フェーズとバブル フェーズの
  • パラメータが
  • true または {capture: true} の場合、リスナーは キャプチャ フェーズをリッスンします。 イベント。
次のコードでは、

要素で発生するキャプチャ フェーズのクリック イベントをリッスンします。
document.body.addEventListener(&#39;click&#39;, () => {
  console.log(&#39;Body click event in capture phase&#39;);
}, true);
In this# In ##Codesandbox デモ

では、ボタンをクリックしたときにイベントがコンソール内でどのように伝播するかを確認できます。 それでは、イベント伝播は複数のボタン イベントのキャプチャにどのように役立つのでしょうか?

アルゴリズムは単純です。イベント リスナーをボタンの親にアタッチし、ボタンがクリックされたときのバブリング イベントをキャプチャします。これがイベント委任の仕組みです。

3. イベント デリゲート

イベント デリゲートを使用して、複数のボタンのクリックをキャプチャしましょう:

<div id="buttons"> <!-- Step 1 -->
  <button class="buttonClass">Click me</button>
  <button class="buttonClass">Click me</button>
  <!-- buttons... -->
  <button class="buttonClass">Click me</button>
</div>

<script>
  document.getElementById(&#39;buttons&#39;)
    .addEventListener(&#39;click&#39;, event => { // Step 2
      if (event.target.className === &#39;buttonClass&#39;) { // Step 3
        console.log(&#39;Click!&#39;);
      }
    });
</script>

Codesandbox デモ

を開いて、[Any] ボタンをクリックすると、 'Click!' メッセージがコンソールに記録されます。 イベント委任の考え方は非常にシンプルです。デリゲート イベント リスナーをボタンに直接アタッチする必要はなく、代わりに親リスナー

をデリゲートできます。ボタンをクリックすると、親要素のリスナーが バブリング イベント をキャプチャします (前に述べたイベントの伝播を覚えていますか?)。 イベント委任の使用には 3 つの手順が必要です:

ステップ 1: イベントを監視する要素の親要素を決定します

上記の例では、

はボタンの親要素です。 ステップ 2: イベント リスナーを親要素にアタッチする

#document.getElementById('buttons') .addEventListener('click', handler)

イベント リスナーをアタッチする親要素にリスナーはボタンの親要素にアタッチされます。

ボタン クリック イベントは祖先要素 を介してバブルアップするため (イベントの伝播により)、このイベント リスナーはボタンのクリックにも反応します。

步骤3:用 event.target 选择目标元素

单击按钮时,将会用event 对象参数调用处理函数。属性 event.target  访问在其上调度了事件的元素,在例子中是一个按钮:

// ...
.addEventListener(&#39;click&#39;, event => {
    if (event.target.className === &#39;buttonClass&#39;) {      
        console.log(&#39;Click!&#39;);
    }
});

顺便说明一下,event.currentTarget 指向事件侦听器直接附加到的元素。在例子中,event.currentTarget 是  <div id="buttons">。<p>现在,你可以看到事件委托模式的好处:事件委托仅需要一个事件侦听器,而不必像本文最初那样将侦听器附加到每一个按钮上。</p> <h2 id="item-4">总结</h2> <p>当发生点击事件(或传播的任何其他事件)时:</p> <ul> <li>事件从 <code>windowdocument、根元素向下传播,并经过目标元素的祖先(捕获阶段);

  • 事件发生在目标(目标阶段)上;
  • 最后,事件在目标祖先之间冒出气泡,直到根元素 documentwindow(冒泡阶段)。
  • 该机制称为事件传播

    事件委托是一种有用的模式,因为你可以只需要用一个事件处理程序就能侦听多个元素上的事件。

    使用事件委托需要三个步骤:

    • 确定要监视事件的元素的父级元素

    • 把将事件侦听器附加到父元素

    • event.target 选择目标元素

    更多计算机编程相关知识,请访问:编程视频!!

    以上がJS におけるイベント委任の詳細な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明:
    この記事は51cto.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
    前の記事:angularjsデータバインディングの失敗に対する解決策次の記事:angularjsデータバインディングの失敗に対する解決策

    関連記事

    続きを見る