2

我是 javascript 的新手,遇到以下问题,在多次搜索后我无法在以前的答案中找到(希望这不是重复的)。

我有以下模块/类。假设我正在尝试实现一个可以在屏幕上拖动的组件。当用户第一次点击它时,我们开始监听 的mousemove事件window以了解用户将鼠标移动到哪里。一旦用户释放鼠标,我们想要移除窗口的事件监听器。该代码非常简单,如果我只是在 iife 之外对其进行编码,它就可以工作。但是,目前removeEventListener根本行不通。我想这可能与clousure范围或其他东西有关,但我完全错过了它。非常感谢您,这里是代码:

MyClass.js

 var myNamespace = myNamespace || {};
 (function(myNamespace){

 var onMouseDragDown = function(e){
          window.addEventListener("mousemove", onMouseDragMove,true);
          window.addEventListener("mouseup", onMouseDragUp,false);
       };

  var onMouseDragUp = function(e){
// This code executes, but the events CONTINUE to be triggered after removing the event listener

//The following lines do not seem to have any effect whatsoever even though they are executed when the user releases the mouse button
      window.removeEventListener("mousemove", onMouseDragMove, true);
      window.removeEventListener("mouseup", onMouseDragUp,false);
  };

  var onMouseDragMove = function(e){
      console.log('moving');
   };

   myNamespace.MyClass = function(param){
      this._param = param;
      this._div = document.createElement('div');  
      this._div = ....

      this._div.addEventListener('mousedown', onMouseDragDown.bind(this), false);
   }

   myNameSpace.MyClass.prototype.getDiv = function (){
      return this._div;
   }
)(myNameSpace);

索引.html

...

        function onCreateNewDocumentClicked(event){
            var myObject = new myNamepace.MyClass(someParams);
            document.body.appendChild(mdi.getDiv());
        }
4

2 回答 2

5

要删除事件侦听器,您必须提供添加时提供的确切功能。
这里发生的是 bind() 每次都会创建一个新函数,所以实际上:

someFunc.bind(someObj) !== someFunc.bind(someObj)

要删除事件侦听器,您必须存储添加时提供的功能。

所以当你添加它时存储监听器以便以后能够删除它:

var someListener = someFunc.bind(someObj);
element.addEventListener("--", someListener ) ;

// then, later :
element.removeEventListener('--', someListener);

我在这里做了一个简短的演示,当你点击第一个按钮时,它会提示“你好”。
我们看到,通过使用新的 bind 调用移除监听器,它并没有移除它。
然后删除存储的功能就可以完成这项工作。

http://jsbin.com/EjevIQA/2/edit

编辑:您不需要为要拖动的每个 div 添加/删除侦听器。相反,您可以只听窗口内的点击,并利用事件的“目标”信息,这将告诉您点击了哪个 div。
也许你会想要停止传播/防止默认当它是一个被点击的被处理的 div 时,我不知道。

事件处理程序将如下所示:

 function handleMouseDown(e) {
     // you might check here which button was clicked (0=left, 2=right)
     var button = e.button;
     // retrieve the target
     var target = e.target ;
     // check if the target is an object we want to drag
     ...
     ... return otherwise.
     // do some things to initialize the drag.
     ...
     // you might want to prevent the click to bubble / trigger default behaviour :
     e.stopPropagation();
     e.preventDefault();
 } 

您在窗口或文档对象上一劳永逸地设置它:

document.addEventListener("mousedown", handleMouseDown)

我在这里做了一个小演示,点击一个 div 看看它已经被识别了:http:
//jsbin.com/ilavikI/2/edit

于 2013-09-22T11:17:14.593 回答
1

难道是你的

 .bind(this) 

  this._div.addEventListener('mousedown', onMouseDragDown.bind(this), false);

不返回对您要删除的同一函数的引用?

于 2013-09-22T11:11:24.497 回答