js的dom事件流、事件委托和阻止绑定事件触发

news2024/11/13 10:18:44

主要讲解事件绑定和事件委托,onclick事件和addEventListener的区别

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .father {
      width: 100%;
      height: 300px;
      display: flex;
    }
    .child {
      width: 100px;
      height: 100px;
      background-color: aquamarine;
      margin: 10px;
    }
  </style>
</head>
<body>
  <div class="father">
    <div class="child">1</div>
    <div class="child">2</div>
    <div class="child">3</div>
    <div class="child">4</div>
    <div class="child">5</div>
  </div>
</body>
</html>

示例1:给元素绑定click点击事件

使用onclick

  • 重复绑定点击事件,后面的事件会覆盖前面的事件
<script>
  const element = document.querySelector('.father')
  element.onclick = () => {
    console.log('点击事件1')
  }
  element.onclick = () => {
    console.log('点击事件2')
  }
  // 控制台只会输出:点击事件2
</script>

使用addEventListener

  • 重复绑定点击事件,事件不会被覆盖(类似于发布订阅模式,on中收集的事件存放在数组中,在emit时会遍历执行事件)
  <script>
    const element = document.querySelector('.father')
    element.addEventListener('click', () => {
      console.log('点击事件1')
    })
    element.addEventListener('click', () => {
      console.log('点击事件2')
    })
    // 控制台输出 点击事件1 点击事件2
  </script>

语法:document.addEventListener(event, function, useCapture)
useCapture是可选的布尔值,指定事件是否在捕获或冒泡阶段执行

  • true:事件在捕获阶段执行
  • false:默认值,事件在冒泡阶段执行
element .addEventListener('click', (el) => {
  console.log(el.currentTarget) // 当前绑定事件的元素
  console.log(el.target) // 点击事件触发的元素
})

示例2:默认给每个child元素绑定一个点击事件,现在如果class名包含out-box的元素需要阻止之前绑定的点击事件

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .father {
      width: 100%;
      display: flex;
    }
    .child {
      width: 100px;
      height: 100px;
      background-color: aquamarine;
      margin: 10px;
    }
  </style>
</head>
<body>
  <div class="father">
    <div class="child">1
      <div class="bady-one">1-1
        <div class="yang-two">1-1-1</div>
      </div>
    </div>
    <div class="child">2
      <div class="bady-one out-box">2-1
        <div class="yang-two">2-1-1</div>
      </div>
    </div>
    <div class="child">3
      <div class="bady-one">3-1
        <div class="yang-two">3-1-1</div>
      </div>
    </div>
  </div>
  <script>
    // 示例:默认给每个child元素绑定一个点击事件,现在如果class名包含out-box的元素需要阻止之前绑定的点击事件
    const childElements = document.querySelectorAll('.child')

    childElements.forEach(el => {
      el.addEventListener('click', () => {
        console.log('child点击事件')
      })
    }) // 默认第三个参数为false,在冒泡阶段执行
  </script>

  <script>
	// 处理需求:在捕获阶段找到class名包含out-box的元素,并阻止冒泡
    const fatherElement = document.querySelector('.father')
    fatherElement.addEventListener('click', (el) => {
      const curentElement = el.target // 点击事件触发的元素,如果不是child元素,需要再找到它的class为child的父元素
      const parentElement = getParentElement(curentElement, 'child')
      if (curentElement.classList.toString().indexOf('child') !== -1 || parentElement) {
        if (curentElement?.querySelector('.out-box') || parentElement?.querySelector('.out-box')) {
          // console.log('点击事件')
          el.preventDefault() // 阻止默认行为
          el.stopPropagation() // 阻止冒泡
        }
      }
    }, true) // true点击事件在捕获阶段执行


    // 获取一个元素指定的父元素,使用元素的parentElement属性和while循环向上遍历DOM树,直到找到指定的父元素为止
    function getParentElement(target, className) {
      let parent = target.parentElement
      while (parent) {
        if (parent.classList.toString().indexOf(className) !== -1) {
          return parent
        }
        parent = parent.parentElement
      }
      return null
    }
  </script>
</body>
</html>

DOM事件流
在这里插入图片描述
事件触发经典案例
在这里插入图片描述

解析:前面提到的DOM事件流的执行顺序是先捕获再冒泡,所以dom事件流从外向内捕获过程就是grandma -> monther -> daughter -> baby,而只有monther和daughter设置了useCapture = true,所以在捕获阶段就先将事件处理了,而grandma和baby并未设置useCapture = true,默认是false,而我们又是点击的baby所以首先会先处理baby目标事件,然后再通过冒泡到grandma事件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/448249.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IT项目管理计算题【太原理工大学】

计算题好像也没多少考点&#xff0c;主要就是记公式吧&#xff0c;其他的不想看了&#xff0c;直接考啥看啥&#xff0c;就看两个&#xff1a; ① 根据进度网络图写出时间参数表&#xff0c;ES、EF、LS、LF、TF 以及 FF&#xff0c;关键路径&#xff0c;总工期&#xff1b;② 挣…

volatile 保证内存变量可见性的实现原理解析

目录 volatile 的定义 可见性问题 JMM&#xff08;JavaMemoryModel&#xff09; 保证可见性 现代计算机的内存模型 MESI&#xff08;缓存一致性协议&#xff09; 嗅探 总线风暴 volatile 的两条实现原则 volatile 的定义 Java代码在编译后会编程 Java …

GD(兆易创新)系列FLASH进行FPGA和ZYNQ配置固化相操作

写在前面 本文主要针对使用GD&#xff08;兆易创新&#xff09;系列的FLASH做启动配置片时&#xff0c;遇到的相关问题进行简单整理复盘&#xff0c;避免后人踩坑。 本人操作固化芯片型号为&#xff1a;ZYNQ7045、690T&#xff08;复旦微替代型号V7 690T&#xff09;。 7系列…

02-waf绕过漏洞发现之代理池指纹被动探针

WAF绕过-漏洞发现之代理池指纹被动探针 思维导图 漏洞发现触发WAF点-针对xray工具&#xff0c;awvs工具等 1.扫描速度&#xff08;绕过方法&#xff1a;代理池&#xff0c;延迟&#xff0c;爬虫白名单&#xff09;2.工具指纹&#xff08;绕过方法&#xff1a;特征指纹&#x…

Qt Quick - Container

Qt Quick - Container使用总结 一、概述二、使用容器三、管理当前索引四、容器实现 一、概述 Container 提供容器通用功能的抽象基类。Container是类容器用户界面控件的基本类型&#xff0c;允许动态插入和删除Item。DialogButtonBox, MenuBar, SwipeView, 和 TabBar 都是继承…

测试工程师为什么要关注研发效能?

研发效能中的“研发”&#xff0c;指的是广义的研发团队&#xff0c;包含开发、测试、和研发团队内部的产品经理&#xff08;不包含业务部门的产品经理&#xff09;。测试工程师身处其中&#xff0c;作为研发团队的一员&#xff0c;对于整体的效能如何提升也应该了然于胸。这篇…

【论文写作】如何写科技论文?万能模板!!!(以IEEE会议论文为例)

0. 写在前面 常言道&#xff0c;科技论文犹如“八股文”&#xff0c;有固定的写作模式。本篇博客主要是针对工程方面的论文的结构以及写作链条的一些整理&#xff0c;并不是为了提高或者润色一篇论文的表达。基本上所有的论文&#xff0c;都需要先构思好一些点子&#xff0c;有…

「计算机控制系统」5. 模拟设计法

模拟控制器的离散化 数字PID控制器 Smith预估控制 文章目录 模拟控制器的离散化数值积分法一阶后向差分法一阶前向差分法双线性变换法&#xff08;Tustin&#xff09; 零极点匹配法其他方法 数字PID控制器模拟PID控制器的离散化数字PID的改进PID控制各环节的作用PID参数的整定扩…

win11删除的文件不在回收站原因及找回文件方法

win11是微软最新推出的操作系统&#xff0c;它的外观和功能都有所升级。但是&#xff0c;在使用win11的过程中&#xff0c;有时候你会误删一些重要的文件&#xff0c;而这些文件并没有进入回收站&#xff0c;这该怎么办呢&#xff1f;win11删除的文件不在回收站怎么找回&#x…

[强化学习]学习路线和关键词拾零

强化学习学习方法和路线 学习路线 先从基础教材开始&#xff0c;构建RL的知识框架&#xff0c;熟悉关键名词和公式推导&#xff0c;扩展到Model-Free的Value-Based和Policy-Based方法&#xff0c;同时参考github的代码练习。接下来精读几篇经典论文&#xff0c;如DQN,PPO等。…

Node内置模块 【压缩zlib模块】

文章目录 &#x1f31f;前言&#x1f31f;zlib模块&#x1f31f;关于gzip与deflate&#x1f31f;使用zlib&#x1f31f;压缩与解压缩&#x1f31f;案例&#xff1a;压缩&#x1f31f;案例&#xff1a;解压缩 &#x1f31f;服务端gzip压缩&#x1f31f;HTTP配置&#x1f31f;HTT…

Android Binder图文详解和驱动源码分析

文章目录 前言一、跨进程通讯的过程1. AIDL客户端代码2. AIDL服务端代码3. 通信过程a. 发送请求时序图b. 接收请求时序图 二、Binder一次拷贝1. 发送给Binder驱动的数据2. 一次拷贝示意图 三、Binder驱动源码1. 相关数据结构2. 阅读Binder驱动源码 参考 前言 最近在学习Binder…

Jupyter Notebook的安装与使用

Jupyter Notebook Jupyter Notebook介绍Jupyter Notebook使用安装启动创建文件编写代码和文本常用命令配置文件 Anaconda Jupyter Notebook介绍 Jupyter Notebook是一个基于Web的交互式计算环境&#xff0c;可以让用户以文档形式记录代码、数据分析结果和说明文本&#xff0c;并…

认识ThinkPHP框架

认识ThinkPHP框架 前言一、MVC框架体系二、 ThinkPHP框架文件夹结构三. ThinkPHP下载和基本配置四. ThinkPHP其他东西 前言 ThinkPHP框架是一款非常优秀的PHP框架&#xff0c;是完全由中国人发明的框架 一、MVC框架体系 ThinkPHP框架由MVC框架体系构成&#xff0c;MVC的解释如下…

ubuntu下安装配置grpc

目录 1.准备环境 2.安装protobuf 3.安装cares库 3.安装grpc-1.17.x 1.准备环境 sudo apt-get install pkg-config sudo apt-get install autoconf automake libtool make g unzip sudo apt-get install libgflags-dev libgtest-dev sudo apt-get install clang libc-dev 如…

linux中的vim编辑器

Vim是一款强大的文本编辑器&#xff0c;可以在终端中使用。它有很多优点&#xff0c;比如快速、高效、灵活等&#xff0c;但同时也有一些难以掌握的操作。在本篇博客中&#xff0c;我们将详细介绍Vim的各种功能&#xff0c;以及如何使用它来提高的编辑效率。 1.基本模式 Vim具…

Unity之ShaderGraph入门

前言 随着Unity版本的不断升级&#xff0c;URP&#xff08;可编程渲染管线&#xff09;也越来越普及了。不管是从效果还是性能&#xff0c;都是吊打老版的build-in-shader。所以无论如何我们都要开始 拥抱URP&#xff0c;升级Unity的时候到了。 引擎版本 我这里选择了Unity …

01_Linux操作系统

第一章&#xff1a;Linux操作系统 阶段内容说明&#xff1a; Linux命令&#xff1a;软件测试第一个任务&#xff0c;一般都要进行环境搭建&#xff0c;一部分环境搭建内容是在服务器上实现的&#xff0c;跟服务器交互需要使用Linux命令&#xff08;因为服务器没有图形化界面&a…

Atlassian Confluence CVE-2022-26134 RCE漏洞

Atlassian Confluence CVE-2022-26134 RCE漏洞 Atlassian Confluence CVE-2022-26134 RCE漏洞 漏洞简介 远程攻击者在未经身份验证的情况下&#xff0c;可构造OGNL表达式进行注入&#xff0c;实现在Confluence Server或Data Center上执行任意代码. 漏洞影响范围 Confluence …

代码优化- 基本概念

思考一个问题&#xff1a;我们可以再抽象语法树上做编译优化吗&#xff1f; 答案是否定的&#xff0c;如果在抽象语法树上做编译优化的话&#xff0c;程序员所写的可能包含错误的代码&#xff0c;可能就被删除了&#xff0c;比如&#xff0c;对下面的程序做不可达代码删除优化…