JS的事件冒泡和事件捕获

Wesley13
• 阅读 550

什么是事件?

事件是文档和浏览器窗口中发生的特定的交互瞬间。 事件是javascript应用跳动的心脏,也是把所有东西黏在一起的胶水,当我们与浏览器中web页面进行某些类型的交互时,事件就发生了。

事件可能是用户在某些内容上的点击,鼠标经过某个特定元素或按下键盘上的某些按键,事件还可能是web浏览器中发生的事情,比如说某个web页面加载完成,或者是用户滚动窗口或改变窗口大小。

什么是事件流:

事件流描述的是从页面中接受事件的顺序,但有意思的是,微软(IE)和网景(Netscape)开发团队居然提出了两个截然相反的事件流概念,IE的事件流是事件冒泡流(event bubbling),而Netscape的事件流是事件捕获流(event capturing)。

下面说一下事件冒泡和事件捕获的概念:

事件冒泡和事件捕获是描述事件触发事件时序问题的术语,事件捕获指的是从document到触发事件的那个节点,也就是说自上而下的去触发事件,相反的,事件冒泡是自下而上的去触发事件,绑定事件方法的第三个参数,就是控制事件触发顺序是否为事件捕获,true为事件捕获,false为事件冒泡,jQuery的e.stopPropagation会阻止冒泡,意思就是到我为止,我的爹和祖宗的事件就不要触发了。

第一种:事件冒泡

IE提出的事件流叫做事件冒泡,即事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点,看一下以下示例:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body onclick="bodyClick()">
 8 
 9     <div onclick="divClick()">
10         <button onclick="btn()">
11             <p onclick="p()">点击冒泡</p>
12         </button>
13     </div>
14     <script>
15        
16        function p(){
17           console.log('p标签被点击')
18        }
19         function btn(){
20             console.log("button被点击")
21         }
22          function divClick(event){
23              console.log('div被点击');
24          }
25         function bodyClick(){
26             console.log('body被点击')
27         }
28 
29     </script>
30 
31 </body>
32 </html>

执行顺序: p=>button=>div=>body

正如上面我们所说的,它会从一个最具体的的元素接收,然后逐级向上传播, p=>button=>div=>body..........事件冒泡可以形象地比喻为把一颗石头投入水中,泡泡会一直从水底冒出水面,也就是说从小到大开始传播。

第二种:事件捕获

网景公司提出的事件流叫事件捕获流。

事件捕获流的思想是不太具体的DOM节点应该更早接收到事件,而最具体的节点应该最后接收到事件,针对上面同样的例子,点击按钮,那么此时click事件会按照这样传播:(下面我们就借用addEventListener的第三个参数来模拟事件捕获流),也就是上面的例子就会倒过来。

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 
 9 <div>
10     <button>
11         <p>点击捕获</p>
12     </button>
13 </div>
14 <script>
15     var oP=document.querySelector('p');
16     var oB=document.querySelector('button');
17     var oD=document.querySelector('div');
18     var oBody=document.querySelector('body');
19 
20     oP.addEventListener('click',function(){
21         console.log('p标签被点击')
22     },true);
23 
24     oB.addEventListener('click',function(){
25         console.log("button被点击")
26     },true);
27 
28     oD.addEventListener('click',  function(){
29         console.log('div被点击')
30     },true);
31 
32     oBody.addEventListener('click',function(){
33         console.log('body被点击')
34     },true);
35 
36 </script>
37 
38 
39 
40 </body>
41 </html>

正如我们看到的,和冒泡流万全相反,从最不具体的元素接收到最具体的元素接收事件  body=>div=>button=>p

DOM事件流:

‘DOM2级事件’规定的事件流包含3个阶段,事件捕获阶段、处于目标阶段、事件冒泡阶段。首先发生的事件捕获为截获事件提供机会,然后是实际的目标接收事件,最后一个阶段是事件冒泡阶段,可以在这个阶段对事件做出响应。

在DOM事件流中,事件的目标在捕获阶段不会接收到事件,这意味着在捕获阶段事件从document到

就停止了,下个阶段是处于目标阶段,于是事件在

上发生,并在事件处理中被看成冒泡阶段的一部分,然后,冒泡阶段发生,事件又传播回document。

JS的事件冒泡和事件捕获

流程就是先捕获,然后处理,最后再冒泡出去

关于DOM 2级事件处理程序:

DOM 2级事件定义了两方法:用于处理添加事件和删除事件的操作: 添加事件 addEventListener()     删除事件  removeEventListener(),所有DOM节点中都包含这两个方法,并且他们都包含3个参数:

(1) 要处理的事件方式(例如:click,mouseover,dbclick.....)

(2)事件处理的函数,可以为匿名函数,也可以为命名函数(但如果需要删除事件,必须是命名函数)

(3)一个布尔值,代表是处于事件冒泡阶段处理还是事件捕获阶段(true:表示在捕获阶段调用事件处理程序;false:表示在冒泡阶段调用事件处理程序)

使用DOM 2级事件处理程序的主要好处是可以添加多个事件处理程序,事件处理会按照他们的顺序触发,通过addEventListener添加的事件只能用removeEventListener来移除,移除时传入的参数与添加时使用的参数必须相同,这也意味着添加的匿名函数将无法移除,(注意:我们默认的第三个参数都是默认false,是指在冒泡阶段添加,大多数情况下,都是将事件处理程序添加到事件的冒泡阶段,这样可以最大限度的兼容各个浏览器)

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Stella981 Stella981
2年前
JavaScript事件 ——常见事件
1.什么是事件?      当我们与浏览器中Web页面进行某些类型的交互时,事件就发生了。事件可能是用户在某些内容上的点击、鼠标经过某个特定元素或按下键盘上的某些按键。事件还可能是Web浏览器中发生的事情,比如说某个Web页面加载完成,或者是用户滚动窗口或改变窗口大小。常见事件:(http://www.runoo
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Stella981 Stella981
2年前
Javascript高级编程学习笔记(57)—— 事件(1)事件流
事件JS与HTML的交互是通过事件实现的而事件指的就是:文档或浏览器窗口特定的交互瞬间可以通过侦听器来预定事件,以便在事件发生时执行相应的代码这种模式也是设计模式中的观察者模式事件流有了事件,也就有了事件流的概念事件流故名思意:也就是事件的流向,所以事件流描述的是从页面中接收事件的顺序虽然事件流描述的都是事件的流
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这