![](https://img.haomeiwen.com/i14882319/f17833ac48b6f328.png)
1、定义:
- 给元素的事件行为绑定方法,当事件行为触发方法会被执行,不仅被执行,而且还会把当前操作的相关信息传递给这个函数 =>传递过来相关信息就叫做事件对象
事件对象是由事件当前本身产生的,和执行什么函数没有关系
2、原理:
事件对象和函数以及给谁绑定的事件没啥必然关系,它存储的是当前本次操作的相关信息,操作一次只能有一份信息,所以在哪个方法中获取的信息都是一样的;第二次操作,存储的信息会把上一次操作存储的信息替换掉...;
- 每一次事件触发,浏览器都会这样处理一下:
- 1.捕获到当前操作的行为(把操作信息获取到),通过创建MouseEvent等类的实例,得到事件对象EV
- 2.通知所有绑定的方法(符合执行条件的)开始执行,并且把EV当做实参传递给每个方法,所以在每个方法中得到的事件对象其实是一个
- 3.后面再重新触发这个事件行为,会重新获取本次操作的信息,用新的信息替换老的信息,然后继续之前的步骤...
3、事件对象类型
-1)鼠标事件对象
如果是鼠标操作,获取的是MouseEvent类的实例(这个实例就是 =>鼠标事件对象)
box.onclick = function (ev) {
console.log(ev);
}
![](https://img.haomeiwen.com/i14882319/bc8068f24e63817f.png)
- 原型链:
- 鼠标事件对象 -> MouseEvent.prototype -> UIEvent.prototype -> Event.prototype -> Object.prototype
- 常用属性:
- clientX/clientY:当前鼠标触发点距离当前窗口左上角的X/Y轴坐标
- pageX/pageY:触发点距离当前页面左上角的X/Y轴坐标
![](https://img.haomeiwen.com/i14882319/785d80ab12b9e1aa.png)
-2)键盘事件对象
如果是键盘操作,获取的是KeyboardEvent类的实例 =>键盘事件对象
- 常用属性:
- code & key:存储的都是按键,code更细致
- keyCode & which:存储的是键盘按键对应的码值
- 键盘常用码值:
- 方向键:37 38 39 40 =>左上右下
- 空格SPACE:32
- 回车ENTER:13
- 回退BACK:8
- 删除DEL:46
- SHIFT:16
- CTRL:17
- ALT:18
window键盘码值:
![](https://img.haomeiwen.com/i14882319/9cf5335aefd88c8e.png)
苹果键盘码值:
![](https://img.haomeiwen.com/i14882319/7644c59b0b655b23.png)
-3)除了以上还有:
- 普通事件对象(Event)、
- 手指事件对象(TouchEvent)等
这里不详细介绍了
4、事件对象event的属性
除了上面,只有鼠标和键盘中有的属性外,还有一些公共的所有事件对象都有的属性
- type:触发事件的类型
- target:事件源(操作的是哪个元素,哪个元素就是事件源)
- 在不兼容的浏览器中可以使用srcElement获取,也代表的是事件源
- preventDefault():用来阻止默认行为的方法
- 不兼容的浏览器中用ev.returnValue=false也可以阻止默认行为
- stopPropagation():阻止冒泡传播
- 不兼容的浏览器中用ev.cancelBubble=true也可以阻止默认行为
5、事件传播机制
![](https://img.haomeiwen.com/i14882319/1fca9087d87458f1.png)
事件传播机制:当某个元素的相关事件行为触发时,浏览器会做三件事情:(可以通过dir(Event)产看Event类上的信息)
-1)冒泡传播机制
Event.prototype:Event 原型上记录了冒泡传播的顺序
![](https://img.haomeiwen.com/i14882319/608e6fd63f46829b.png)
-
1、捕获阶段:=>CAPTURING_PHASE:1
从最外层向最里层事件源依次进行查找
- 目的:是为冒泡阶段事先计算好传播的层级路径
-
2、目标阶段:=>AT_TARGET:2
- 当前元素的相关事件行为触发
-
3、冒泡传播:=>BUBBLING_PHASE:3
- 触发当前元素的某一个事件行为,不仅它的这个行为被触发了, 而且它所有的祖先元素(一直到window)相关的事件行为都会被依次触发(从内到外的顺序)
![](https://img.haomeiwen.com/i14882319/7d87ce58c20dd2cf.png)
-2)阻止冒泡传播
ev.stopPropagation()
- 不兼容的浏览器中用ev.cancelBubble=true也可以阻止默认行为
6、事件委托
又叫做事件代理
![](https://img.haomeiwen.com/i14882319/5ac4fe6f383541b7.png)
核心:基于事件的冒泡传播机制完成
原理:
利用事件的冒泡传播机制,只给最外层容器的相关事件行为绑定方法,这样不管触发容器内部哪一个后代元素的相关事件行为,都会传播到容器上,触发它的对应事件行为,
在执行的方法中,可以基于ev.target来判断事件源,从而做不同的事情;避免给后台元素一个个的注册事件绑定,性能有很大的提高;
1、应用场景一
如果一个容器中很多元素都要在触发某一事件的时候做一些事情的时候,
原始方案:给元素每一个都单独进行事件绑定
基于事件委托:
我们只需要给当前容器的这个事件行为绑定方法,
这样不论是触发后代中哪一个元素的相关事件行为,由于冒泡传播机制,当前容器绑定的方法也都要被触发执行
想知道点击的是谁(根据是谁做不同的事情),只需要基于事件对象中的ev.target事件源获取即可
2、应用场景二
数据是动态绑定渲染的,要给每一条数据绑定事件行为时,选用事件委托,就可以实现动态点击的处理了,不用在逐一获取绑定了
3、应用场景三
除某某事件源以外的其它事件源,操作的时候统一做某事的,基本上都要基于事件委托解决
4、优点
基于事件委托实现,整体性能要比一个个的绑定方法高出50%左右
如果多元素触发,业务逻辑属于一体的,基于事件委托来处理更加好
某些业务场景只能基于事件委托处理
网友评论