目录

  • 前言
  • 一,基础部分
    • 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中的事件提高篇(事件流,事件对象,事件委托深层次理解)相关推荐

  1. js中unload什么意思_JS之onunload、onbeforeunload事件详解

    简介 onunload,onbeforeunload都是在刷新或关闭时调用,可以在 onbeforeunload 是正要去服务器读 取新的页面时调用,此时还没开始读取:而onunload则已经从服务器 ...

  2. three.js中坐标系转换以及camera的position、lookAt与up属性理解

    为了更好的理解camera的position.lookAt与up属性,文章最开始我们先来阐述three.js的坐标系转换的概念. 1.监听event的事件获得屏幕坐标 文章的最开始首先讨论在哪里进行点 ...

  3. 【EventBus】事件通信框架 ( 订阅类-订阅方法缓存集合 | 事件类型-订阅者集合 | 订阅对象-事件类型集合 )

    文章目录 前言 一.订阅类-订阅方法缓存集合 二.事件类型-订阅者集合 三.订阅对象-事件类型集合 前言 首先声明几个数据结构 , 参考 [EventBus]EventBus 源码解析 ( 注册订阅者 ...

  4. js中console在一行内打印字符串和对象

    在前端开发中,大多数的调试一般都是F12中的console和network中查看请求数据和响应数据,也有一部分人喜欢用debugger. 在开发大一些的项目时,在开发环境下,打开着控制台,切换一下页面 ...

  5. js 中使用idx模块方便获取链条式的对象属性值

    1. 背景 从一个js对象的属性值中的属性再次获得值,或者从集合中获得元素再获得属性值要写很多判断是否空的表达式,才能继续读取,否则就出现异常.这在开发过程很繁琐的事情,idx 模块就是来解决这个问题 ...

  6. js中如何优雅修改一个多层嵌套list对象的值

    如何优雅更改一个N层嵌套对象属性的值 看下边的代码,要加工一个嵌套list的属性值,然后再赋值回去,大概只能这样写: dp.data.treelist = dp.data.treelist.map(. ...

  7. JS详解 | 对象 事件 节点 | 系统性学习 | 无知的我费曼笔记

    无知的我正在复盘js- 文章目录 JavaScript 1 常用命令 输出语句 转换为字符串 得到变量类型 1 获取元素对象 1.1 H5新增获取元素对象 1.2 直接获取特殊元素对象 2 事件三要素 ...

  8. JS OOP -02 深入认识JS中的函数

    深入认识JS中的函数: 1.概述,认识函数对象 2.函数对象和其他内部对象的关系 3.将函数作为参数传递 4.传递给函数的隐含参数:arguments 5.函数的apply,call方法和length ...

  9. Javascript开发技巧(JS中的变量、运算符、分支结构、循环结构)

    一.Js简介和入门 继续跟进JS开发的相关教程. <!-- [使用JS的三种方式] 1.HTML标签中内嵌JS(不提倡使用): 示例:<button οnclick="javas ...

最新文章

  1. (38)Spring Boot分布式Session状态保存Redis【从零开始学Spring Boot】
  2. kubernetes组件
  3. thymeleaf模板的使用(转)
  4. python基础(十二):正则、re模块、贪婪和非贪婪
  5. matlab同时给多个变量赋值(deal)
  6. apt-get update碰到错误
  7. Oracle对表空间操作的sql
  8. linux内核参数备注
  9. 如何查看/统计当前AD域控制器的活动用户
  10. 巩膜:论文翻译《一种改进的眼角检测算法》An Improved Algorithm for Eye Corner Detection
  11. 把Vim改装成一个IDE编程环境
  12. Android App的破解技术有哪些?如何防止反编译?
  13. pox控制器学习笔记
  14. python有几级等级考试成绩查询_python查询46级成绩
  15. vue自定义表格(每一列表格下面包含一个子表格)
  16. nginx日志格式分析
  17. 【linux kernel】linux内核如何唤醒线程
  18. 渗透测试漏洞平台DVWA-参考答案
  19. CouchDB与CouchBase的比较
  20. 平板电脑3C认证的重要性,为什么要3C认证?Ⓠ欢Ⓠ迎3来8网3赚5喔0

热门文章

  1. H3C-NS228万兆交换机端口聚合调试报告
  2. [渝粤教育] 武汉船舶职业技术学院 Adobe Illustrator 图形图像制作 参考 资料
  3. 高考英语口试计算机,重庆高考英语口试怎么考
  4. iOS - 外加字体(只需三步-教你轻松实现)
  5. php网页代码字体颜色设置,html和css中字体颜色设置的相关总结
  6. Unity技术面试题
  7. oracle数据库imp用法,imp导入数据库的用法
  8. 苹果未来秘密在这里!从神秘组织到七大技术布局
  9. win7系统计算机虚拟内存不足,正版win7旗舰版总是提示虚拟内存不够电脑为什么会虚拟内存不够...
  10. 任天堂发布首款整合 Google 搜索的 Wii 游戏