事件委托之一二事

事件

事件是指用户或者浏览器自身执行的某种动作, 例如点击事件(click), 鼠标事件(mouseover),按键事件(keyup) 等,为响应某个事件的函数叫做事件处理程序(监听器)

事件委托/代理

首先之所以需要有时间委托这个概念, 是因为考虑到内存开销和性能优化.试想一下如果我们为了操作一个DOM而到处声明新的引用(对象),会导致增加DOM的访问次数,而JS中函数也是一个对象,对象需要内存空间,所以性能会受影响,如果我们可以在页面生命周期的任何时间点是为它添加事件处理程序,无需等待DOMContentLoaded和load 这两个过程, 并且在同一个范畴内的事件处理程序能够被重用,那么DOM引用减少,内存得到释放,性能就上来.

所谓的事件委托,是利用了冒泡事件, 通过制定一个处理程序去管理同一类型的事件

1
2
3
4
5
<ul id="mylick">
<li id="1">1</li>
<li id="2">2</li>
<li id="3">3</li>
</ul>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var list = document.getElementById('mylick')
list.addEventListener('click', function(event) {
var target = event.target.id
switch (target) {
case '1':
alert(1)
break;
case '2':
alert(2)
break;
case '3':
alert(3)
break;
default:
break;
}
}, false)

ul下的子元素都公用同一个事件处理程序,这就是事件委托

DOM0级事件

传统的事件处理程序,将一个函数赋值给一个事件处理程序属性

1
2
3
btn.onclick = function () {
...
}

DOM2级事件

DOM2 包含addEventLinstenerremoveEventLinstener两个处理事件方法,接收三个参数: 事件处理名称, 处理函数 和一个布尔值, true表示采用事件捕获, false表示采用事件冒泡

1
2
3
4
5
var handler = function () {
...
}
btn.addEventListener('click', handler, false)
btn.removeEventListener('click', handler, false)

IE事件处理

IE跟DOM有所区别, 它提供了attachEvent和detachEvent 两个事件处理方法,但attachEvent()添加的事件处理都会默认被添加到事件冒泡阶段.
跟DOM2不同的是, 第一个参数指定的时间名必须是”on+type”开头,而且,attachEvent事件处理是在全局作用域中执行,而DOM却是在所属元素作用域中执行,这一点要注意.

跨浏览器限制

我们可以用polyfill写法来越过浏览器对事件处理的差异,一般做法是提供addHandler和removeHandler这两个Api, 分别传入三个参数: 操作元素, 事件名称, 事件处理函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var EventUtil = {
addHandler: function (ele, type, fn) {
if (ele.addEventListener) {
ele.addEventListner(type, fn, false)
} else if (ele.attachEvent) {
ele.attachEvent('on'+type, fn, false)
} else {
ele['on'+type] = fn
}
},
removeHandler: function (ele, type, fn) {
if (ele.removeEventListener) {
ele.removeEventListner(type, fn, false)
} else if (ele.detachEvent) {
ele.detachEvent('on'+type, fn, false)
} else {
ele['on'+type] = null
}
},
}


参考资料: 红宝书

感谢您的阅读,本文由 lynhao 原创提供。如若转载,请注明出处:lynhao(http://www.lynhao.cn
webpack渐入佳境
{}+{} in Javascript