class A{ //绑定事件的方法 bindEvent(){ let that = this; this.button1.on('click',function(e){ this.addClass('on'); //this指代所点的元素 that.doSomething(); //that指向类的this }) } doSomething(){ //事件处理函数 } //解绑事件 unBindEvent(){ this.button1.off(); } }
ES6中javascript实现函数绑定及类的事件绑定功能详(2)
这种方法只在使用jquery时有用,因为jquery解绑事件不需要提供回调函数,直接off就可以了。但是原生js需要提供回调函数也有它的道理,因为同一个元素的同一种事件可以绑定多个回调函数,所以你需要指出释放哪一个。
方案二:使用bind()改变this的指向
有类A,在A中要添加mousemove事件,根据需求写出下面代码:
class A{ //添加事件 addEvent(){ document.addEventListener( 'mousemove', onMouseMove, false ); } //添加事件 removeEvent(){ document.removeEventListener( 'mousemove', onMouseMove , false ); } } //事件回调函数中 function onMouseMove(event){ console.log(this); //#document }
但是,这样获取不到类的this。onMouseMove的this将会指向document。因为事件是添加到document上的,所以自然是由document触发事件并调用onMouseMove进行处理,所以onMouseMove中的this指向document。
比较正确的做法是:使用bind()
函数改变onMouseMove中this的指向,同时将事件回调函数移到类外面:
class A{ //添加事件 addEvent(){ document.addEventListener( 'mousemove', onMouseMove.bind(this), false ); } //添加事件 removeEvent(){ document.removeEventListener( 'mousemove', onMouseMove.bind(this) , false ); } } //事件回调函数中 function onMouseMove(event){ console.log(this); }
但是这样仍然存在问题,事件移除不掉了!因为this.bind()
每次调用都会返回一个新的函数,所以:
document.addEventListener( 'mousemove', onMouseMove.bind(this), false );
和
document.removeEventListener( 'mousemove', onMouseMove.bind(this), false );
两者的第二个参数并不相同。
正确的做法是: 将bind()
的结果保存到一个变量中:
class A{ constructor(){ this._onMouseMove = onMouseMove.bind(this); //看这里 } //添加事件 addEvent(){ document.addEventListener( 'mousemove', this._onMouseMove , false ); } //添加事件 removeEvent(){ document.removeEventListener( 'mousemove', this._onMouseMove , false ); } } //事件回调函数中 function onMouseMove(event){ console.log(this); }
内容版权声明:除非注明,否则皆为本站原创文章。