How to check whether dynamically attached event listener exists or not?
Solution 1
There is no way to check whether dynamically attached event listeners exist or not.
The only way you can see if an event listener is attached is by attaching event listeners like this:
elem.onclick = function () { console.log (1) }
You can then test if an event listener was attached to onclick
by returning !!elem.onclick
(or something similar).
Solution 2
I did something like that:
const element = document.getElementById('div');
if (element.getAttribute('listener') !== 'true') {
element.addEventListener('click', function (e) {
const elementClicked = e.target;
elementClicked.setAttribute('listener', 'true');
console.log('event has been attached');
});
}
Creating a special attribute for an element when the listener is attached and then checking if it exists.
Solution 3
What I would do is create a Boolean outside your function that starts out as FALSE and gets set to TRUE when you attach the event. This would serve as some sort of flag for you before you attach the event again. Here's an example of the idea.
// initial load
var attached = false;
// this will only execute code once
doSomething = function()
{
if (!attached)
{
attached = true;
//code
}
}
//attach your function with change event
window.onload = function()
{
var txtbox = document.getElementById('textboxID');
if (window.addEventListener)
{
txtbox.addEventListener('change', doSomething, false);
}
else if(window.attachEvent)
{
txtbox.attachEvent('onchange', doSomething);
}
}
Solution 4
Possible duplicate: Check if an element has event listener on it. No jQuery Please find my answer there.
Basically here is the trick for Chromium (Chrome) browser:
getEventListeners(document.querySelector('your-element-selector'));
Solution 5
tl;dr: No, you cannot do this in any natively supported way.
The only way I know to achieve this would be to create a custom storage object where you keep a record of the listeners added. Something along the following lines:
/* Create a storage object. */
var CustomEventStorage = [];
Step 1: First, you will need a function that can traverse the storage object and return the record of an element given the element (or false).
/* The function that finds a record in the storage by a given element. */
function findRecordByElement (element) {
/* Iterate over every entry in the storage object. */
for (var index = 0, length = CustomEventStorage.length; index < length; index++) {
/* Cache the record. */
var record = CustomEventStorage[index];
/* Check whether the given element exists. */
if (element == record.element) {
/* Return the record. */
return record;
}
}
/* Return false by default. */
return false;
}
Step 2: Then, you will need a function that can add an event listener but also insert the listener to the storage object.
/* The function that adds an event listener, while storing it in the storage object. */
function insertListener (element, event, listener, options) {
/* Use the element given to retrieve the record. */
var record = findRecordByElement(element);
/* Check whether any record was found. */
if (record) {
/* Normalise the event of the listeners object, in case it doesn't exist. */
record.listeners[event] = record.listeners[event] || [];
}
else {
/* Create an object to insert into the storage object. */
record = {
element: element,
listeners: {}
};
/* Create an array for event in the record. */
record.listeners[event] = [];
/* Insert the record in the storage. */
CustomEventStorage.push(record);
}
/* Insert the listener to the event array. */
record.listeners[event].push(listener);
/* Add the event listener to the element. */
element.addEventListener(event, listener, options);
}
Step 3: As regards the actual requirement of your question, you will need the following function to check whether an element has been added an event listener for a specified event.
/* The function that checks whether an event listener is set for a given event. */
function listenerExists (element, event, listener) {
/* Use the element given to retrieve the record. */
var record = findRecordByElement(element);
/* Check whether a record was found & if an event array exists for the given event. */
if (record && event in record.listeners) {
/* Return whether the given listener exists. */
return !!~record.listeners[event].indexOf(listener);
}
/* Return false by default. */
return false;
}
Step 4: Finally, you will need a function that can delete a listener from the storage object.
/* The function that removes a listener from a given element & its storage record. */
function removeListener (element, event, listener, options) {
/* Use the element given to retrieve the record. */
var record = findRecordByElement(element);
/* Check whether any record was found and, if found, whether the event exists. */
if (record && event in record.listeners) {
/* Cache the index of the listener inside the event array. */
var index = record.listeners[event].indexOf(listener);
/* Check whether listener is not -1. */
if (~index) {
/* Delete the listener from the event array. */
record.listeners[event].splice(index, 1);
}
/* Check whether the event array is empty or not. */
if (!record.listeners[event].length) {
/* Delete the event array. */
delete record.listeners[event];
}
}
/* Add the event listener to the element. */
element.removeEventListener(event, listener, options);
}
Snippet:
window.onload = function () {
var
/* Cache the test element. */
element = document.getElementById("test"),
/* Create an event listener. */
listener = function (e) {
console.log(e.type + "triggered!");
};
/* Insert the listener to the element. */
insertListener(element, "mouseover", listener);
/* Log whether the listener exists. */
console.log(listenerExists(element, "mouseover", listener));
/* Remove the listener from the element. */
removeListener(element, "mouseover", listener);
/* Log whether the listener exists. */
console.log(listenerExists(element, "mouseover", listener));
};
<!-- Include the Custom Event Storage file -->
<script src = "https://cdn.rawgit.com/angelpolitis/custom-event-storage/master/main.js"></script>
<!-- A Test HTML element -->
<div id = "test" style = "background:#000; height:50px; width: 50px"></div>
Although more than 5 years have passed since the OP posted the question, I believe people who stumble upon it in the future will benefit from this answer, so feel free to make suggestions or improvements to it. 😊
Related videos on Youtube
Stano
Updated on July 21, 2022Comments
-
Stano almost 2 years
Here is my problem: is it somehow possible to check for the existence of a dynamically attached event listener? Or how can I check the status of the "onclick" (?) property in the DOM? I have searched the internet just like Stack Overflow for a solution, but no luck. Here is my html:
<a id="link1" onclick="linkclick(event)"> link 1 </a> <a id="link2"> link 2 </a> <!-- without inline onclick handler -->
Then in Javascript I attach a dynamically created event listener to the 2nd link:
document.getElementById('link2').addEventListener('click', linkclick, false);
The code runs well, but all my attempts to detect that attached listener fail:
// test for #link2 - dynamically created eventlistener alert(elem.onclick); // null alert(elem.hasAttribute('onclick')); // false alert(elem.click); // function click(){[native code]} // btw, what's this?
jsFiddle is here. If you click "Add onclick for 2" and then "[link 2]", the event fires well, but the "Test link 2" always reports false. Can somebody help?
-
Ivan almost 12 yearsI'm sorry to say, but it is impossible to get the event bindings using your current method: stackoverflow.com/questions/5296858/…
-
arufian over 7 yearsyou can do it using chrome dev tool: stackoverflow.com/a/41137585/863115
-
Angel Politis over 6 yearsYou can do it by creating your own storage that keeps track of the listeners. See my answer for more.
-
Syknapse over 4 yearsIf the objective is to prevent an event that has already been added from being added again then the right answer is here. Basically, if you use a named function instead of an anonymous one, duplicate identical event listeners will be discarded and you don't need to worry about them.
-
Jacksonkr over 4 yearsIf you're concerned about having duplicate listeners then remove the current event listener before you add it again. It's not perfect but it's simple.
-
-
Justin over 9 yearsYou could also assign a property to the element your element basically marking it as element that has a event attached to it;
-
Zach Saucier almost 8 years
onclick
is separate from.addEventListener
- it affects an attribute while.addEventListener
does not -
conrad10781 over 6 yearsThis is the approach I have used in the past. My recommendation would be to use a very specific syntax structure. IE instead of "listener", use the event itself. So "data-event-click". This provides some flexibility in the event you're looking to do more than one event, and keeps things a bit more readable.
-
user202729 over 5 yearsThis requires you to change the code of the attached event to keep track of whether it is attached (similar to this or this answer). It won't work if you don't control the code.
-
Arye Eidelman almost 5 yearsThis with @conrad10781 's addition seems like the most reliable and simplest way. If for any reason the element is rerenderd and the event listener gets disconnected, this attribute will be reset as well.
-
Panu Logic over 4 yearsThat's a good trick, but I assume it works only if you have a ref to the function that is one of the currently "added" event-listeners. I think this is clearly a shortcoming of the standard API, if we can add any event-listener, it should also be possible to check what event-listeners have been so far added. It is almost like event-listeners currently are "write only variables" which seems like an obscure concept.
-
JPA over 4 yearsThank you for this solution, it's straightforward and sturdy. One remark though, there is one little mistake. The function "removeListener" checks if the event array is empty or not but the ternary is incorrect. It should say "if (record.listeners[event].length!=-1)".
-
JohnK about 4 yearsMore precisely, here: stackoverflow.com/a/41137585/1431728.
-
ceckenrode about 3 yearsIn my usecase the user might have the same page open with different tabs. This only works if the event will only ever be attached in one place in one tab. The boolean can't really be kept in sync with whether or not the event is attached or not because we're just guessing that it's not when this loads
-
Devin Rhode about 3 yearsI'd love to look at this chrome extension! I think we may have the same idea
-
Mike Gashler about 3 yearsAlas, I built that for work so the creative portion is not mine, but I tried to share all the technical bits above.
-
Dazed over 2 yearsI may be going daft (74 upvotes on this) but I'm thinking that
elementClicked.setAttribute('listener', 'true');
should be added outside theaddEventListender
function - otherwise it is only added when the event is triggered and therefore doesn't actually allow you to check the event listener is attached reliably. -
Dazed over 2 yearsAt time of posting this is top voted, but (as above comment) the logic is a little off. A better alternative is below (stackoverflow.com/a/69189193/1265200)
-
Dazed over 2 yearsonly one suggestion - the
element.setAttribute('listenerOnClick', 'true');
could/should be inside theif
-
minigeek about 2 yearsI wrote utility method stackoverflow.com/a/71247657/6789999