addEventListener之listener obj

今天在学习iscroll源码的时候,发现它的addEventListener函数第二个事件传入的是 IScroll 这个对象,而不是一个函数。

// this 就是 IScroll 对象
eventType(this.wrapper, 'touchstart', this);
eventType(target, 'touchmove', this);
eventType(target, 'touchcancel', this);
eventType(target, 'touchend', this);

谷歌之,MDN上就有相关介绍,嘿嘿

关于第二个参数 listener,  有下面一句话:

listener The object that receives a notification when an event of the specified type occurs. This must be an object implementing the EventListener  interface, or simply a JavaScript function.

四级水平翻译下: listener 是当有特定类型的事件触发时被通知的那个对象,该对象必须是一个实现EventListener接口的对象,或者是一个js函数.

如果传递的是一个对象,当有事件触发时,会调用对象下面的 handleEvent 方法

var obj = {
    name: 'foo',
    handleEvent: function (ev){
        switch(ev.type){
            case 'click':
            this.clickHandler();
            break;
        case 'mousedown':
            this.mousedownHandler();
            break;
        case 'mouseup':
            this.mouseupHandler();
            break;
        }
    },
    clickHandler: function (){
        console.log('click');
    },
    mousedownHandler: function (){
        console.log('mousedown');
    },
    mouseupHandler: function (){
        console.log('mouseup');
    }
};

document.addEventListener('click', obj, false);
document.addEventListener('mousedown', obj, false);
document.addEventListener('mouseup', obj, false);

 

使用listener object 有什么优势

1、自动绑定this为listener obj

obj 对象下面有个一个 init 方法,在该方法中绑定的事件只需传递this作为回调,当绑定的事件触发时 handleEvent  函数就会触发对应的事件处理函数,并且自动将 this 指向obj对象

var obj  =  {
    init: function() {
        document.getElementById("btn").addEventListener("click", this, false);
        document.getElementById("btn").addEventListener("touchstart", this, false);
    },
    handleEvent: function(e) {
        switch(e.type) {
            case "click":
                this.button();
                break;
            case "touchstart":
                this.button();
                break;
        }
    },
    dude: "holla",
    button: function() {
        alert(this.dude);
    }
};

obj.init();

2、方便解除事件绑定,我们只需要重新对 handleEvent  赋值即可,解决了 removeEventListener 不能解绑匿名函数的困难局面,尤其是ES5标准严格模式废除了 arguments.callee 之后。

changeHandleEvent: function(evt) {
    this._handleEvent = this.handleEvent;
    // Change the the handleEvent method without needing to remove 
    // and re-attach the event(s)
    this.handleEvent = function(e) {
        var t = evt.target;
        
        if (t.id === "btn") {
            // Check the button being clicked and do new stuff
        } else if(t.id === "btn3") {
            this.revertHandleEvent();
        }
    }
}

 

浏览器兼容性

机会所有支持 addEventListener 的浏览器都支持  handleEvent,除了 黑莓6浏览器,IE8及以下不支持  addEventListener

这里统一作  Polyfill

function on(el, evt, fn, bubble) {
 if("addEventListener" in el) {
        // BBOS6 doesn't support handleEvent, catch and polyfill
        try {
            el.addEventListener(evt, fn, bubble);
        } catch(e) {
            if(typeof fn == "object" && fn.handleEvent) {
                el.addEventListener(evt, function(e){
                    // Bind fn as this and set first arg as event object
                    fn.handleEvent.call(fn,e);
                }, bubble);
            } else {
                throw e;
            }
        }
    } else if("attachEvent" in el) {
        // check if the callback is an object and contains handleEvent
        if(typeof fn == "object" && fn.handleEvent) {
            el.attachEvent("on" + evt, function(){
                // Bind fn as this
                fn.handleEvent.call(fn);
            });      
        } else {
            el.attachEvent("on" + evt, fn);
        }
    }
}

 

参考网站: http://www.thecssninja.com/javascript/handleevent

posted @ 2015-09-26 14:44  胖子2  阅读(333)  评论(0)    收藏  举报