1

I have 1 div (a message) which appears on the page when the page is loaded. When a user clicks somewhere on a page outside this message I want this message to disappear and show (ONCE) a log in the console that the message has disappeared. The problem is I continue receiving my console messages every time I click everywhere on my page though the message is already gone. I.E. I cannot detach 'click' event from my page. The code is following:

var elems = document.querySelectorAll(':not(#my-widget)'); //all elements in my page except message
var promptwidget = document.getElementById('my-widget');
console.log('WIDGET==> ' + promptwidget);
if (typeof(promptwidget) != 'undefined' && promptwidget != 'null') {
  for (var i = 0; i < elems.length; i++) //add click eventlistener to the rest document 
  {
    elems[i].addEventListener("click", function(e) {
      e.preventDefault(),
        removeWidget(["my-widget"]), //parentNode.removeChild wrapper, works OK
        console.log('widget removed'), //received everytime I click on a page but I need only ONCE
        promptwidget = document.getElementById('my-widget'); //tried to reassign a null value to my promptwidget var and call removeEventListener but no work 
    });
  }
} else //this code never called, but I want it after my-widget removal
{
  for (var i = 0; i < elems.length; i++) {
    elems[i].removeEventListener("click", function(e) {
      e.preventDefault(),
        console.log("clickevent removed")
    });
  }
}

Any help would be appreciated.

EDIT_1: Thank you everyone, the problem was solved as follows:

var elems = document.querySelectorAll(':not(#my-widget)');
var promptwidget = document.getElementById('my-widget');
for(var i = 0; i<elems.length; i++) 
            {
              elems[i].addEventListener("click", function(e) 
              {
                e.preventDefault();
                if(typeof(promptwidget) != 'undefined' && promptwidget != null)
                {
                   removeWidget(["my-widget"]), 
                   console.log('widget removed'), //now showed once
                   promptwidget = undefined
                }
              });
            }

This code was very helpful

Community
  • 1
  • 1
Jack
  • 857
  • 14
  • 39

2 Answers2

1

It doesn't make sense to pass a newly declared anonymous function as the 2nd parameter to removeEventListener. You need to pass a reference to the actual function to be removed. You will have to define this function with a name outside of the scope, and then you can use the name as a reference to remove it.

function removeWidgetFn (e) {
  e.preventDefault(),
    removeWidget(["my-widget"]), 
    console.log('widget removed'),
    promptwidget = document.getElementById('my-widget');
});

And then,

elems[i].addEventListener("click", removeWidgetFn);

And then,

elems[i].removeEventListener("click", removeWidgetFn);

An element can have many click handlers, so you need to specify which click handler you want to remove.

sahbeewah
  • 2,690
  • 1
  • 12
  • 18
  • Maybe you could write some short example? I cannot get the idea what should be there inside this function? Thank you – Jack Apr 20 '16 at 13:19
  • Tried that and also as described in a question linked above but when I add both add and remove EventListeners the message is not removed(( If I comment out removeEventListener, message is removed but the event is not detached. I think this is because I remove EventListener immediately after addition. Maybe I am wrong somewhere? – Jack Apr 20 '16 at 14:00
1

addEventListener allows you to specify more than one event handler for each event type, so to remove a specific event handler you need to specify not only the event type, but also which handler you want to remove:

addEventListener(eventType, eventHandler);
removeEventListener(eventType, eventHandler); 
// arguments passed to removeEventListener must be exactly the same
// as in addEventListener so you cannot pass an anonymous function
marzelin
  • 10,790
  • 2
  • 30
  • 49