27

I need to find all events handlers attached to #mySelect and if the event is created via jQuery I can get it , here alert(e) will show only "change" without "click"

JavaScript :

$("#mySelect").change(function(){
    alert("changed");
})           
$.each($._data(  $("#mySelect")[0], "events" ), function(e) {
    alert(e);
})

Html :

<select id="mySelect" onclick="alert('hello')" >
    <option value="1">option 1</option>
    <option value="2">option 2</option>
    <option value="3">option 3</option>
    <option value="4">option 4</option>
</select>
j08691
  • 204,283
  • 31
  • 260
  • 272
Mohamed Omezzine
  • 1,074
  • 3
  • 15
  • 28

3 Answers3

31

The short answer is that it's not possible to reliably determine all the listeners on an element just using javascript.

The long answer is that there is no standard mechanism to list all attached listeners. Some libraries keep a list of listeners that have been attached using the library, but don't necessarily know about other listeners. Listeners added in the markup or as element properties can be found by testing related element properties and attributes (somewhat tedious testing for onclick, onchange, onblur, etc. for each element). But it's impossible to find a listener added using addEventListener or attachEvent unless a reference has been kept somewhere and it's made available (see comment about libraries).

Also, there are "delegated" listeners that give the appearance of being attached to an element when in fact they are attached to a parent element.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • 5
    If I can see all the events bound through the chrome inspector than certainly there should be some javascript way of doing the same right? Unless all the bound listeners are not visible in chrome either. Or chrome has some unexposed functionality that we do not have access to. – Pasha Skender Apr 03 '17 at 22:35
  • Cannot find a reliable way to do it, so this is probably the right answer. Basically attach dynamic events using some sort of wrapper/framework that keeps track of it and you are fine. In my case the framework that should be doing that is bugging out :) Really annoying to debug since you cannot inspect it by simply looking at properties. – Neikius Feb 21 '18 at 13:24
15
$( '#mySelect' ).bind( {
    'change': function( event ) {

    },
    'click': function( event ) {

    }
});


$.each($._data(  $("#mySelect")[0], "events" ), function(e) {
    alert(e);
});
Yuan Zhaohao
  • 574
  • 5
  • 4
  • 3
    You, sir, are a savior. I have been searching for something like this for hours now, inside and outside Stack Overflow, and no one had given a proper answer thus far. Your answer, however, did the trick. – Geeky Guy Jan 27 '14 at 13:19
  • 3
    this code only works for jQuery v1.*.*, but not for v2.*.* – cuixiping Aug 10 '16 at 18:26
  • I'm voting this down, because in general use in any language, you are not supposed to access methods that start with and underscore. These are private class methods. – Paul Allsopp Mar 21 '18 at 17:17
  • 1
    @CrazyMerlin "in any language"??? Plus there are ways of making methods *truly* private; one should *not* have to rely on prepending the method name with an underscore as a convention to indicate that a method should merely be *considered* private. If it's publicly accessible it is in essence part of the interface and the developers should have been more careful to not let the abstraction leak. – Dexygen May 09 '19 at 14:11
  • 2
    @GeorgeJempty This is JavaScript, there are no real private methods, so the use of an underscore is the developers way of telling someone using the library not to use the method. Private methods don't have to care about public consumption so will change without telling you...hence, don't use them! – Paul Allsopp May 12 '19 at 04:07
  • @CrazyMerlin I'm well aware it's Javascript, but I'm also well aware that you actually *can* create private methods in Javascript – Dexygen May 12 '19 at 11:15
  • @GeorgeJempty If you're talking about exporting, or prototyping, or closures, then you're not talking about real private methods, you're talking about scope emulation. JavaScript is not a programming language, so it was never designed with true private scope in mind. – Paul Allsopp May 12 '19 at 21:24
  • 1
    @CrazyMerlin stop being a pedant and just admit there are ways to not have to expose non public functionality in javascript instead of the inane convention of pretending names with an underscore – Dexygen May 13 '19 at 10:15
-1

In addition for events attached inline you can try this:

alert(document.getElementById('mySelect').getAttribute('onclick'));
nico
  • 837
  • 5
  • 4