pradeep Arora
pradeep Arora

Reputation: 63

Can't remove event listener

Can anyone tell why bt2 event listener is not getting removed in if block. As when I remove the event listener in the p function, it's getting removed without any error or bug. I am pretty sure there might be any stack or scope problem due to which event listener is not getting removed but I can't figure out what that could be. And I know that event listener is not getting removed as with the succeeding clicks on bt2 element all the preceding event listeners are also running again, as the same function is running multiple times. Please tell me what's the problem.

Here's the full code:

    (function()
    {
        if(window.addEventListener) window.addEventListener('load',init,false);
        function init()
        {   var i=0;
            var get=document.getElementById('bt1').addEventListener('click',function() { pro(0);},false);

            function pro(x)
            {   alert('yeah');
                if(!x) x=0
                if(x!=0) //I dont want to remove event listener in the first time , so i want it to function with the next call to pro,in which the value of x is bigger than 0                
{
                    //alert('right'); 
                      document.getElementById('bt2').removeEventListener('click',p,false); //event listener is not getting removed .
                }
                document.getElementById('bt2').innerHTML='this is a button '+x;
                function passTo(y)
                {   
                    pro(y);     
                }
                document.getElementById('bt2').addEventListener('click',p,false);
                function p()
                {   //document.getElementById('bt2').removeEventListener('click',p,false); //here the event listener is getting removed easily
                    passTo(x+1);
                }

            }
        }
    }());

Upvotes: 1

Views: 1968

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074038

removeEventListener requires that you pass it the same function, but your p functions are not the same: A new one is created every time pro is called. So the one you're trying to remove isn't the one you added, and so it isn't removed.

Removing it within p works, because within each p function, the identifier p refers to that specific p function. So if that one's been added, it will successfully remove itself.

You can prove this to yourself by putting a unique identifier on your function (see comments):

(function() {
    if (window.addEventListener) window.addEventListener('load', init, false);

    var functionId = 0; // Something to give us unique IDs

    function init() {
        var i = 0;
        var get = document.getElementById('bt1').addEventListener('click', function() {
            pro(0);
        }, false);

        function pro(x) {
            snippet.log('yeah');
            // We ALWAYS to into the body of this if, the condition
            // is just here for emphasis
            if (!p.id) {
                p.id = ++functionId;
            }
            if (!x) x = 0
            if (x != 0)
            {
                snippet.log("Removing #" + p.id); // <===
                document.getElementById('bt2').removeEventListener('click', p, false);
            }
            document.getElementById('bt2').innerHTML = 'this is a button ' + x;

            function passTo(y) {
                pro(y);
            }
            snippet.log("Adding #" + p.id); // <===
            document.getElementById('bt2').addEventListener('click', p, false);

            function p() { 
                passTo(x + 1);
            }

        }
    }
}());
<button id="bt1">bt1</button>
<button id="bt2">bt2</button>

<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

If we run that and click bt1 once, then repeatedly click bt2, we see:

yeah
Adding #1
yeah
Removing #2
Adding #2
yeah
Removing #3
Adding #3
yeah
Removing #4
Adding #4

Note how each time we're trying to remove a different function than we added.

If you want to remove the previous one, you need to remember it elsewhere (see comments):

(function() {
    if (window.addEventListener) window.addEventListener('load', init, false);

    var functionID = 0;
    var lastp = null; // <===

    function init() {
        var i = 0;
        var get = document.getElementById('bt1').addEventListener('click', function() {
            pro(0);
        }, false);

        function pro(x) {
            snippet.log('yeah');
            if (!p.id) { // Again, always true
                p.id = ++functionID;
            }
            if (!x) x = 0;
            if (lastp) // <===
            {
                snippet.log("Removing #" + lastp.id);
                document.getElementById('bt2').removeEventListener('click', lastp, false);
            }
            document.getElementById('bt2').innerHTML = 'this is a button ' + x;

            function passTo(y) {
                pro(y);
            }
            lastp = p; // <===
            snippet.log("Adding #" + p.id);
            document.getElementById('bt2').addEventListener('click', p, false);

            function p() { 
                passTo(x + 1);
            }

        }
    }
}());
<button id="bt1">bt1</button>
<button id="bt2">bt2</button>

<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Upvotes: 1

Related Questions