42

I want to add an listener exactly once for beforeunload. This is my pseudocode:

if(window.hasEventListener('beforeunload') === false) {
     window.addEventListener('beforeunload', function() { ... }, false);
}

But hasEventListener does not exist obviously. How can I achieve this? Thanks.

3 Answers 3

48

In fact there is no need to check if an listener was added to a target:

If multiple identical EventListeners are registered on the same EventTarget with the same parameters, the duplicate instances are discarded. They do not cause the EventListener to be called twice, and since the duplicates are discarded, they do not need to be removed manually with the removeEventListener method.

Source:https://developer.mozilla.org/en-US/docs/Web/API/EventTarget.addEventListener#Multiple_identical_event_listeners

Sign up to request clarification or add additional context in comments.

6 Comments

unfortunately it is not true. at least not for chrome.
It is true, if you actually use the exact same listener, not just a listener with the same text: jsfiddle.net/myxqu27d
@MikeLee The listener function have to be reference of previously added listener, otherwise it will execute more than twice
@MikeLee updated fiddle showing event listeners are NOT called twice jsfiddle.net/mbd5s1ko/39
@MikeLee Lee its true that in case of multiple event listeners, the latest listener overrides the previous one. But for that you have to define a named callback function instead of anonymous callback function. Because event listeners consider both anonymous callback function as different and keep both attached. See this jsfiddle.net/hr5d3zuw
|
13

Using jquery you can do use data("events") on any object (here the window) :

var hasbeforeunload = $(window).data("events") && $(window).data("events").['beforeunload'];

But this works only for jquery added events.

In a more general case, you should simply store the information that you add a listener somewhere :

   var addedListeners = {};
   function addWindowListenerIfNone(eventType, fun) {
      if (addedListeners[eventType]) return;
      addedListeners[eventType] = fun;
      window.addEventListener(eventType, fun);
   }

I think there is no standard way in javascript to get the existing event handlers. At best you could surcharge the addEventListener function of Node to intercept and store the listeners but I don't recommend it...

EDIT :

From jQuery 1.8, event data are available in $._data(element, "events"). The change log has a warning that should be taken into account :

Note that this is not a supported public interface; the actual data structures may change incompatibly from version to version.

7 Comments

+1 for the plain javascript but you could make it cross browser(attachEvent).
Maybe. This would be done as explained by the MDN
Thanks for the attempt with jQuery, however I need native Javascript, sorry for not mentioning. I will however go with your flag attempt. I will wait for further answers, and if no better, I will choose yours.
I'm pretty sure there isn't a native way to find what event listeners are added. If you want I could show how to surcharge Node.addEventListener but if you can avoid using it it's cleaner.
This seems to stop working in newer jQuery Versions (around 1.8)... Any idea why? jsfiddle.net/YEGbM/1
|
7

In Chrome Dev tool, you can check all events attached to an element (For debugging)-

// print all events attached to document
var eventObjectAttachedToDocument = getEventListeners(document);

for (var event in eventObjectAttachedToDocument) {
    console.log(event);
}

enter image description here

2 Comments

create 2 click listeners and your code will just display 1 click.
this is chrome only and chrome with devtools open

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.