How to find event listeners on a DOM node when debugging or from the JavaScript code?

前端 未结 19 2482
臣服心动
臣服心动 2020-11-21 05:34

I have a page where some event listeners are attached to input boxes and select boxes. Is there a way to find out which event listeners are observing a particular DOM node a

相关标签:
19条回答
  • 2020-11-21 06:02

    You could wrap the native DOM methods for managing event listeners by putting this at the top of your <head>:

    <script>
        (function(w){
            var originalAdd = w.addEventListener;
            w.addEventListener = function(){
                // add your own stuff here to debug
                return originalAdd.apply(this, arguments);
            };
    
            var originalRemove = w.removeEventListener;
            w.removeEventListener = function(){
                // add your own stuff here to debug
                return originalRemove.apply(this, arguments);
            };
        })(window);
    </script>
    

    H/T @les2

    0 讨论(0)
  • 2020-11-21 06:02

    Opera 12 (not the latest Chrome Webkit engine based) Dragonfly has had this for a while and is obviously displayed in the DOM structure. In my opinion it is a superior debugger and is the only reason remaining why I still use the Opera 12 based version (there is no v13, v14 version and the v15 Webkit based lacks Dragonfly still)

    enter image description here

    0 讨论(0)
  • 2020-11-21 06:02

    I am trying to do that in jQuery 2.1, and with the "$().click() -> $(element).data("events").click;" method it doesn't work.

    I realized that only the $._data() functions works in my case :

    	$(document).ready(function(){
    
    		var node = $('body');
    		
            // Bind 3 events to body click
    		node.click(function(e) { alert('hello');  })
    			.click(function(e) { alert('bye');  })
    			.click(fun_1);
    
            // Inspect the events of body
    		var events = $._data(node[0], "events").click;
    		var ev1 = events[0].handler // -> function(e) { alert('hello')
    		var ev2 = events[1].handler // -> function(e) { alert('bye')
    		var ev3 = events[2].handler // -> function fun_1()
            
    		$('body')
    			.append('<p> Event1 = ' + eval(ev1).toString() + '</p>')
    			.append('<p> Event2 = ' + eval(ev2).toString() + '</p>')
    			.append('<p> Event3 = ' + eval(ev3).toString() + '</p>');        
    	
    	});
    
    	function fun_1() {
    		var txt = 'text del missatge';	 
    		alert(txt);
    	}
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <body>
    </body>

    0 讨论(0)
  • 2020-11-21 06:06

    If you have Firebug, you can use console.dir(object or array) to print a nice tree in the console log of any JavaScript scalar, array, or object.

    Try:

    console.dir(clickEvents);
    

    or

    console.dir(window);
    
    0 讨论(0)
  • 2020-11-21 06:08

    Prototype 1.7.1 way

    function get_element_registry(element) {
        var cache = Event.cache;
        if(element === window) return 0;
        if(typeof element._prototypeUID === 'undefined') {
            element._prototypeUID = Element.Storage.UID++;
        }
        var uid =  element._prototypeUID;           
        if(!cache[uid]) cache[uid] = {element: element};
        return cache[uid];
    }
    
    0 讨论(0)
  • 2020-11-21 06:09

    1: Prototype.observe uses Element.addEventListener (see the source code)

    2: You can override Element.addEventListener to remember the added listeners (handy property EventListenerList was removed from DOM3 spec proposal). Run this code before any event is attached:

    (function() {
      Element.prototype._addEventListener = Element.prototype.addEventListener;
      Element.prototype.addEventListener = function(a,b,c) {
        this._addEventListener(a,b,c);
        if(!this.eventListenerList) this.eventListenerList = {};
        if(!this.eventListenerList[a]) this.eventListenerList[a] = [];
        this.eventListenerList[a].push(b);
      };
    })();
    

    Read all the events by:

    var clicks = someElement.eventListenerList.click;
    if(clicks) clicks.forEach(function(f) {
      alert("I listen to this function: "+f.toString());
    });
    

    And don't forget to override Element.removeEventListener to remove the event from the custom Element.eventListenerList.

    3: the Element.onclick property needs special care here:

    if(someElement.onclick)
      alert("I also listen tho this: "+someElement.onclick.toString());
    

    4: don't forget the Element.onclick content attribute: these are two different things:

    someElement.onclick = someHandler; // IDL attribute
    someElement.setAttribute("onclick","otherHandler(event)"); // content attribute
    

    So you need to handle it, too:

    var click = someElement.getAttribute("onclick");
    if(click) alert("I even listen to this: "+click);
    

    The Visual Event bookmarklet (mentioned in the most popular answer) only steals the custom library handler cache:

    It turns out that there is no standard method provided by the W3C recommended DOM interface to find out what event listeners are attached to a particular element. While this may appear to be an oversight, there was a proposal to include a property called eventListenerList to the level 3 DOM specification, but was unfortunately been removed in later drafts. As such we are forced to looked at the individual Javascript libraries, which typically maintain a cache of attached events (so they can later be removed and perform other useful abstractions).

    As such, in order for Visual Event to show events, it must be able to parse the event information out of a Javascript library.

    Element overriding may be questionable (i.e. because there are some DOM specific features like live collections, which can not be coded in JS), but it gives the eventListenerList support natively and it works in Chrome, Firefox and Opera (doesn't work in IE7).

    0 讨论(0)
提交回复
热议问题