为了能够更加直观的来了解事件的运作的整个流程,我们先来看看下面这个简单的HTML代码:
<html><body><div>My Div</div></body></html>
当我点击My Div的时候,会触发click事件,它的具体流程如下图所示:
从上图所示我们可以看出,当我们点击My Div时,首先触发的是Event Capturing Phase,自顶向下,依次经过html > body > div,最后到达指定目标对象,然后接下来它并没有到此停止,而是继续往上bubble,触发Event Bubbling Phase。所以,一个完整的事件流程为:Capturing Phase => Target Event => Bubbling Phase
Event Types
从大的方向上来说,JavaScript的事件可以大致归类为一下几大类别:
- UI事件,例如focus, blur事件
- 鼠标事件,例如mousedown, mouseup,click, dbclick
- 键盘事件,例如keydown, keypress, keyup
- 页面事件,例如load,unload
- 表单事件,例如submit, select, change
Binding Events
一般来说,我们可以通过以下的三种方式来给DOM元素绑定特定的处理事件,每种方式各有利弊,具体如下所示:
Traditional Event Binding
最常见的,适用性最为广泛的是传统方式,或者也称之为DOM0的Event Binding方式,具体的展现方法如下代码所示:
window.onload = function (event) { // event handling details } document.getElementById('id').onclick = function (event) { // event handling details }
使用这种方法的好处如下:
- 适用性最为广泛,基本上所有的浏览器都支持这种方法
- 当使用这种方式绑定事件的时候,关键字this指向当前的操作元素,这对于后续的操作有很大的便利之处
使用这种方法的弊端如下:
- 这种方法只能是适用于事件的Bubbling Phase,不能对Capturing Phase做任何的处理
- 这种方法所绑定的handler,对于IE浏览器,不会传递入event对象,想要获取IE下的event对象,必须通过window.event来获得
- 这种方法只能够绑定一个特定事件,当绑定多个事件的时候,后面的事件会覆盖掉前面的处理事件
W3C Event Binding
现代浏览器绝大部分都支持这种事件绑定的方法,具体的操作方式如下所示:
var myId = document.getElementById('id'); myId.addEventListener('click', myHandler, false); function myHandler(event) { alert('button was clicked!'); }
使用这种方法的好处如下:
- 使用这种方法,可以针对Capturing/Bubbling Phase进来特定的事件绑定操作,addEventListener方法总共有三个参数,第一个参数是事件触发的类型,第二个是这对这个触发事件所要绑定的事件,第三个参数是一个布尔变量,false表示Bubbling Phase
- 使用这种方法可以针对某一个事件类型,绑定多以处理事件,而相互之间又不会互相影响
- 在绑定的处理方法中,关键字this指向现在当前的操作对象
- 你可以轻松获取到绑定方法的event对象,它被以第一个参数的形式带入到执行方法中
使用这种方法的弊端如下:
- 不适用于旧版本的IE浏览器,对于旧版IE,需要使用attachEvent来进行事件的绑定,具体见下面小节所示
Internet Event Binding
var myId = document.getElementById('id'); myId.attachEvent('onclick', myHanlder); function myHandler() { alert('button was clicked!'); }
使用这种方法的好处如下:
- 使用这种方法可以针对某一个事件类型,绑定多以处理事件,而相互之间又不会互相影响
使用这种方法的弊端如下:
- 只适用于IE浏览器的操作
- 在绑定的处理事件中,关键字this,指向的是window对象
- 只能处理Bubbling Phase
- 想要获取event对象,必须通过window.event来获得
鉴于不同的浏览器有不同的具体实现,为了能够更好的操作事件,我们有必要开发一个辅助方法,来提供跨浏览器的支持,以下就是一个小小的Demo,仅供参考: