JavaScript中的事件处理程序
前言
关于JavaScript中的事件,我们首先会想到的就是两种事件流:事件冒泡和事件捕获,事件流在前端面试中也问的比较多,但是从我工作的实际经验来看,事件冒泡和事件捕获的区分在工作中涉及的比较少。反倒是为事件指定处理程序用的非常多。今天我就把事件处理程序总结一下。
概念
事件处理程序就是当指定的事件发生时的处理方式,比如说我们在网页上点击一个按钮,弹出了一个弹窗,这时候 点击 就是事件,而 弹出一个弹窗 就是相对应的事件处理程序。
简单吧?那么我们怎么为一个事件添加事件处理程序呢?以前我并没有总结过,只知道有那么几种方式,总结了之后,才对事件以及事件处理程序有一个完整的了解。
事件处理程序
事件处理程序按照指定方式的不同可以分为:
- HTML事件处理程序
- DOM0级事件处理程序
- DOM2级事件处理程序
在DOM0级/DOM2级事件处理程序中,又涉及到IE/非IE事件处理程序。
HTML事件处理程序
HTML事件处理程序就是在HTML代码里为元素指定事件处理程序.
1 | <input type="button" value="点击" onclick="alert('test')"> |
这种方式有两个很明显的缺点:
- 当需要为多个同样的元素绑定相同的事件处理程序时,需要重复添加
onclick="alert('test')"
这段代码,很明显这样是很麻烦的,并且也违背了将HTML与JavaScript分离的原则。 - 如果用户在DOM内容加载之后,js文件加载之前点击了按钮,那就会报错。
DOM0级事件处理程序
DOM0级事件处理程序是先获取元素,然后为元素指定事件处理程序
1 | <input type="button" value="点击" id="btn"> |
这种方式就避免了上文提到的DOM0级事件处理程序的两个问题,但是又有新的问题。当为一个元素指定了两个及多个同类型的事件处理程序后,后面的会将前面的覆盖。在上面的例子中,点击按钮,之后只会弹出b,虽然说这种情况比较少(如果有的话也可以通过把程序写在一个函数里来避免),但终究不是好的解决方法。
想要删除事件处理程序的话只需要使用btn.onclick = null
,这时候就会把为btn
指定的所有click事件
全部去掉,很明显,这也不是一种好的处理方式。
DOM2级事件处理程序
DOM2级事件处理程序有两个方法:addEventListener()
和removeEventListener()
。分别用于绑定事件和解除绑定。使用方法和DOM2级事件处理程序类似,先获取元素然后指定事件。
1 | <input type="button" value="点击" id="btn"> |
这种方法相比DOM0级事件处理程序,好处是可以为同一个元素绑定多个相同类型的事件,不会彼此覆盖。
1 | <input type="button" value="点击" id="btn"> |
这两个函数的最后一个参数都必须要有,表示调用事件处理程序的时间,为true表示在捕获阶段调用,为fasle表示在冒泡阶段调用。不过在我实际的工作中,很少需要特意区分冒泡和捕获,一般都是把最后一个参数设置为false。
IE事件处理程序
IE中有两个事件处理程序:attachEvent()
和detachEvent()
,其使用形式和DOM2级的事件处理程序类似,值得注意的是设置事件名的时候需要在事件名前加on
.
1 | <input type="button" value="点击" id="btn"> |
在使用detachEvent()
解除绑定时,用法和removeEventListener()
一样,无法解除绑定的匿名函数处理程序,只能解除通过相同参数设置的处理程序。
需要注意的是:不要因为IE自己定义了两个方法,就认为DOM2级的方法在IE中不能用,DOM2级的方法在IE9+中都是可以使用的。
事件在工作中的实际使用
在工作中一般都使用了某个JavaScript框架,框架本身提供了绑定事件的方法。这个时候的原则是:能使用 事件代理 就使用 事件代理 。事件代理的好处在我看来主要有两个:
- 防止了可能因为资源加载的问题找不到元素而报错的情况。
- 为多个同类型元素绑定同类型事件时不需要一个一个绑定。只需要绑定一次就行。