第三天:js中的事件提高篇(事件流,事件对象,事件委托深层次理解)
目录
- 前言
- 一,基础部分
- 1.1 js监听并绑定事件
- 1.2 删除事件绑定
- 二,事件流
- 2.1 事件流是什么
- 2.2 事件流模型
- 2.3 捕获与冒泡具体示例
- 2.3.1 addEventListener的第三个参数
- 2.3.1 捕获阶段
- 2.3.2 冒泡阶段
- 三,事件对象
- 3.1 事件对象是什么
- 3.2 事件对象常用的属性和方法
- 3.2.1 阻止默认行为
- 3.2.2 阻止事件冒泡
- 3.2.3 鼠标事件对象
- 四,事件委托
- 后记
前言
对于一个html网页来说,html是页面的骨架,css是页面的样式,而js则控制页面元素的行为。本篇我们将学习原生网页界面如何操作元素(监听并绑定事件)。并介绍事件流,事件对象,事件冒泡,以及事件委托这几个点。希望对读者的学习有帮助!
一,基础部分
1.1 js监听并绑定事件
请看以下代码:
<button>方法监听注册事件</button><script>var btn = document.querySelector('button');btn.addEventListener('click', function() {alert('22');})btn.addEventListener('click', function() {alert('22');})</script>
通过上述代码可了解:
第一步:绑定页面元素
第二步:监听器addEventListener
e.addEventListener('事件','回调函数') {}
这里需要注意的是,之前我们写简单的事件绑定,如e.onclick(),e.onmouse等,在新学习的这种写法中,事件写的内容要在原来的基础上把on去掉。
1.2 删除事件绑定
请看以下代码:
divs[1].addEventListener('click', fn);function fn() {alert('22');divs[1].removeEventListener('click',fn);}
最开始给divs中索引为1的元素绑定了click事件,回调函数为fn。当点击fn后,先弹出‘22’模态框,然后取消了该元素的绑定事件。并执行新的回调函数。
二,事件流
2.1 事件流是什么
首先从字面上理解,事件流指从页面中接收事件的顺序。。
我们知道,js是单线程的脚本语言(JavaScript是一种解释型的脚本语言,C、C++等语言先编译后执行,而JavaScript是在程序的运行过程中逐行进行解释。),当页面中的DOM元素触发事件,浏览器从Window开始从上往下遍历,来查找整个DOM元素。概括为事件发生时会在元素节点与根节点之间按照特定的顺序传播,路径所经过的所有节点都会收到该事件,这个传播过程即DOM事件流。
2.2 事件流模型
事件流模型则可以很直观的从原理来为我们呈现事件流,事件流模型分为两个部分:分别是冒泡型事件流,捕获型事件流。
我们知道,网页中元素很多,大部分元素都有父元素,也有部分元素有子元素,那么我们是不是可以把元素看成一棵树(DOM树):
冒泡型事件流:从DOM树的叶子到根,从下到上,范围从小到大遍历;
捕获型事件流:从DOM树的跟到叶子,从上到下,范围从大到小遍历。
2.3 捕获与冒泡具体示例
2.3.1 addEventListener的第三个参数
刚刚我们已经了解,js中addEventListener的用法。在介绍完冒泡与捕获后,向大家介绍第三个参数:具体格式如下
e.addEventListener('事件',‘回调函数’,第三个参数)
第三个参数是一个布尔值,默认为false,false对应的是冒泡,true代表的是捕获。
接下来我们利用以下结构来学习捕获与冒泡的具体实例:
<div class="father"><div class="son"></div></div>
2.3.1 捕获阶段
捕获阶段,addEventListener的第三个值是true,请看以下代码:
var son = document.querySelector('.son');son.addEventListener('click', function() {alert('son');}, true);//捕获阶段var father = document.querySelector('.father');father.addEventListener('click', function() {alert('father');}, true);//捕获阶段document.addEventListener('click', function() {alert('document');})
对子盒子,父盒子先进行获取,然后再绑定事件。理论上,点击son会弹出son模态框,点击father会弹出father模态框。但在捕获阶段:
点击father时没有任何问题:
点击son时却:
原因:捕获型事件流:从DOM树的跟到叶子,从上到下,范围从大到小遍历。
点击父元素遍历顺序:father
点击子元素遍历顺序:father->son,所以点击子元素时会先出现父元素模态框,再出现子元素模态框。
至于为什么没有出现document的模态框,因为我们没有点document,点的是father所以从father开始遍历。
2.3.2 冒泡阶段
捕获阶段,addEventListener的第三个值是false(或者不写,因为默认false),请看以下代码:
var father = document.querySelector('.father');father.addEventListener('click', function() {alert('father');});var son = document.querySelector('.son');son.addEventListener('click', function() {alert('son');});document.addEventListener('click', function() {alert('document');})
点击father时:
点击son时:
原因:冒泡型事件流:从DOM树的叶子到根,从下到上,范围从小到大遍历。
点击父元素遍历顺序:father->document;
点击子元素遍历顺序: son->father->document。
三,事件对象
3.1 事件对象是什么
div是一个盒子,为它绑定事件:
var div = document.querySelector('div');div.addEventListener('click', function(event){console.log(event);})
打印event,结果是一个对象:
我们把event称作事件对象。其中,event可以看作是形参,可以任意更改名字。
这里简单定义一下事件对象:事件对象是事件的一系列相关数据的集合,跟事件相关的,比如鼠标点击的信息,键盘。事件对象存在的前提是事件存在,由系统自动为我们创建。
3.2 事件对象常用的属性和方法
3.2.1 阻止默认行为
非常常用!默认行为比如:链接跳转,按钮自动提交等等,我们可以通过事件对象阻止默认行为,下面以阻止链接跳转为例:
e.preventDefault()
var a = document.querySelector('a');a.addEventListener('click', function(e) {// e.preventDefault();//方法// e.returnValue;//属性return false;//通用,但不能执行后续代码})
3.2.2 阻止事件冒泡
事件冒泡是子到父,当我们为子与父都绑定了点击出现模态框事件,如何取消?见如下代码:
e.stopPropagation();
var father = document.querySelector('.father');var son = document.querySelector('.son');father.addEventListener('click', function() {alert('我是father');})son.addEventListener('click', function(e) {alert('我是son');e.stopPropagation();})
即可成功阻止
3.2.3 鼠标事件对象
我们有了事件对象,便可通过事件对象获取鼠标的位置。具体如上图,大家也可以拿下面的代码进行实验:
document.addEventListener('click', function(e) {console.log(e.clientX);console.log(e.clientY);console.log(e.pageX);console.log(e.pageY);console.log(e.screenX);console.log(e.screenY);})
四,事件委托
定义:事件委托(事件代理)。是JavaScript中常用绑定事件的常用技巧。顾名思义,“事件代理”即是把原本需要绑定在子元素的响应事件(click、keydown…)委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。
大家请自行编译如下代码:
<ul><li>子元素</li><li>子元素</li><li>子元素</li><li>子元素</li><li>子元素</li></ul><script>//给父节点添加监听器var ul = document.querySelector('ul');ul.addEventListener('click', function(e) {alert('弹出');e.target.style.backgroundColor = 'pink';})</script>
效果:当我们点击每个子元素li时候,都会弹出模块框‘弹出’。原因:
点击子元素后,由于是冒泡阶段(默认false),所以遍历顺序:子元素->父元素->document。所以,点击子元素后,会触发父元素,于是就会触发模块狂的弹出。
注意:使用“事件委托”时,并不是说把事件委托给的元素越靠近顶层就越好。事件冒泡的过程也需要耗时,越靠近顶层,事件的”事件传播链”越长,也就越耗时。如果DOM嵌套结构很深,事件冒泡通过大量祖先元素会导致性能损失。
后记
本节我们对事件流,事件对象,事件委托等内容进行了讲解。后续会更新更多底层原理及应用,谢谢喜欢,欢迎关注!
第三天:js中的事件提高篇(事件流,事件对象,事件委托深层次理解)相关推荐
- js中unload什么意思_JS之onunload、onbeforeunload事件详解
简介 onunload,onbeforeunload都是在刷新或关闭时调用,可以在 onbeforeunload 是正要去服务器读 取新的页面时调用,此时还没开始读取:而onunload则已经从服务器 ...
- three.js中坐标系转换以及camera的position、lookAt与up属性理解
为了更好的理解camera的position.lookAt与up属性,文章最开始我们先来阐述three.js的坐标系转换的概念. 1.监听event的事件获得屏幕坐标 文章的最开始首先讨论在哪里进行点 ...
- 【EventBus】事件通信框架 ( 订阅类-订阅方法缓存集合 | 事件类型-订阅者集合 | 订阅对象-事件类型集合 )
文章目录 前言 一.订阅类-订阅方法缓存集合 二.事件类型-订阅者集合 三.订阅对象-事件类型集合 前言 首先声明几个数据结构 , 参考 [EventBus]EventBus 源码解析 ( 注册订阅者 ...
- js中console在一行内打印字符串和对象
在前端开发中,大多数的调试一般都是F12中的console和network中查看请求数据和响应数据,也有一部分人喜欢用debugger. 在开发大一些的项目时,在开发环境下,打开着控制台,切换一下页面 ...
- js 中使用idx模块方便获取链条式的对象属性值
1. 背景 从一个js对象的属性值中的属性再次获得值,或者从集合中获得元素再获得属性值要写很多判断是否空的表达式,才能继续读取,否则就出现异常.这在开发过程很繁琐的事情,idx 模块就是来解决这个问题 ...
- js中如何优雅修改一个多层嵌套list对象的值
如何优雅更改一个N层嵌套对象属性的值 看下边的代码,要加工一个嵌套list的属性值,然后再赋值回去,大概只能这样写: dp.data.treelist = dp.data.treelist.map(. ...
- JS详解 | 对象 事件 节点 | 系统性学习 | 无知的我费曼笔记
无知的我正在复盘js- 文章目录 JavaScript 1 常用命令 输出语句 转换为字符串 得到变量类型 1 获取元素对象 1.1 H5新增获取元素对象 1.2 直接获取特殊元素对象 2 事件三要素 ...
- JS OOP -02 深入认识JS中的函数
深入认识JS中的函数: 1.概述,认识函数对象 2.函数对象和其他内部对象的关系 3.将函数作为参数传递 4.传递给函数的隐含参数:arguments 5.函数的apply,call方法和length ...
- Javascript开发技巧(JS中的变量、运算符、分支结构、循环结构)
一.Js简介和入门 继续跟进JS开发的相关教程. <!-- [使用JS的三种方式] 1.HTML标签中内嵌JS(不提倡使用): 示例:<button οnclick="javas ...
最新文章
- (38)Spring Boot分布式Session状态保存Redis【从零开始学Spring Boot】
- kubernetes组件
- thymeleaf模板的使用(转)
- python基础(十二):正则、re模块、贪婪和非贪婪
- matlab同时给多个变量赋值(deal)
- apt-get update碰到错误
- Oracle对表空间操作的sql
- linux内核参数备注
- 如何查看/统计当前AD域控制器的活动用户
- 巩膜:论文翻译《一种改进的眼角检测算法》An Improved Algorithm for Eye Corner Detection
- 把Vim改装成一个IDE编程环境
- Android App的破解技术有哪些?如何防止反编译?
- pox控制器学习笔记
- python有几级等级考试成绩查询_python查询46级成绩
- vue自定义表格(每一列表格下面包含一个子表格)
- nginx日志格式分析
- 【linux kernel】linux内核如何唤醒线程
- 渗透测试漏洞平台DVWA-参考答案
- CouchDB与CouchBase的比较
- 平板电脑3C认证的重要性,为什么要3C认证?Ⓠ欢Ⓠ迎3来8网3赚5喔0
热门文章
- H3C-NS228万兆交换机端口聚合调试报告
- [渝粤教育] 武汉船舶职业技术学院 Adobe Illustrator 图形图像制作 参考 资料
- 高考英语口试计算机,重庆高考英语口试怎么考
- iOS - 外加字体(只需三步-教你轻松实现)
- php网页代码字体颜色设置,html和css中字体颜色设置的相关总结
- Unity技术面试题
- oracle数据库imp用法,imp导入数据库的用法
- 苹果未来秘密在这里!从神秘组织到七大技术布局
- win7系统计算机虚拟内存不足,正版win7旗舰版总是提示虚拟内存不够电脑为什么会虚拟内存不够...
- 任天堂发布首款整合 Google 搜索的 Wii 游戏