Skip to content

浏览器事件捕获和冒泡

浏览器事件模型中的过程主要分为三个阶段:捕获阶段、目标阶段、冒泡阶段。

捕获->目标->冒泡

img.png

  • 事件捕获

事件触发顺序: 父元素->子元素

  • 事件冒泡

事件触发顺序: 子元素->父元素

第三个参数

js
window.addEventListener(
  'click',
  function (e) {
    console.log(e.target.nodeName) //指当前点击的元素
    console.log(e.currentTarget.nodeName) //绑定监听事件的元素
  },
  false
) //false为默认为冒泡,true为捕获

阻止事件传播

  • e.stopPropagation()

    阻止冒泡和捕获阶段的传播。

阻止默认行为

  • e.preventDefault()

    可以阻止事件的默认行为发生,默认行为是指:点击 a 标签就转跳到其他页面、拖拽一个图片到浏览器会自动打开、点击表单的提交 按钮会提交表单等等,因为有的时候我们并不希望发生这些事情,所以需要阻止默认行为。

vue 如何阻止事件冒泡与设置捕获行为

  • .stop 阻止冒泡事件
  • .capture 设置捕获事件

默认是冒泡

One
Two
Three. Click Me!!!
Click me to view the code
vue
<template>
  <div @click="callback($event)" class="border border-solid border-red-100">
    <div @click="callback($event)">One</div>
    <div @click="callback($event)" class="border border-solid border-red-200">
      <div @click="callback($event)">Two</div>
      <div @click="callback($event)" class="border border-solid border-red-300">
        <div @click="callback($event)">Three. Click Me!!!</div>
      </div>
    </div>
  </div>
</template>

<script setup>
  const callback = (event) => {
    const ms = (event.timeout = event.timeout + 200 || 0)
    const target = event.currentTarget

    console.log(target)

    setTimeout(function () {
      target.classList.add('highlight')
      setTimeout(function () {
        target.classList.remove('highlight')
      }, 200)
    }, ms)
  }
</script>
<style>
  .highlight {
    background: red;
  }
</style>

捕获 添加.capture

One
Two
Three. Click Me!!!
Click me to view the code
vue
<template>
  <div @click.capture="callback($event)" class="border border-solid border-red-100">
    <div @click.capture="callback($event)">One</div>
    <div @click.capture="callback($event)" class="border border-solid border-red-200">
      <div @click.capture="callback($event)">Two</div>
      <div @click.capture="callback($event)" class="border border-solid border-red-300">
        <div @click.capture="callback($event)">Three. Click Me!!!</div>
      </div>
    </div>
  </div>
</template>

<script setup>
  const callback = (event) => {
    const ms = (event.timeout = event.timeout + 200 || 0)
    const target = event.currentTarget

    console.log(target)

    setTimeout(function () {
      target.classList.add('highlight')
      setTimeout(function () {
        target.classList.remove('highlight')
      }, 200)
    }, ms)
  }
</script>
<style>
  .highlight {
    background: red;
  }
</style>