0

Is there a way to get all elements that have a certain event listener attached to them?

I know I can get them if the event listener is defined as an attribute:

var allElemsInBodyWithOnclickAttr = $("body").find("*[onclick]");

But I have elements that have event listeners that are attached by code and thus have no onclick attribute.

So when I do (for example) this:

$("a").on("click", function(evt) { 
    alert("Hello"); 
});

..then using the code below doesn't fire the click on those anchor elements:

$("a[onclick]").trigger("click");

I guess I could loop through all the elements and check if they have the listener I'm looking for (using this SO question) but I can't imagine that's going to perform very well..

Community
  • 1
  • 1
REJH
  • 3,273
  • 5
  • 31
  • 56
  • With `[onclick]` selector, you are selecting elements having `onclick` attribute but you never had elements having this attribute.... – Rayon Aug 19 '16 at 09:08
  • 3
    I think you're going about this the wrong way. It would be better to put a common class on all the elements and then attach the event to that class, eg `$('.myClass').click(fn)`. Then you can raise the event on all those elements when needed using `$('.myClass').trigger('click')` – Rory McCrossan Aug 19 '16 at 09:09
  • @RoryMcCrossan unfortunately that is not really a solution for this case. I need this to circumvent the ridicilous delay that iOS' UIWebView has between tapping and firing the click event. So I want to prevent the original onclick, put touchstart/touchend on those elements and trigger the click event myself. Thing is, it's for a framework of sorts so I'm not the one who can just put a custom class on everything.. – REJH Aug 19 '16 at 09:57
  • In which case I would suggest you create a native app. Probably not a helpful answer, but any solution you create to get around that issue will be a brittle, rather hacky, fudge. – Rory McCrossan Aug 19 '16 at 09:59
  • Hehe yea that's not the answer my stormtroopers are looking for. Well, I can control the onclicks that my framework registers etc so it's going to be some refactoring but I can add the classes.. worth a try :) – REJH Aug 19 '16 at 10:11

2 Answers2

1

I think this is not possible, since it is not possible to test if a single element has an event listener attached to it.

Look here

So the only way to do that is to manage a map which contains a reference to each event handler for each event for each element.

Edit

With respect to the answer of @Ivan Shmidt, I must correct my answer: Obviously It seams to be possible with jQuery. That is because jQuery is holding a reference of attached event handlers, BUT events attached using good old .addEventListener() would bypass this and also not be found this way.

Community
  • 1
  • 1
philipp
  • 15,947
  • 15
  • 61
  • 106
1

Can't add comments, but still - consider using https://github.com/ftlabs/fastclick for removing the delay.

That helped me, when i was developing app using cordova.

Also, didn't notice you have already mentioned this post, so i have written implementation for 'loop through all elements'-type-of-solution

Array.prototype.reduce.call(
    $('body').children(),
    (answer, node) => {
        if (typeof $._data($(node)[0], 'events') != 'undefined') {
            answer.push(node);
        }
        return answer;
    },
    []
);
Community
  • 1
  • 1
Ivan Shmidt
  • 163
  • 1
  • 7