js 事件流、事件冒泡、事件捕获、阻止事件的传播

简介: js 事件流、事件冒泡、事件捕获、阻止事件的传播

事件流

js 事件的执行过程分为捕获阶段(由外层节点传播到内层节点)和冒泡阶段(由内层节点传播到外层节点),即先执行捕获阶段的代码,后执行冒泡阶段的代码

事件冒泡

js 事件中的代码默认在冒泡阶段执行,以下图为例,点击box2时,会依次触发box2的点击事件【冒泡阶段执行】、box1的点击事件【冒泡阶段执行】、window的点击事件【冒泡阶段执行】。

  window.addEventListener("click", function (e) {
    if (e.target.id === "box2") {
      console.log("点击box2触发window的click事件");
    } else if (e.target.id === "box1") {
      console.log("点击box1触发window的click事件");
    } else {
      console.log("触发了window的click事件");
    }
  });

  document.getElementById("box1").addEventListener("click", function (e) {
    console.log("触发了box1的click事件");
  });

  document.getElementById("box2").addEventListener("click", function (e) {
    console.log("触发了box2的click事件");
  });

事件捕获

给 addEventListener 函数的第三个参数传入 true ,便会将事件中的代码改为在捕获阶段执行,此时点击box2时,会依次触发window的点击事件【捕获阶段执行】,box2的点击事件【冒泡阶段执行】,box1的点击事件【冒泡阶段执行】。

  window.addEventListener(
    "click",
    function (e) {
      if (e.target.id === "box2") {
        console.log("点击box2触发window的click事件");
      } else if (e.target.id === "box1") {
        console.log("点击box1触发window的click事件");
      } else {
        console.log("触发了window的click事件");
      }
    },
    //改为在捕获阶段执行
    true
  );

  document.getElementById("box1").addEventListener("click", function (e) {
    console.log("触发了box1的click事件");
  });

  document.getElementById("box2").addEventListener("click", function (e) {
    console.log("触发了box2的click事件");
  });

阻止事件的传播

使用

e.stopPropagation()

范例:点击box2时,只触发box2的点击事件,不触发box1和window的点击事件

  window.addEventListener("click", function (e) {
    if (e.target.id === "box2") {
      console.log("点击box2触发window的click事件");
    } else if (e.target.id === "box1") {
      console.log("点击box1触发window的click事件");
    } else {
      console.log("触发了window的click事件");
    }
  });

  document.getElementById("box1").addEventListener("click", function (e) {
    console.log("触发了box1的click事件");
  });

  document.getElementById("box2").addEventListener("click", function (e) {
    console.log("触发了box2的click事件");
    // 阻止事件继续传播
    e.stopPropagation();
  });

实战范例

需求:

  1. 点击box2时,只执行window点击事件中通过点击box2触发window点击事件的代码,不执行box1的点击事件代码
  2. 点击box1时,只执行box1的点击事件代码,不执行window点击事件中通过点击box1触发window点击事件的代码
  window.addEventListener(
    "click",
    function (e) {
      if (e.target.id === "box2") {
        console.log("点击box2触发window的click事件");
        // 阻止事件继续传播
        e.stopPropagation();
      } else if (e.target.id === "box1") {
        return;
        console.log("点击box1触发window的click事件");
      } else {
        console.log("触发了window的click事件");
      }
    },
    true
  );

  document.getElementById("box1").addEventListener("click", function (e) {
    console.log("触发了box1的click事件");
  });

  document.getElementById("box2").addEventListener("click", function (e) {
    console.log("触发了box2的click事件");
  });

目录
相关文章
|
2月前
|
JavaScript 前端开发
js事件队列
js事件队列
|
26天前
|
JavaScript 前端开发
JavaScript 事件
JavaScript 事件
29 2
|
8天前
|
JavaScript 前端开发
JavaScript HTML DOM 事件
JavaScript HTML DOM 事件
14 5
|
8天前
|
监控 JavaScript 前端开发
|
26天前
Nest.js 实战 (十二):优雅地使用事件发布/订阅模块 Event Emitter
这篇文章介绍了在Nest.js构建应用时,如何通过事件/发布-订阅模式使应用程序更健壮、灵活、易于扩展,并简化服务间通信。文章主要围绕@nestjs/event-emitter模块展开,这是一个基于eventemitter2库的社区模块,提供了事件发布/订阅功能,使得实现事件驱动架构变得简单。文章还介绍了如何使用该模块,包括安装依赖、初始化模块、注册EventEmitterModule、使用装饰器简化监听等。最后总结,集成@nestjs/event-emitter模块可以提升应用程序的事件驱动能力,构建出更为松耦合、易扩展且高度灵活的系统架构,是构建现代、响应迅速且具有高度解耦特性的Nest.
|
21天前
|
JavaScript 前端开发
|
27天前
|
存储 JavaScript 前端开发
js事件冒泡和事件委托
事件冒泡是指事件从最内层元素开始逐级向上传播至祖先元素的过程,默认情况下,点击子元素时会先触发自身的事件处理程序,再依次向上触发父元素的处理程序。事件委托则是在父元素上设置事件处理程序,利用事件冒泡机制处理子元素的事件,以此减少内存消耗和提高性能,特别适用于处理大量动态子元素的情况。其区别在于事件冒泡是事件传播机制的一部分,而事件委托是编程技巧,通过在父元素上绑定事件处理程序来简化子元素的事件处理。
17 0
|
3月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
78 2
|
3月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的宠物援助平台附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的宠物援助平台附带文章源码部署视频讲解等
68 4