Reputation: 2046
I am a newbie on javascript and I am encountering the following problem, which I wasn't able to find in previous answers after searching multiple times (hope this is not a duplicate).
I have the following module/class. Let's suppose that I am trying to implement a component which can be dragged around the screen. When the user clicks on it the first time, we start to listen to the mousemove
events of the window
to know where the user is moving the mouse to. Once the user releases the mouse, we want to remove the event listeners of the window.
The code is quite straight forward, and it works if I just code it outside of an iife. However, currently the removeEventListener
simply does not work. I guess it might have something to do with the clousure, the scope or something, but I am totally missing it. Thank you very much in advance, here is the code:
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);
Index.html
...
function onCreateNewDocumentClicked(event){
var myObject = new myNamepace.MyClass(someParams);
document.body.appendChild(mdi.getDiv());
}
Upvotes: 2
Views: 2440
Reputation: 19294
To remove an event listener, you must provide the exact function that you provided when adding it.
What's happening here is that bind() creates a new function each time, so in fact :
someFunc.bind(someObj) !== someFunc.bind(someObj)
to remove an event listener, you have to store the very function that you provided when adding it.
so store the listener when you add it to be able to remove it later :
var someListener = someFunc.bind(someObj);
element.addEventListener("--", someListener ) ;
// then, later :
element.removeEventListener('--', someListener);
i made a short demo here, when you click on first button it will alert 'hello'.
We see that by removing the listener with a new call to bind, it doesn't remove it.
Then removing the stored function does the job.
http://jsbin.com/EjevIQA/2/edit
Edit : you don't need to add / remove a listener to each div you want dragged.
instead, you could just listen to click within the window, and make use of the 'target'
information of the event, which will tell which div was clicked.
Maybe you'll want to stop propagation / prevent default when it is a handled
div which is clicked, i don't know.
the event handler will look like :
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();
}
you set it up once and for all on the window or document object :
document.addEventListener("mousedown", handleMouseDown)
I made a tiny demo here, click on a div to see that it has been identified :
http://jsbin.com/ilavikI/2/edit
Upvotes: 5
Reputation: 651
Could it be that your
.bind(this)
in
this._div.addEventListener('mousedown', onMouseDragDown.bind(this), false);
does not return the reference to the same function you are removing?
Upvotes: 1