DOM事件流
事件流包括三个阶段
- 捕获阶段
- 目标阶段
- 冒泡阶段
事件一开始从文档的根节点流向目标对象(捕获阶段),然后在目标对象上被触发(目标阶段),之后再回溯到文档的根节点(冒泡阶段)
所有的事件都会经过捕获阶段和目标阶段,但有些事件会跳过冒泡阶段,比如,让元素获得输入焦点的focus事件已经失去输入焦点的blur事件就都不会冒泡
事件处理程序
HTML事件处理程序
<input type="button" value="click me" onclick=“console.log(event.type)” />
<input type="button" value="click me" onclick=“handler(event)” />
结构和行为相耦合,不易维护
DOM 0级事件处理程序
btn.onclick = function(){
...
}
这种方式会在事件流的冒泡阶段被处理,删除事件 btn.onclick = null
DOM 2级事件处理程序
dom.addEventListenter() / dom.removeEventListener()
接收3个参数:要处理的事件名, 函数, 布尔值
可以为同一个元素添加多个同类型事件
按照顺序触发
IE事件处理程序
attachEvent() 和 detachEvent()
接收2个参数, 事件名(要加‘on’),函数
IE8及之前的版本
只支持事件冒泡
可添加多个处理程序,但触发顺序是反着来的
最大的区别是:作用域是 全局,this.id指的是 window的id
// 兼容性写法
function addEvent(type, el, fn){
if(window.addEventListener){
el.addEventListenter(type,fn,false)
}else if(window.attachEvent){
el.attachEvent('on'+type, fn)
}
}
// 结合惰性函数的兼容性写法
var addEvent = function (type, el, fn){
if(window.addEventListener){
addEvent = function(type, el, fn){
el.addEventListenter(type,fn,false)
}
}else if(window.attachEvent){
addEvent = function(type, el, fn){
el.attachEvent('on'+type, fn)
}
}
}
DOM 事件对象(event)
- currentTarget 事件遍历DOM时,标识事件的当前目标元素
- target 标识事件起源的元素
- preventDefault 阻止默认事件
- stopPropagation 阻止捕获或冒泡阶段中当前事件的进一步传播
- stopImmediatePropagation 阻止当前节点上所有的回调函数
- type 事件类型
在事件处理程序内部,对象this始终等于currentTarget,而target则指事件起源的元素,
如果直接将事件处理程序指定给目标元素,则this,currentTarget,target三者相同
兼容浏览器的事件对象
- event event || window.event
- target evnet.target || evnet.srcElement
- preventDefault evnet.preventDefault() || event.returnValue = true
- stopPropagation event.stopPropagation() || event.cancelBubble = true
事件类型
- UI load, unload, error,select, resize, scroll...
- input blur, focus, change
- 鼠标 click,mousedown/up,mouseenter/leave,mousemove...
- 键盘 keydown/up,keypress...
- 触摸 touchstart,touchend,touchmove...
- 手势 gesturestart, gestureend,gesturechange...
- 设备 orientationchange(检测设备屏幕旋转), deviceorientation(检测设备方向变化)。。。
内存和性能
事件委托/代理事件监听
事件委托(事件代理) 利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件,也就是说。可以为某个父类元素指定一个事件处理程序,不必为所有的子类元素都添加事件处理程序,通过event.target来判读是否是要触发的子类元素
只要指定一个事件处理程序,让父类做事件代理,节省了内存和性能
新增的子元素也能动态的绑定事件
移除事件处理程序
- 当移除绑定事件处理程序的元素时,也需要手动的移除事件处理程序
btn.onclick = null
body.removeChild(btn)
- 当页面卸载时,也会导致“空事件处理程序”
通过onunload事件 移除所有事件处理程序
一些常用操作
load 事件
load事件指在所有的资源被加载完成时触发
img.onload = function(){}
img只要设置了src属性就会开始下载
script.onload = function(){}
script只有设置了src属性并添加到文档后,才会开始下载js文件
onbeforeunload事件(H5事件)
离开一个页面的之前
页面添加onbeforeunload事件,会导致浏览器不对页面进行缓存
resize
屏幕resize,使用函数防抖
"获取鼠标在网页中的坐标"
e.clientX/target.clientY
// 水平滚动条偏移
document.documentElement.scrollLeft || // 火狐,IE9及以下滚动条是html的
document.body.scrollLeft ||//chrome 滚动条是 body
window.pageXOffset // IE10及以上
// 页面上的位置
e.pageX ||
e.clientX+ 水平滚动条偏移值
网友评论