以点击事件为例,看一下事件的绑定。
绑定事件
1.句柄方式
div.onclick = function (e) {
console.log('click');
}
事件可以持续监听,并不是执行完一次就失效,因此这个事件监听部分并不属于js引擎,因为js引擎是单线程的,事件监听属于内核的其他模块部分。
句柄方式的兼容性很好,但是一个元素的一种事件只能绑定一个函数。
2.ele.addEventListener(type, handle, false)方法。
div.addEventListener(‘click’, function(e) {
console.log(‘a’);
}, false);
这里面有三个参数,第一个参数是事件类型,第二个参数是处理函数,第三个参数是是否捕获。
这种方法一种事件可以绑定多个函数,但是同一个处理函数只能绑定一次。
function test1 () {
console.log('a');
}
function test2() {
console.log('b');
}
div.addEventListener('click', test1, false);
div.addEventListener('click', test2, false);
// 同时打印 a b
因为这种方法ie不支持,所以ie浏览器只有事件捕获没有事件冒泡。
3.ele.attachEvent(‘on’ + type, handle)
div.attachEvent('onclick', function (){
console.log('a');
});
基本和addEventListener差不多,但是有一点区别是,当同一个函数绑定多次的时候,addEventListener是只执行一次,但是attachEvent会绑定几次执行几次。
事件处理程序的运行环境
1.句柄绑定方式中,函数里面的this指向元素本身。
2.addEventListener方式中,函数里面的this也是指向元素本身。
3.attachEvent中,函数里面的this指向的是window而不是元素本身,这算是IE的一个BUG。针对这种情况,我们就需要把函数提取出来,然后在attachEvent的时候用call来改变函数内部this的指向。
兼容性的事件绑定函数
function attachEvent(ele, type, handle) {
if (ele.addEventListener) {
ele.addEventListener(type, handle, null);
}else if (ele.attachEvent) {
ele['temp' + type + handle] = handle;
ele[type + handle] = function () {
ele['temp' + type + handle].call(ele);
};
ele.attachEvent('on' + type, ele[type + handle]);
}else {
ele['on' + type] = handle;
}
}
解除事件处理程序
1.句柄方式
ele.onclick=null
2.ele.removeEventListener(type, handle, false)
但是这里要注意,只有命名函数才可以解除绑定,当绑定的函数是匿名函数的时候,是没有办法解除绑定的。
div.addEventListener('click', function (){
console.log('a');
}, false);
div.removeEventListener('click', function (){
console.log('a');
}, false);
// 这是没有办法解除绑定的,因为这是两个匿名函数。
3.ele.detachEvent(‘on’ + type, handle)
针对IE的attachEvent的解除绑定。
封装兼容性的解除绑定函数
function remvoeEvent(ele, type, handle) {
if(ele.removeEventListener) {
ele.removeEventListener(type, handle, false);
}else if (ele.detachEvent) {
ele.detachEvent('on' + type, handle);
}else {
ele['on' + type] = null;
}
}