Reputation: 8280
I have a event listener which is assigned to a div
using the click
listener.
The problem is it does not remove the listener it just keeps adding to it.
This is the script where it is happening:
var resourceCheckout = function (quantity,btn){
//quantity = integer
// btn = document.getElementByID('the_div');
var calculate = function (e) {
var allowed = false;
for(var i in test){
var total = quantity * test[i].q;
if(total > 200){ //if total > 200 remove eventListener
allowed = false; break;
} else {
allowed = true;
}
};
if(allowed){
btn.addEventListener('click',assign,false);
} else {
btn.removeEventListener('click', assign ,false);
}
};
var assign = function (e) {
do_it(quantity); //this gets called more than once when it should be
// a maximum of one
};
calculate();
};
I decided to make a working jsfiddle to show you it in action, simply move the slider then hit the button, it will then call the function the listener is assigned to and count how many times it was called.
I hope someone can explain my mistake as its getting confusing to understand as my script gets more complicated!
Upvotes: 4
Views: 165
Reputation: 114461
This code potentially adds a new listener for the event each time it is called.
Also note that every time you call ResourceCheckout
a new different function object is created for variable assign
and therefore the removeEventListener
will never succeed because that specific function object passed has just been created and was never registered for the event (what was registered was a different function object, created in a previous call).
Upvotes: 0
Reputation: 1074048
The problem is that the function you try to remove has never been added, and so nothing is removed.
Every call to your resourceCheckout
function creates a new assign
function, which is then used by your calculate
function. Since it's a new assign
function, it cannot have ever been added to the button, so calling removeEventListener
and passing it in has no effect.
If a previous call to resourceCheckout
put an assign
on a button, you have to use that same function reference to remove it.
This may be clearer with a simpler example:
function foo() {
function bar() {
}
return bar;
}
foo
creates a new bar
function every time it's called. So:
var b1 = foo();
var b2 = foo();
console.log(b1 === b2); // false
b1
and b2
are different functions.
To make your resourceCheckout
work, you'd need to remember the previous assign
and use that to remove the handler.
You asked in a comment why this doesn't apply to the slider code in the fiddle, which looks like this (since it's not in the question):
// The OP's slider code
var initSlider = function (el,func,data) {
var clickX = null;
var startSlider = function (e) {
clickX = e.pageX;
document.body.addEventListener('mousemove', calc, false);
document.body.addEventListener('mouseup', endSlider, false);
};
var endSlider = function (e) {
document.body.removeEventListener('mousemove', calc, false);
document.body.removeEventListener('mouseup', endSlider, false);
};
var calc = function (e) {
var dif = e.pageX - clickX;
clickX = e.pageX;
var parentWidth = parseInt(window.getComputedStyle(el.parentNode).width);
var childWidth = parseInt(window.getComputedStyle(el).width);
var childLeft = parseInt(window.getComputedStyle(el).left);
var left = childLeft + dif;
if (left < 0) { left = 0; }
else if (left > (parentWidth-childWidth)) { left = (parentWidth-childWidth); }
el.style.left = left + 'px';
func(data,left,parentWidth-childWidth);
};
el.addEventListener("mousedown", startSlider, false);
};
There, the startSlider
code successfully removes a handler from the body
element. It works because the startSlider
code has a reference to the endSlider
function that was created at the same time startSlider
was created (the same call to initSlider
). So since startSlider
has a reference to the same function that was used with addEventListener
, removeEventListener
works.
Upvotes: 4