事件捕获和事件冒泡有什么区别

事件冒泡(event bubbling)和事件捕获(event capturing)是指在浏览器中处理事件时,事件传递的两种不同方式。

事件冒泡

事件冒泡是指当一个元素上的事件被触发后,该事件会从该元素开始向上冒泡,依次触发父元素的相同事件,直到冒泡到文档根节点为止。例如,当用户点击一个按钮时,该按钮的点击事件会被触发,然后该事件会向上冒泡,可能触发该按钮的父元素、祖先元素的点击事件。

<!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>

在这个示例中,我们同样有一个包含一个按钮的父元素和一个子元素。不同的是,我们给父元素和子元素分别添加了点击事件处理函数,并在添加事件处理函数时指定了第三个参数为 true,表示使用事件捕获机制。当用户点击按钮时,事件会先在文档根节点上触发,然后向下捕获到父元素和子元素,最终触发子元素的点击事件处理函数。因此,当用户点击按钮时,控制台会分别输出:

Parent element clicked
Child element clicked

事件捕获和事件冒泡有什么区别

事件捕获和事件冒泡是事件传递中的两种不同机制,它们的区别在于事件的传递方向和触发顺序。

事件捕获是指事件从文档根节点开始向下传递,直到到达事件的目标元素,触发目标元素上的事件处理函数。这种机制可以让我们在事件到达目标元素之前截获并处理事件,但在实际应用中很少使用。

事件冒泡是指事件从事件的目标元素开始向上冒泡,直到到达文档根节点,触发父元素、祖先元素上的事件处理函数。这种机制是默认的事件传递机制,也是最常用的一种事件传递机制。

在实际应用中,我们通常使用事件冒泡机制来处理事件,因为这样可以让我们更方便地处理事件。在事件冒泡机制中,我们可以将事件处理函数绑定在目标元素的父元素或祖先元素上,从而实现事件委托和动态绑定事件处理函数等功能。另外,我们也可以通过在事件处理函数中调用 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:事件只会触发一次。
除了以上列出的事件修饰符,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 只有当事件是由当前元素自身触发才触发事件处理函数,@click.once 事件只会触发一次。

猜你喜欢

转载自blog.csdn.net/u013194063/article/details/130284649
今日推荐