为什么这个react / javascript“ removeEventListener”不能删除监听器?

时间:2018-12-21 08:31:43

标签: javascript reactjs ecmascript-6 addeventlistener removeeventlistener

似乎未在此处删除侦听器。任何想法如何解决这个问题?我猜想这与我“共享”侦听器并且使用箭头功能(根据此处的建议https://medium.freecodecamp.org/reactjs-pass-parameters-to-event-handlers-ca1f5c422b9)有关

代码:

import * as React from 'react';

export default class ITestComponent extends React.Component { 

  public render() {
    return (
      <div>

        <div 
          onMouseDown={this.handleMouseDown('horizontal')}
          draggable={false}
          style={{ border: '1px solid blue', padding:20 }}
        >
          Horizontal Drag Test
        </div>

        <div 
          onMouseDown={this.handleMouseDown('vertical')}
          draggable={false}
          style={{ border: '1px solid green', padding:20 }}
        >
          Vertical Drag Test
        </div>

      </div>
    );
  }

  private handleMouseDown = (eType:string) => (e:any) => {
    console.log('Add Event Listeners (handleMouseDown)', eType)
    window.addEventListener('mousemove', this.handleMouseMove(eType))
    window.addEventListener('mouseup', this.handleMouseUp(eType))
  }

  private handleMouseMove = (eType:string) => (e:MouseEvent) => {
    console.log(' - handleMouseMove', eType, e.clientY)
  };

  private handleMouseUp = (eType:string) => (e:MouseEvent) => {
    console.log('Remove Listeners (handleMouseUp)', eType)
    window.removeEventListener('mousemove', this.handleMouseMove(eType))
    window.removeEventListener('mouseup', this.handleMouseUp(eType));
  };

}

控制台输出,单击“水平拖动测试”并向下拖动(按下鼠标按钮),然后释放鼠标按钮,然后再拖动一点。

Add Event Listeners (handleMouseDown) horizontal
 - handleMouseMove horizontal 61
 ...
 - handleMouseMove horizontal 220
 - handleMouseMove horizontal 221
Remove Listeners (handleMouseUp) horizontal
 - handleMouseMove horizontal 222
 - handleMouseMove horizontal 222
 - handleMouseMove horizontal 228
 ...

具体的问题是如何保留“重用”事件处理程序以用于多种目的的概念?

请注意,我在此处未使用匿名函数,如建议的答案之一(Javascript removeEventListener not working

1 个答案:

答案 0 :(得分:1)

即使您使用咖喱箭功能定义函数并执行this.handleMouseDown('horizontal'),每次都会返回一个新的函数实例,并且为了分配和删除eventListener,也需要传递相同的函数实例。您可以通过以下方式实现以上

import * as React from 'react';

export default class ITestComponent extends React.Component { 

  public render() {
    return (
      <div>

        <div 
          onMouseDown={this.handleMouseDown.bind(this,'horizontal')}
          draggable={false}
          style={{ border: '1px solid blue', padding:20 }}
        >
          Horizontal Drag Test
        </div>

        <div 
          onMouseDown={this.handleMouseDown.bind(this,'vertical')}
          draggable={false}
          style={{ border: '1px solid green', padding:20 }}
        >
          Vertical Drag Test
        </div>

      </div>
    );
  }

  private handleMouseDown = (eType:string, e:any) => {
    console.log('Add Event Listeners (handleMouseDown)', eType)
    this._handleMouseMove = this.handleMouseMove.bind(this, eType);
    this._handleMouseUp = this.handleMouseUp.bind(this, eType);
    window.addEventListener('mousemove', this._handleMouseMove)
    window.addEventListener('mouseup', this._handleMouseUp)
  }

  private handleMouseMove =  (eType: string, e:MouseEvent) => {
    console.log(' - handleMouseMove', eType, e.clientY)
  };

  private handleMouseUp = (eType:string, e:MouseEvent) => {
    console.log('Remove Listeners (handleMouseUp)', eType)
    window.removeEventListener('mousemove', this._handleMouseMove)
    window.removeEventListener('mouseup', this._handleMouseUp);
  };

}