事件传播机制
捕获阶段:点击当前元素时,首先从最外层开始向内查找(找到要操作的事件源),查找目的是构造出冒泡传播的路线(按照HTML层级结构找的)
目标阶段:把事件源相关操作行为触发
冒泡传播:触发当前元素的某一个事件行为,不仅当前元素事件行为触发,而且其祖先元素的相关事件行为也会依次被触发
不同浏览器对于最外层祖先元素是不一样的
谷歌 / 火狐:window document html body
IE高版本:window html body
IE低版本:html body
关于事件对象的一些理解
1、事件对象是存储当前本次操作的相关信息,和操作无关,和元素无必然关联
2、当我们基于鼠标或者键盘操作时,浏览器会把本次操作信息存储起来(标准浏览器存储到默认的内存中自己找不到,IE低版本浏览器存储到window.event
中,存储的值是一个对象,元素触发某个行为,把绑定的方法执行,此时标准浏览器会把之前存储的对象当作实参传递给每一个执行的方法,所以操作依次,即使在多方法中都有e,但存储的值都是一个)
事件委托(事件代理):
利用事件的冒泡传播机制,如果一个容器的后代元素中,很多元素的事件行为都要做一些处理,不用给每个元素绑定方法,只用给容器绑定即可,点击任一个后代元素,都会根据冒泡传递机制,把容器行为触发,把对应方法执行,根据事件源判断点击的是谁,从而做不同的事情
事件委托一般应用场景:
1、容器中有很多后代元素的某些行为要进行操作,委托给容器处理
2、元素是动态绑定
3、除了某个元素,剩下的操作都做同样的事情
事件绑定:
DOM 0级事件绑定[element].onxxx = function () {}
方法在当前元素事件行为的冒泡阶段或者目标阶段完成
DOM0事件(私有属性)就是给元素的某一个事件私有属性赋值,只允许给元素某个事件绑定一个方法,多次绑定后面绑定内容会替换掉前面绑定的,以最后一次绑定方法为主
DOM 2级事件绑定[element].addEventListener('xxx',function(){},false)
,移除removeEventListener
[element].attachEvent('onxxx',function(){})
IE6-8,移除detachEvent
第三个参数 false 也是方法在当前元素事件行为的冒泡阶段或者目标阶段完成,参数为 true 代表方法在事件传播捕获阶段触发执行
该方法都是EventTarget.prototype
上定义的
基于addEventListener
完成事件绑定,是基于“事件池机制”完成的,当元素某个事件触发后,浏览器会到事件池中按照循序依次把之前监听的方法执行,执行的方法不会重复(在向事件池中增加的时候就去重了)
DOM 2事件绑定可以给当前元素某一个事件行为绑定“多个不同方法”
DOM2兼容问题
谷歌 VS IE高版本,在移除事件时候,如果移除操作发生在正要执行的方法之前,谷歌会立即生效,第一次就不再执行,IE是本次不生效,下一次才生效
标准 VS IE低版本,语法不一样,标准浏览器中方法中的this
是当前元素本身,IE低版本中的this
是window。标准浏览器事件池默认去重,IE地把呢不能不能去重。标准浏览器按照事件池存放顺序依次执行,IE低版本是乱序执行
DOM 0级事件绑定和DOM2级事件绑定区别
1、机制不一样,DOM0采用给私有属性赋值,只能绑定一个方法,DOM2采用事件池机制,可以绑定多个不同方法
2、DOM2在移除时,必须清除要移除的那个方法(绑定实名函数),DOM0直接赋值为null
给元素绑定某一个事件,方法执行的时候浏览器给方法传递一个实参信息值,这个值就是事件对象
事件对象中记录了属性名和属性值,信息中包含当前操作的基础信息,例如:
[mouseEvent]e.target
事件源,当前操作的元素e.clientX / e.clientY
距离窗口左上角X/Y轴坐标e.pageX / e.pageY
距离BODY(第一屏幕)左上角X/Y轴坐标e.preventDefault
阻止默认行为e.stopPropagation
阻止事件的冒泡传播e.type
当前事件类型
[keyboardEvent]e.code
当前按键‘keyX’e.key
当前按键'X'e.which / e.keyCode
当前按键的键盘码
IE低版本浏览器中,浏览器执行绑定的方法,并没有把事件对象传递进来,需要基于window.event
来获取(由于是全局属性,鼠标每次操作都会把上一次的值替换掉)
低版本浏览器中不存在pageX / pageY
处理兼容思想一
if(!e){
e = window.event;
e.target = e.srcElement;
e.pageX = e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft);
e.pageY = e.clientY + (document.documentElement.scrollTop || document.body.scrollTop);
e.which = e.keyCode;
e.preventDefault = function(){e.returnValue = false}; // 低版本阻止默认行为
e.stopPropagation = function(){e.cancelBubble = true} // 低版本阻止冒泡传播
e.preventDefault();
e.stopPropagation();
}
处理兼容思想二(适合处理兼容较少)e = e || window.event;var target = ev.target || ev.srcElement;
默认行为:事件本身就是天生就有的,某些事件触发,即使没有绑定方法,也会存在一些效果,这些默认效果就是事件默认行为,例如a标签有页面跳转,锚点定位
DOM事件:
1、什么是事件:事件就是一件事情或者一个行为(对于元素来说,它的很多事件都是天生自带的),只要操作这个元素,就会触发这些行为
2、事件绑定:给元素天生自带的事件行为绑定方法,当事件触发,会把对应的方法执行
3、元素天生自带的事件:
[鼠标事件]click
点击(PC端是点击,移动端的click
代表单击且会有300ms延迟)dblclick
双击mouseover
鼠标经过mouseout
鼠标移出mouseenter
鼠标进入mouseleave
鼠标移开mousemove
鼠标移动mousedown
鼠标按下(鼠标左右键都起作用,它是按下即触发,click
是按下抬起才触发,而且是先把down和up触发,才会触发click)mouseup
鼠标抬起mousewheel
鼠标滚轮滚动
......
[键盘事件]keydown
键盘按下keyup
键盘抬起keypress
和keydown
类似,只不过keydown
返回的是键盘码,keypress
返回的是ASCII码值input
移动端用
[表单元素常用事件]focus
获取焦点blur
失去焦点change
内容改变
[移动端手指事件]touchstart
手指按下touchmove
手指移动touchend
手指离开touchcancel
因意外情况导致手指操作取消gesturestart
手指按下(多手指操作)gesturechange
手指改变(多手指操作)gestureend
手指离开(多手指操作)
......
[H5中的audio / video 音视频事件]canplay
可以播放,资源未加载完成可能出现卡顿canplaythrough
资源加载完成,可以正常无障碍播放play
开始播放playing
播放中pause
暂停播放
[其它常用事件]load
加载完成unload
资源卸载beforeeunload
浏览器在关闭之前error
资源加载失败scroll
滚动条滚动事件resize
大小改变事件 window.onresize
浏览器窗口大小改变,会触发这个事件
作者:好酒不见_
链接:https://www.jianshu.com/p/8c3ad6b11a28
来源:简书