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); } } }

浙公网安备 33010602011771号