事件是个很大的知识点,这里只讲解一些核心点。
一, 事件传播 && DOM事件流
事件传播、dom事件流是相同的概念不同的解释;分成三个阶段:
1.事件捕获
2.处于目标阶段
3.事件冒泡
DOM2规范中明确要求捕获阶段不涉及事件目标,但是IE9、Safari、Chrome、Firefox、Opera等都支持捕获阶段触发事件对象;
因此,有两个机会在目标对象上操作事件(事件捕获、事件冒泡);
1.1 事件捕获
在事件捕获提供了事件没有送达目标之前查看它们的机会,事件捕获用于程序调试、事件取消技术;
在DOM2中,addEventListener(eventType,callback,boolean),其中boolean为true时,表示在捕获阶段调用事件处理程序;
1.2 事件冒泡
事件冒泡提供了事件送达目标之后查看事件目标的机会,事件冒泡用于事件委托技术;
在DOM2中,addEventListener(eventType,callback,boolean),其中boolean为false时,表示在冒泡阶段调用事件处理程序;
二,事件处理程序
事件处理程序大致分成以下几种:
2.1 HTML中的事件处理程序
<input onclick="alert(value)">
这种写法已经淘汰,缺点很明显,与HTML耦合严重;
2.2 DOM0级事件处理程序
var btn = document.querySelector('#btn'); btn.onclick = function(event){};
2.3 DOM2级事件处理程序
有两个接口函数addEventListener(),removeEventListener();这两个函数有三个参数:事件名称、事件处理程序、布尔值;
布尔值为true时,表示在捕获阶段调用事件处理程序;这种用法,通常用于调试,比如判断目标对象时候正确,然后决定是否取消事件传播;
布尔值为false时,表示冒泡阶段,通常在此阶段进行事件委托技术处理;
一般在冒泡阶段注册事件处理程序,不推荐在捕获阶段;
注意:
2.3.1.如果事件处理程序是匿名函数,removeEventListener()则无法移除匿名函数;也就是说,事件触发时,对应的事件处理程序仍在!
document.querySelector('#btn').addEventListener('click',function(e){ },false) document.querySelector('#btn').removeEventListener('click',function(e){ // 无效,无法删除绑定的事件处理程序 },false)
如何解决这个问题?只要把匿名函数写成具名函数,然后将函数作为参数传入即可!
function handler(e){} document.querySelector('#btn').addEventListener('click',handler,false) // 有效的,可以移除注册函数 document.querySelector('#btn').removeEventListener('click',handler,false)
三,事件对象
事件处理程序中传入的参数是event,这个就是事件对象;事件对象包含了几个比较重要的属性、方法;
属性:
1. currentTarget // 表示当前绑定的dom元素
2. target // 表示事件目标(事件源)
方法:
1. preventDefault() // 取消事件默认行为,比如<a>点击后会跳转的行为
2. stopPropagation() // 阻止事件传播
在事件处理程序中,要分清楚this,target,currentTarget之间的区别;
<div id="testDiv"> <button id="testBtn">click on</button> </div>
document.querySelector('#testDiv').addEventListener('click',function(e){ // this === currentTarget 这个始终相等 // this,currentTarget始终等于绑定的DOM元素 // target 等于事件目标,此时点击的是按钮button,按钮就是事件源,就是target },true) document.querySelector('#testBtn').addEventListener('click',function(e){ // this === currentTarget // 此时事件源、绑定的DOM元素是相同的,因此target===this===currentTarget },true)
四,事件委托 && 事件取消
事件取消技术:
利用事件捕获阶段,来判断是否需要触发事件处理程序;
事件委托技术:
利用事件冒泡阶段,委托处理;减少DOM操作,优化性能;
网上很多大牛采用“收快递场景”模拟说明;
五,事件类型
参考文档: