jQuery源代码学习笔记_bind

一般想到JS的兼容性问题的时候,首先会想到addEventListener与attachEvent这一对冤家,那么我们先来看看它们有什么兼容性问题

addEventListener与attachEvent区别:

一般我们在JS中添加事件,是这样子的

obj.onclick=method

这种绑定事件的方式,兼容主流浏览器,但如果一个元素上添加多次同一事件呢?

1. obj.onclick=method1;

2. obj.onclick=method2;

3. obj.onclick=method3;

如果这样写,那么只有最后绑定的事件,这里是method3会被执行,这个时候我们就不能用onclick这样的写法了,在IE中我们可以使用attachEvent方法

//1. object.attachEvent(event,function);

2. btn1Obj.attachEvent("onclick",method1);

3. btn1Obj.attachEvent("onclick",method2);

4. btn1Obj.attachEvent("onclick",method3);

火狐和其他浏览器都不支持,他们都支持W3C标准的addEventListener方法

//element.addEventListener(type,listener,useCapture);

btn1Obj.addEventListener("click",method1,false);

btn1Obj.addEventListener("click",method2,false);

btn1Obj.addEventListener("click",method3,false);

从上面两个例子可以看到,addEventListener与attachEvent有不同的。关于两者区别,几乎很多前端面试都会考察到,下面再回忆一下:
![](//images0.cnblogs.com/blog2015/629726/201504/021112104202814.jpg)

### 解决作用域问题

由于attachEvent执行函数时,作用域是window,因此我们需要对传入的函数进行处理,让它可以指向正确的对象,这里面我们就用到了jquery中的一个方法$.proxy,不过更多的类库包括ES5都喜欢把这个函数叫bind,所以我这还是说bind,这个函数的作用是固定一个函数的调用对象,代码如下:

```javascript

    var slice = [].slice;

    /**
     * 固定函数的`this`变量和若干参数
     *
     * @param {Function} fn 操作的目标函数
     * @param {Object} context 函数的`this`变量
     * @param {*} [args] 函数执行时附加到执行时函数前面的参数
     * @return {Function} 固定了`this`变量和若干参数后的新函数对象
     */
    function bind(fn, context, args) {
        args = slice.call(arguments, 2);
        return fn && function () {
            return fn.apply(context, args.concat(slice.call(arguments)));
        };
    }

有了bind函数之后,我们就可以轻松的实现事件处理的兼容性了:

处理事件兼容

function addEvent(ele, type, fn) {
	// 有addEventListener时优先使用
	if(ele.addEventListener){
		// 由于IE不支持捕获,所以所有的都用冒泡
		ele.addEventListener(type, fn, false);
	}else{
		// 加一个on处理事件名不同的问题
		// 使用bind让fn指向ele,以使attachEvent的行为和addEventListener一样
		ele.attachEvent('on' + type, bind(fn, ele));

	}
}
posted @ 2015-04-02 11:05  青青flye  阅读(300)  评论(0编辑  收藏  举报