本文首次发布于 tinypoint`s blog, 作者 @张小点(tinypoint) ,转载请保留原文链接.
前言
本文带我们去回顾js中事件的相关知识
事件流
“DOM2级事件”规定事件流包括三阶段:
- 事件捕获阶段(不具体到具体)
- 目标阶段
- 事件冒泡阶段(从具体到不具体)
处于目标阶段,事件发生,在事件处理中被算作冒泡阶段的一部分。
“DOM2级事件”明确要求捕获阶段不会涉及事件目标,但是IE9,Safari,Chrome,Firefox和Opera9.5及更高版本都会在捕获阶段触发事件对象上的事件。结果,就是有两个机会在目标对象上面操作事件。<p style="text-align:right">–JavaScript高级程序设计(第3版)</p>
事件处理程序(事件监听)
html事件监听
利用html属性,on + 事件名小写,值为js表达式,或一个函数,可接受一个event参数,函数内this指向事件的目标元素
<button onclick="clickMe()">click me</button>
DOM0级事件监听
var btn = document.getElementById('btn');
// 添加
btn.onclick = function () {
alert('Hi');
}
// 删除
btn.onclick = null;
DOM2级事件监听
addEventListener, reomveEventListener 接受三个参数:事件名,事件处理函数,表示在什么阶段调用处理程序的布尔值,true表示在捕获阶段,false在冒泡阶段,一般用false
function fn () {
alert('Hi');
}
var btn = document.getElementById('btn');
// 添加
btn.addEventListener('click', fn,false)
// 可以添加多个,但是匿名函数不能通过removeEventListener移除
btn.addEventListener('click', function() {alert('Hello')}, false);
// 删除
btn.removeEventListener('click', fn, false);
兼容各个浏览器的事件处理程序
var EventUtil = {
addHandler: function (elem, type, handler) {
if (elem.removeEventListener) {
elem.removeEventListener(type,handler, false);
} else if (elem.attachEvent) {
elem.attachEvent('on' + type, handler);
} else {
elem.['on' + type] = handler;
}
},
removeHandler: function (elem, type, handler) {
if (elem.addEventListener) {
elem.addEventListener(type,handler, false);
} else if (elem.attachEvent) {
elem.detachEvent('on' + type, handler);
} else {
elem.['on' + type] = null;
}
}
}
事件对象
DOM中的事件对象
bubbles是否冒泡cancelable是否可以取消默认行为currentTarget你注册事件的那个元素,函数内this始终等于currentTargettarget触发事件的实际元素defaultPrevented是否调用了preventDefaul()detail事件相关的细节信息eventPhase事件的阶段,1-2-3分为对应捕获-目标-冒泡preventDefault()取消默认事件stopImmediatePropagation()取消捕获或冒泡,同时阻止任何事件stopPropagation()取消捕获或冒泡trustedtrue表示是浏览器生成的,false表示是开发人员注册的view事件发生的视图,指向window
IE中的事件对象
DOM0级的event被保存在window.event中,DOM2级的event会被当做参数传入
cancelBubble默认为false,为true代表可以取消事件,类似stopPropagation()returnValue默认为true,为false表示取消默认,类似preventDefault()srcElement等同target
事件类型
UI事件
1.load
windowimg指定src就开始下载。scriptlink和script一样,指定了src或者href而未插入到文档中,不会开始下载。
2.unload
文档一切都卸载之后触发,一般用于引用清除,以避免内存泄漏。
要小心使用unload事件,因为页面的对象就不存在了。
貌似Chrome不支持onunload事件,IE支持。
3.resize
几个简单的获取窗口宽高的方法:
document.body.clientWidthdocument.body.offsetWidthdocument.body.scrollWidth
4.scroll
scrollTopscrollLeft
焦点事件
-
blur失焦触发,不会冒泡,所有浏览器支持
-
focusout失焦触发,冒泡,IE5.5+,Safari5.1+,Opera11.5+,Chrome支持
-
focus获得焦点触发,不会冒泡,所有浏览器支持
-
focusin获得焦点触发,冒泡,IE5.5+,Safari5.1+,Opera11.5+,Chrome支持
鼠标与滚轮事件
- click(mousedown > mouseup > click)
- dobuleclick(两个click)
- mousedown
- mouseup
- mouseenter(不冒泡)
- mouseleave(不冒泡)
- mouseout
- mouseover
- mousemove
mouseenter和mouseleave相比较mouseover和mouseout,前二者不冒泡,后二者冒泡
- 修改键
event.shiftKey,event.ctrlKey,event.altKey,event.metaKey - 屏幕坐标
screenX,scrrenY - 浏览器视口坐标
clientX,clientY - 页面坐标
pageX,pageY
IE8之前不支持页面坐标,可以通过client和scroll换算出来
function getPageXAndY (event) {
var pageX = event.pageX;
var pageY = event.pageY;
if (pageX === undefined) {
pageX = event.clientX + (docuemnt.body.scrollLeft || document.documentElement.scrollLeft);
pageY = event.clientY + (docuemnt.body.scrollTop || document.documentElement.scrollTop);
}
return {
pageX: pageX,
pageY: pageY
}
}
-
mouseover和mouseout特有事件对象属性relatedElement(其他事件该值为null),IE8之前不支持,有类似的fromElement和toElement -
鼠标按钮,事件对象的button属性,0主鼠标按钮,1中间按钮,2次鼠标按钮,IE有更多的button属性
-
其他事件信息
altLeft,ctrlLeft,offsetX,offsetY,shiftLeft
- 滚轮事件
参考