0

How do I access what events have been bound to a DOM element using JavaScript and NOT using a library/framework or Firefox add-on? Just pure JavaScript. I incorrectly assumed there would be an events object stored as a property of the element which has the binding.

For example if I had bound say, click, dblclick and mouseover to an element how would I do the following NOT using jQuery. Just JavaScript.

function check(el){
 var events = $(el).data('events');
 for (i in $(el).data('events')) {
  console.log(i) //logs click dblclick and mouseover
  }
}

I know jQuery stores an events object as a data property i.e. $(el).data('events') and the eventbug add-on displays the event binding so there must be way.

I will also add that this question came about because I read about memory leaks in older IE browsers and how it's best to remove the bound events before removing a node from the DOM, which lead me to think, how can I test for what events are bound to an element?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
screenm0nkey
  • 18,405
  • 17
  • 57
  • 75
  • possible duplicate of [How to find event listeners on a DOM node?](http://stackoverflow.com/questions/446892/how-to-find-event-listeners-on-a-dom-node) – Felix Kling Apr 14 '11 at 11:19
  • I read that post Felix but it didn't have an answer. They tell you how to bind events and use add-ons and widgets to view the events but I know all that. I want to know if there's a kind of events property of a dom elements that allows me to see all the bound events. – screenm0nkey Apr 14 '11 at 13:24
  • 1
    @NickLowman: Well the answers say that it is not possible. – Felix Kling Apr 14 '11 at 13:42
  • 1
    @Nick Hm, eventbug may have access to certain internal aspects of the browser that regular JavaScript code doesn't. – Šime Vidas Apr 14 '11 at 13:47
  • @Nick jQuery's `.data('events')` works only for event handers bound via jQuery. If you use `.onclick = function () { ... };`, jQuery won't register it. – Šime Vidas Apr 14 '11 at 13:51

2 Answers2

1

You can't reliably know what listeners are on an element if you aren't in complete control of the environment. Some libraries manually control event listeners, e.g. jQuery stores them in an object and adds a custom attribute to the element so that when an even occurs, it uses the custom property to look up the listeners for that element and event and calls them.

Try:

<div id="d0">div 0</div>
<script type="text/javascript">

var el = document.getElementById('d0')
el.addEventListener('click',function(){alert('hey');},false);

// Make sure listener has had time to be set then look at property
window.setTimeout(function(){alert(el.onclick)}, 100); // null

</script>

So to know what listeners have been added, you need to be in complete control.

Edit:

To make it clear, there is no reliable way to inspect an element with javascript and discover what listeners have been added, or even if any have been added at all. You can create an event registration scheme to track listeners added using your event registration methods. But if listeners are added some other way (e.g. directly by addEventListener) then your registration scheme won't know about them.

As pointed out elsewhere, jQuery (and others) can't track listeners that are added directly to elements without using the jQuery event registration methods (click, bind, mouseover, etc.) because they use those methods to register (and call) the listeners.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • @RobG I don't think that jQuery does that. Do you have a source? From my understanding of the jQuery source code, it uses addEventListener internally. – Šime Vidas Apr 14 '11 at 12:27
  • @RobG - Doesn't really answer my question but maybe I wasn't very clear. Just say I wasn't using any libraries and I wanted to write a function that checked to see what events were bound to a particular dom element, passed into my function as an argument. And it had to support DOM Level 1 event model. – screenm0nkey Apr 14 '11 at 12:34
  • @Sime - I'd a be agreeing with you on that one. I kind of ignored that part of the response. – screenm0nkey Apr 14 '11 at 12:37
  • @Nick What do you mean by DOM Level 1 event model? DOM Level 1 doesn't define an event model. The event model was introduced in DOM Level 2 Events, and improved in DOM Level 3 Events. – Šime Vidas Apr 14 '11 at 12:47
  • @Sime - My bad - I meant the DOM Level 0 event Model ie el.onclick=function(){}. So can you help with my original question? – screenm0nkey Apr 14 '11 at 12:53
  • @Nick Yes. If you bind the event handlers by simply assigning the handlers to the `onevent` properties of the DOM element, then you can just iterate over all those properties and check whether or not they point to a function. – Šime Vidas Apr 14 '11 at 12:59
  • @Šime Vidas - the code is freely available on the web, download it and have a look. Be prepared for quite a bit of work though, it's spread across various parts of the code. – RobG Apr 15 '11 at 05:38
  • @Nick Lowman - I updated my answer, hopefully it's clearer now. The bottom line is that if you are in control, then keep a register of the listeners that you put on elements. If you have other scripts running in the page, then you are out of luck, you can't reliably know the elements they've added listeners to. – RobG Apr 16 '11 at 07:24
0
// list of onevent attributes; you'll have to complete this list
var arr = ['onclick', 'onmouseover', 'onmouseup'];

for ( var i = 0; i < arr.length; i++ ) {
    if ( el[arr[i]] != null ) {
        // element has an arr[i] handler
    }  
}

where el is a reference to your DOM element

Complete lists are here

Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
  • Sorry man, I'm being really unclear but my original question was in relation to the DOM leve1 2/3 event binding but with support for DOM 0. I'll edit my original question to make it clearer. – screenm0nkey Apr 14 '11 at 13:21