今天写BUG的时候,要在一个touchstart事件内添加 touchmove和touchend的事件注册。

然后,在touchend的时候再把2个事件给移除了。

之前一直不是很在意bind,apply,call一些细节的的我就在这里吃了亏,果然出来混的迟早要还的。

代码如下:

  1. dom.addEventListener('touchstart', fTouchstart.bind(this));
  2. function fTouchstart(e) {
  3. console.log('start:' + e, this); // TouchEvent对象,实例对象
  4. dom.addEventListener('touchmove', fTouchmove.bind(this));
  5. dom.addEventListener('touchend', fTouchend.bind(this));
  6. }
  7. function fTouchmove(e) {
  8. console.log(‘move:’ + e, this); // TouchEvent对象,实例对象
  9. dom.removeEventListener('touchmove', fTouchmove);
  10. dom.removeEventListener('touchend', fTouchend);
  11. }

然后在浏览器上换成移动端在dom上点击几次,你会发现end事件执行次数之后每次会递增1。


原因:

bind方法返回了一个新的函数。在removeEventListener中移除的事件并没有绑定在TouchEvnent上,绑定上去的是bind()方法每次返回的函数。


解决方法:

在外面保存bind()返回函数的引用。

修改上面代码:

  1. // 保存引用
  2. var fTouchstart_ = fTouchstart.bind(this),
  3. fTouchmove_ = fTouchmove.bind(this),
  4. fTouchend_ = fTouchend.bind(this);
  5. dom.addEventListener('touchstart', fTouchstart_);
  6. function fTouchstart(e) {
  7. console.log('start:' + e, this); // TouchEvent对象,实例对象
  8. dom.addEventListener('touchmove', fTouchmove_);
  9. dom.addEventListener('touchend', fTouchend_);
  10. }
  11. function fTouchmove(e) {
  12. console.log(‘move:’ + e, this); // TouchEvent对象,实例对象
  13. dom.removeEventListener('touchmove', fTouchmove_);
  14. dom.removeEventListener('touchend', fTouchend_);
  15. }