イベントキャプチャとイベントバブリングの違いは何ですか

イベント バブリングとイベント キャプチャは、ブラウザーでイベントを処理するときの 2 つの異なるイベント配信方法を指します。

イベントバブリング

イベント バブリングとは、要素上のイベントがトリガーされると、そのイベントが要素からバブルアップし、ドキュメントのルート ノードにバブルされるまで、親要素の同じイベントを順番にトリガーすることを意味します。たとえば、ユーザーがボタンをクリックすると、ボタンのクリック イベントがトリガーされ、その後イベントがバブルアップして、ボタンの親要素と祖先要素のクリック イベントがトリガーされる場合があります。

<!DOCTYPE html>
<html>
  <body>
    <div id="parent">
      <button id="child">Click me</button>
    </div>

    <script>
      // 获取父元素和子元素
      var parent = document.getElementById("parent");
      var child = document.getElementById("child");

      // 添加点击事件处理函数
      parent.addEventListener("click", function() {
    
    
        console.log("Parent element clicked");
      });

      child.addEventListener("click", function() {
    
    
        console.log("Child element clicked");
      });
    </script>
  </body>
</html>

この例では、ボタンと子要素を含む親要素があります。親要素と子要素にそれぞれクリック イベント ハンドラーを追加しました。ユーザーがボタンをクリックすると、最初に子要素でイベントがトリガーされ、次にイベントが親要素にバブルアップして、最後に親要素のクリック イベント ハンドラー関数がトリガーされます。したがって、ユーザーがボタンをクリックすると、コンソールはそれぞれ次のように出力します。

Child element clicked
Parent element clicked

イベントキャプチャ

イベント キャプチャとは、要素上のイベントがトリガーされると、そのイベントがドキュメントのルート ノードから下方向にキャプチャされ、要素がキャプチャされるまで子要素の同じイベントが順番にトリガーされることを意味します。たとえば、ユーザーがボタンをクリックすると、ボタンのクリック イベントがトリガーされますが、ボタンのクリック イベントがトリガーされる前に、まずイベントがドキュメントのルート ノードからキャプチャされ、祖先要素とボタンの親要素は、クリック イベントによってトリガーされる場合があります。

<!DOCTYPE html>
<html>
  <body>
    <div id="parent">
      <button id="child">Click me</button>
    </div>

    <script>
      // 获取父元素和子元素
      var parent = document.getElementById("parent");
      var child = document.getElementById("child");

      // 添加点击事件处理函数,指定事件捕获
      parent.addEventListener("click", function() {
    
    
        console.log("Parent element clicked");
      }, true);

      child.addEventListener("click", function() {
    
    
        console.log("Child element clicked");
      }, true);
    </script>
  </body>
</html>

この例には、ボタンを含む親要素と子要素もあります。違いは、親要素と子要素にそれぞれクリック イベント ハンドラーを追加し、イベント ハンドラーの追加時に 3 番目のパラメーターを true に指定して、イベント キャプチャ メカニズムが使用されることを示していることです。ユーザーがボタンをクリックすると、最初にドキュメントのルート ノードでイベントがトリガーされ、次に親要素と子要素に至るまで、最後に子要素のクリック イベント ハンドラー関数がトリガーされます。したがって、ユーザーがボタンをクリックすると、コンソールはそれぞれ次のように出力します。

Parent element clicked
Child element clicked

イベントキャプチャとイベントバブリングの違いは何ですか

イベント キャプチャとイベント バブリングはイベント配信における 2 つの異なるメカニズムであり、その違いはイベント配信の方向とトリガーのシーケンスにあります。

イベント キャプチャとは、イベントがドキュメントのルート ノードからイベントのターゲット要素に到達するまで渡され、ターゲット要素でイベント処理関数がトリガーされることを意味します。このメカニズムにより、イベントがターゲット要素に到達する前にインターセプトして処理できるようになりますが、実際のアプリケーションではほとんど使用されません。

イベント バブリングとは、イベントがイベントのターゲット要素からドキュメントのルート ノードに到達するまでバブルアップし、親要​​素と祖先要素でイベント ハンドラーをトリガーすることを意味します。このメカニズムはデフォルトのイベント配信メカニズムであり、最も一般的に使用されるイベント配信メカニズムです。

実際のアプリケーションでは、通常、イベント バブリング メカニズムを使用してイベントを処理します。これにより、イベントをより便利に処理できるようになります。イベントバブリング機構では、対象要素の親要素や先祖要素にイベント処理関数をバインドすることで、イベント委任やイベント処理関数の動的バインディングなどの機能を実現します。さらに、イベント処理関数で stopPropagation() メソッドを呼び出してイベントのバブリングを停止し、不必要なイベントのトリガーを回避することもできます。

stopPropagation()

イベント ハンドラーで stopPropagation() メソッドを呼び出すと、イベントのバブリングを防ぐことができます。以下は、イベント ハンドラーで stopPropagation() メソッドを呼び出す方法を示すサンプル コードです。

<!DOCTYPE html>
<html>
  <body>
    <div id="parent">
      <button id="child">Click me</button>
    </div>

    <script>
      // 获取父元素和子元素
      var parent = document.getElementById("parent");
      var child = document.getElementById("child");

      // 添加点击事件处理函数,指定事件冒泡
      parent.addEventListener("click", function(event) {
    
    
        console.log("Parent element clicked");
      });

      child.addEventListener("click", function(event) {
    
    
        console.log("Child element clicked");
        event.stopPropagation(); // 阻止事件冒泡
      });
    </script>
  </body>
</html>

この例には、ボタンを含む親要素と子要素もあります。違いは、子要素のクリック イベント ハンドラーで stopPropagation() メソッドを呼び出してイベントのバブリングを防ぐことです。したがって、ユーザーがボタンをクリックすると、親要素のクリック イベント ハンドラーではなく、子要素のクリック イベント ハンドラーのみがトリガーされます。

イベント ハンドラーで stopPropagation() メソッドを呼び出すと、現在のイベントのバブリングのみを防止でき、他のイベントのバブリングは防止できないことに注意してください。イベント バブリングを完全に無効にする必要がある場合は、stopImmediatePropagation() メソッドを使用できます。さらに、イベントのバブリングが防止されると、イベントのデフォルトの動作も防止されるため、preventDefault() メソッドを呼び出してデフォルトの動作をキャンセルする必要があります。

イベントのデフォルトの動作もブロックされるとはどういう意味ですか?

Web 開発では、各要素にはいくつかのデフォルト動作があります。たとえば、<a>リンク (ラベル) のデフォルト動作はリンク先ページにジャンプし、<input type="submit">フォーム送信ボタン ( ) のデフォルト動作はフォームを送信します。 。これらのデフォルトの動作は、ユーザーが何も処理せずに要素を操作すると実行されます。場合によっては、イベント ハンドラーでこれらのデフォルトの動作を防止したい場合は、preventDefault() メソッドを使用できます。

イベント オブジェクトのPreventDefault() メソッドが呼び出されるとき、それはイベントのデフォルトの動作を防止することを意味します。たとえば、フォーム送信ボタンのクリック イベント ハンドラーでPreventDefault() メソッドを呼び出すと、フォームが自動的に送信されなくなります。デフォルトの動作を防止しない場合、フォーム データがサーバーに送信され、ページが更新されます。

デフォルト動作の防止はイベント処理関数内でのみ実行でき、イベント処理関数の最初に呼び出す必要があることに注意してください。イベント ハンドラーのどこかの後でPreventDefault() メソッドが呼び出された場合、デフォルトの動作がすでに実行されている可能性があり、それ以上は防止できません。

vueで

Vue では、イベント配信とイベント処理は、イベント キャプチャやイベント バブリングなど、通常の DOM イベントと同じです。Vue は、開発者がイベント配信とイベント処理を容易に処理できるようにするイベント修飾子も提供します。

Vue でのイベント配信とイベント処理と通常の DOM イベントの違いは、Vue コンポーネント イベントの処理が DOM 要素の親子関係ではなく、コンポーネント ツリーの親子関係に基づいていることです。したがって、Vue コンポーネントのイベント配信とイベント処理は、ネイティブのイベント配信とイベント処理とは若干異なります。

Vue では、イベント配信とイベント処理はデフォルトでイベント バブリング メカニズムに基づいています。つまり、イベントがサブコンポーネントでトリガーされると、イベントは最初にサブコンポーネント内で処理されてから上に進みます。コンポーネント ツリー ルート コンポーネントに到達するまで渡されます。イベント処理関数でevent.stopPropagation()メソッドが呼び出された場合、DOMイベントでのイベントバブリングを防止するのと同様に、イベントが上方に渡され続けることが防止されます。

イベント バブリングに加えて、Vue はイベント キャプチャ メカニズムも提供します。これは、イベント名の後に .capture 修飾子を追加することで有効にできます。たとえば、@click.capture="handleClick" は、イベント キャプチャ メカニズムがオンになっていることを示します。クリック イベントがサブコンポーネントでトリガーされると、イベントは最初にルート コンポーネントで処理され、次にコンポーネントに渡されます。サブコンポーネント内でイベントを内部的に処理します。イベント バブリングとは対照的に、イベント キャプチャはルート コンポーネントから開始され、最初に祖先コンポーネントを処理し、次に子コンポーネントを処理します。

Vue でのイベント修飾子の使用

Vue では、イベント修飾子は開発者がイベント配信とイベント処理を行うための便利な方法です。Vue にはさまざまなイベント修飾子が用意されており、イベント名の後に修飾子を追加することで使用できます。

一般的に使用されるイベント修飾子を次に示します。

.stop: イベントのバブリングを停止します。
.prevent: イベントのデフォルトの動作を防止します。
.capture: イベント キャプチャ メカニズムを使用してイベントを処理します。
.self: イベント ハンドラーは、イベントが現在の要素自体によってトリガーされた場合にのみトリガーされます。
.once: イベントは 1 回だけトリガーされます。
上記のイベント修飾子に加えて、Vue は他のイベント修飾子も提供しており、開発者は特定の状況に応じてイベントを処理する適切なイベント修飾子を選択できます。

Vue でイベント修飾子を使用する方法を示すサンプル コードを次に示します。

<template>
  <div>
    <!-- 阻止事件继续冒泡 -->
    <div @click.stop="handleParentClick">
      <button @click="handleButtonClick">Click me</button>
    </div>

    <!-- 阻止事件的默认行为 -->
    <form @submit.prevent="handleSubmit">
      <input type="text" v-model="inputValue">
      <button type="submit">Submit</button>
    </form>

    <!-- 使用事件捕获机制处理事件 -->
    <div @click.capture="handleParentClick">
      <button @click="handleButtonClick">Click me</button>
    </div>

    <!-- 只有当事件是由当前元素自身触发才触发事件处理函数 -->
    <div @click.self="handleParentClick">
      <div>
        <button @click="handleButtonClick">Click me</button>
      </div>
    </div>

    <!-- 事件只会触发一次 -->
    <button @click.once="handleButtonClick">Click me</button>
  </div>
</template>

<script>
export default {
    
    
  data() {
    
    
    return {
    
    
      inputValue: ''
    }
  },
  methods: {
    
    
    handleParentClick() {
    
    
      console.log('parent clicked')
    },
    handleButtonClick() {
    
    
      console.log('button clicked')
    },
    handleSubmit() {
    
    
      console.log('form submitted')
    }
  }
}
</script>

上記のサンプル コードでは、@click.stop はイベントのバブリングを防止し、@submit.prevent はフォームのデフォルト動作を防止し、@click.capture はイベント キャプチャ メカニズムを有効にし、@click.self はイベントの生成時にのみ機能します。 by the current element イベント ハンドラーは、それ自体によってトリガーされた場合にのみトリガーされ、@click.once イベントは 1 回だけトリガーされます。

おすすめ

転載: blog.csdn.net/u013194063/article/details/130284649