学习要点:
1.问题所在
2.设置代码
本节课,我们主要探讨一下事件绑定,在此之前我们都使用的是传统的事件绑定。这节
点,我们想使用现代绑定对事件进行绑定和删除。
一.问题所在
现代绑定中 W3C 使用的是:addEventListener 和 removeEventListener。IE 使用的是
attachEvent 和 detachEvent。我们知道 IE 的这两个问题多多,并且伴随内存泄漏。所以,解
决这些问题非常有必要。
那么我们希望解决非 IE 浏览器事件绑定哪些问题呢?
1.支持同一元素的同一事件句柄可以绑定多个监听函数;
2.如果在同一元素的同一事件句柄上多次注册同一函数,那么第一次注册后的所有注册都被忽略;
3.函数体内的 this 指向的应当是正在处理事件的节点(如当前正在运行事件句柄的节点);
4.监听函数的执行顺序应当是按照绑定的顺序执行;
5.在函数体内不用使用 event = event || window.event; 来标准化 Event 对象;
二.设置代码
//跨浏览器添加事件
function addEvent(obj, type, fn) {
if (typeof addEventListener != 'undefined') {
obj.addEventListener(type, fn, false);
} else if (typeof attachEvent != 'undefined') {
obj.attachEvent('on' + type, fn);
}
}
//跨浏览器删除事件
function removeEvent(obj, type, fn) {
if (typeof removeEventListener != 'undefined') {
obj.removeEventListener(type, fn);
} else if (typeof detachEvent != 'undefined') {
obj.detachEvent('on' + type, fn);
}
}
上面的这两个函数解决了:1.同时绑定多个函数;2.标准 event;
上面的这两个函数没有解决的问题:1.IE 多次注册同一函数未被忽略;2.IE 中顺序是倒
序;3.IE 中 this 传递过来的是 window
为了解决 this 传递问题,我们需要使用匿名函数+传递方式参数的方式来解决:
obj.attachEvent('on' + type, function () {
fn(obj);
});
addEvent(oButton, 'click', function (_this) {
alert(_this.value);
});
这种方式比较古板,更好一点的方式是使用 call 来冒充对象。
obj.attachEvent('on' + type, function () {
fn.call(obj);
});
addEvent(oButton, 'click', function () {
alert(this.value);
});
call 的用法回忆一下:
fn.call(obj); //this 就是 obj 对象
fn.call(123); //this 就是 123
fn.call(123,456); //this 就是 123,第一个参数是 456
PS:也就是说,使用了 call 第一个参数就是 this 获取,从第 2 个参数开始,可以通过函
数参数获取,以此类推。
使用了 call 传递 this,带来的诸多另外的问题:1.无法标准化 event;2.无法删除事件。
导致的原因很明确,就是使用了匿名函数。标准化 event 可以解决,无法删除事件就没有办
法了,因为无法确定是哪一个事件。
obj.attachEvent('on' + type, function () {
fn.call(obj, window.event);
});
那么最终有几个问题无法解决:1.无法删除事件;2.无法顺序执行;3.IE 的现代事件绑
定存在内存泄漏问题。
网友评论