Cannot delete Listener event without understanding my error

I have an event listener that is assigned to a div using a click listener.

The problem is that it does not remove the listener, which it simply continues to add to it.

This is the script where this happens:

 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 in action, just move the slider and press the button, then it will call the function to which the listener is assigned and count how many times it has been called.

JSFIDDLE LINK

I hope someone can explain my mistake as it confuses it because my script gets complicated!

+4
source share
2 answers

The problem is that the function you are trying to delete is never added, and therefore nothing is deleted.

Each call to your resourceCheckout function creates a new assign function, which is then used by your calculate function. Since this is a new assign function, it has never been added to a button, so calling removeEventListener and passing it has no effect.

If the previous call to resourceCheckout placed the assign button on the button, you must use the same function link 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 is 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 need to remember the previous assign and use it to remove the handler.

You asked in a comment why this does not apply to the code of the slider in the violin, which looks like this (since this is not the question):

 // The OP 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 the handler from the body element. It works because the startSlider code has a link to the endSlider function, which was created at the same time that startSlider was created (the same initSlider call). Since startSlider has a link to the same function that was used with addEventListener , removeEventListener works.

+4
source

This code potentially adds a new listener for the event each time it is called.

Also, note that each time you call ResourceCheckout , a new different function object is created for the assign variable, and therefore removeEventListener will never succeed, because only this one was just created and the event was never registered (the one registered was another function object created in the previous call).

0
source

Source: https://habr.com/ru/post/1491571/


All Articles