DOM事件体系:事件流、事件对象、事件代理

news/2024/10/29 2:27:05/

文章目录

  • 事件流
    • 事件与事件监听
    • 事件捕获、事件冒泡
  • 事件对象
    • 事件对象的属性
    • 事件对象的方法
  • 事件代理
  • 总结


事件流

事件流表示的是事件在页面中传播的顺序,现代浏览器都遵从一套通用的事件流标准,包括 捕获流冒泡流

事件与事件监听

  • 事件

事件描述的是发生在浏览器里的动作,这个动作可以由用户从外部触发,也可以是浏览器内部逻辑触发。

  • 事件监听函数
document.addEventListener(event, function, useCapture)

event: 事件类型,像点击(click)、鼠标悬停(mouseover)、鼠标移走(mousemove)等。
function: 事件触发后执行的函数
useCapture: 事件的执行时机 :

  • false: 默认, 事件在冒泡阶段执行 ;
  • true: 事件在捕获阶段执行

事件捕获、事件冒泡

为了方便的表示事件在元素中的两种传递方式,我们新建如下html页面

<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="UTF-8"><title>Document</title><style>#out{background-color: red;width:300px;height: 300px;}#middle{background-color: green;width:200px;height: 200px;}#in{background-color: blue;width:100px;height: 100px;}</style>
</head><body><div id="out"><div id="middle"><div id="in"></div></div></div><script></script>
</body></html>

在这里插入图片描述

当事件被触发时,首先经历捕获流:事件会从最外层的元素开始逐元素到目标元素;然后事件从目标元素原路返回,进入到冒泡流—— 逐个元素冒到最外层。

在这里插入图片描述

  • 事件冒泡
    为三个div逐个注册事件,addEventListener 的第三个参数设置为false(默认值),开启事件冒泡流:
 <script>const div_out = document.getElementById('out')const div_middle = document.getElementById('middle')const div_in = document.getElementById('in')// 事件冒泡流div_out.addEventListener('click', function(){console.log('冒泡----div_out--red')}, false)div_middle.addEventListener('click', function(){console.log('冒泡----div_middle--green')}, false)div_in.addEventListener('click', function(){console.log('冒泡----div_in--blue', )}, false)</script>

点击蓝色区域,输出如下👇
在这里插入图片描述

  • 事件捕获
    为三个div逐个注册事件,addEventListener 的第三个参数设置为true,开启事件捕获流:
 <script>const div_out = document.getElementById('out')const div_middle = document.getElementById('middle')const div_in = document.getElementById('in')// 事件捕获流div_out.addEventListener('click', function(){console.log('捕获----div_out--red')}, true)div_middle.addEventListener('click', function(){console.log('捕获----div_middle--green')}, true)div_in.addEventListener('click', function(){console.log('捕获----div_in--blue', )}, true)</script>

同样是点击蓝色区域,输出如下👇

在这里插入图片描述

事件对象

当 DOM 事件处理函数触发时,就会产生一个事件对象 event 作为处理函数的入参。这个对象中囊括了与事件有关的信息,比如事件具体是由哪个元素所触发、鼠标点击位置,触发事件的元素对象等。

    div_in.addEventListener('click', function(e){console.log('捕获----div_in--blue', e)}, true)

事件对象的属性

在 event 上有两个重要的属性 currentTargettarget

在这里插入图片描述

  • currentTarget :记录事件当下正在被哪个元素接收
  • target :指触发事件的具体目标,即事件的真正来源。

事件对象的方法

除此之外,在事件对象的原型链向上寻找,还有两个非常重要的方法 preventDefaultstopPropagation

在这里插入图片描述

  • preventDefault :阻止特定事件的默认行为,如 点击 a 标签时禁止跳转
  • stopPropagation:终止事件在传播过程的捕获或冒泡阶段进一步传播

事件代理

在前面简单介绍过:e.target 是指触发事件的具体元素,就算事件处理函数没有绑定在目标元素上、而是绑定在了目标元素的父元素上,由于冒泡机制的存在,目标元素仍然是冒泡到父容器上触发的,仍然可以通过父元素的 target 来感知到目标子元素

利用事件的冒泡特性,把多个子元素的同一类型的监听逻辑,合并到父元素上通过一个监听函数来管理的行为,就是事件代理

如下所示,假设我想每点击一个元素就打印该元素的文本内容,给全部的 li 标签都注册同一个事件当然可以,但是这种做法不仅代码逻辑冗余,而且浪费开销。

在这里插入图片描述


<html lang="en">
<head><meta charset="UTF-8"><title>Document</title><style>#li-wrap{background-color: azure;}</style>
</head>
<body><ul id="li-wrap"><li>这是第一行</li><li>这是第二行</li><li>这是第三行</li><li>这是第四行</li><li>这是第五行</li><li>这是第六行</li><li>这是第七行</li></ul><script></script>
</body>
</html>

点击任何一个 li 标签时,该点击事件都会被冒到它们共同父元素上,id为 li-wrap 的父元素不仅能感知到子元素的事件,还可以通过 e.target 拿到实际触发事件的具体子元素,实现事件代理。因此我们可以这么做:

  <script>const parent = document.getElementById('li-wrap')parent.addEventListener('click', function(e) {console.log(e.target.innerHTML, e)}) </script>

这样就实现了事件代理👇
在这里插入图片描述

总结

事件流

  • 事件与事件监听

  • 事件捕获、事件冒泡

事件对象

  • 事件对象的属性

  • 事件对象的方法

事件代理


http://www.ppmy.cn/news/37453.html

相关文章

Redis持久化——追加与快照

持久化意味着写入数据到持久化储存。redis有两个持久化手段 RDB(Redis Database): 以指定的时间间隔执行数据的时间点快照。AOF(Append Only File): 持久化每个server收到的写入操作到log。 AOF执行过程 命令传播: Redis将执行完的命令等信息发送给AOF程序中 缓存追加: AOF程…

出售Steam上线游戏的完整开发资源包

我开发了一款Steam上的小游戏&#xff1a; 《述途路人团乐之国》&#xff08;英文名称&#xff1a;《As Talk As Walk Wayfarer Team - Land of Music》&#xff09; https://store.steampowered.com/app/2332050/_/ 发行日期&#xff1a;2023年3月13日。 发行平台&#xff1a;…

尚硅谷大数据技术Hadoop教程-笔记07【Hadoop-源码解析】

视频地址&#xff1a;尚硅谷大数据Hadoop教程&#xff08;Hadoop 3.x安装搭建到集群调优&#xff09; 尚硅谷大数据技术Hadoop教程-笔记01【大数据概论】尚硅谷大数据技术Hadoop教程-笔记02【Hadoop-入门】尚硅谷大数据技术Hadoop教程-笔记03【Hadoop-HDFS】尚硅谷大数据技术Ha…

HR都想招到的优秀00后程序员,都有这些特点...

拉勾招聘发布的《2022程序员群体职场洞察报告》显示&#xff0c;74%的00后程序员的薪酬已经过万&#xff0c;这一数据比应届生平均起薪高出50%&#xff0c;一些大厂&#xff08;SP/SSPSpeicial Offer&#xff09;所提供的薪酬则更加可观。 上图节选自拉勾招聘《2022程序员群体…

【Vue3源码Runtime-core篇】 第一章 初识Runtime

第一章 初识Runtime 前言 当设计一个框架的时候&#xff0c;我们有三种选择&#xff1a;纯运行时的、运行时 编译时的或纯编译时的。 我们先聊聊纯运行时的框架。 假设我们设计了一个框架&#xff0c;它提供 一个 Render 函数&#xff0c;用户可以为该函数提供一个树型结构的…

33、搜索旋转排序数组

难度&#xff1a;中等 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], n…

RocketMQ中核心概念及术语介绍

文章目录 角色ProducerConsumerPushConsumerPullConsumer概念术语Producer GroupConsumer GroupTopicTagMessage QueueOffsetConsumer Offset集群消费广播消费顺序消息普通顺序消息严格顺序消息RocketMQ中有很多独有的概念,其中包括一些术语和角色。 理清楚基本的概念是理解原…

前端重装系统需要安装什么

目录 1.安装nvm 2.安装git 3.安装yarn 4. 安装cnpm 5. 配置hbuilder 6. 配置vscode 1.安装nvm 1.1 下载 下载地址&#xff1a;Releases coreybutler/nvm-windows GitHub 如果下载慢&#xff0c;可以复制链接到迅雷下载 1.2 安装 在c盘下创建一个nvm文件夹并创建一个…