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

前端 未结 19 2459
臣服心动
臣服心动 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:10

    To get all eventListeners on a page printed alongside their elements

    Array.from(document.querySelectorAll("*")).forEach(e => {
        const ev = getEventListeners(e)
        if (Object.keys(ev).length !== 0) console.log(e, ev)
    })
    
    0 讨论(0)
  • 2020-11-21 06:11

    It is possible to list all event listeners in JavaScript: It's not that hard; you just have to hack the prototype's method of the HTML elements (before adding the listeners).

    function reportIn(e){
        var a = this.lastListenerInfo[this.lastListenerInfo.length-1];
        console.log(a)
    }
    
    
    HTMLAnchorElement.prototype.realAddEventListener = HTMLAnchorElement.prototype.addEventListener;
    
    HTMLAnchorElement.prototype.addEventListener = function(a,b,c){
        this.realAddEventListener(a,reportIn,c); 
        this.realAddEventListener(a,b,c); 
        if(!this.lastListenerInfo){  this.lastListenerInfo = new Array()};
        this.lastListenerInfo.push({a : a, b : b , c : c});
    };
    

    Now every anchor element (a) will have a lastListenerInfo property wich contains all of its listeners. And it even works for removing listeners with anonymous functions.

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

    I was recently working with events and wanted to view/control all events in a page. Having looked at possible solutions, I've decided to go my own way and create a custom system to monitor events. So, I did three things.

    First, I needed a container for all the event listeners in the page: that's theEventListeners object. It has three useful methods: add(), remove(), and get().

    Next, I created an EventListener object to hold the necessary information for the event, i.e.: target, type, callback, options, useCapture, wantsUntrusted, and added a method remove() to remove the listener.

    Lastly, I extended the native addEventListener() and removeEventListener() methods to make them work with the objects I've created (EventListener and EventListeners).

    Usage:

    var bodyClickEvent = document.body.addEventListener("click", function () {
        console.log("body click");
    });
    
    // bodyClickEvent.remove();
    

    addEventListener() creates an EventListener object, adds it to EventListeners and returns the EventListener object, so it can be removed later.

    EventListeners.get() can be used to view the listeners in the page. It accepts an EventTarget or a string (event type).

    // EventListeners.get(document.body);
    // EventListeners.get("click");
    

    Demo

    Let's say we want to know every event listener in this current page. We can do that (assuming you're using a script manager extension, Tampermonkey in this case). Following script does this:

    // ==UserScript==
    // @name         New Userscript
    // @namespace    http://tampermonkey.net/
    // @version      0.1
    // @description  try to take over the world!
    // @author       You
    // @include      https://stackoverflow.com/*
    // @grant        none
    // ==/UserScript==
    
    (function() {
        fetch("https://raw.githubusercontent.com/akinuri/js-lib/master/EventListener.js")
            .then(function (response) {
                return response.text();
            })
            .then(function (text) {
                eval(text);
                window.EventListeners = EventListeners;
            });
    })(window);
    

    And when we list all the listeners, it says there are 299 event listeners. There "seems" to be some duplicates, but I don't know if they're really duplicates. Not every event type is duplicated, so all those "duplicates" might be an individual listener.

    Code can be found at my repository. I didn't want to post it here because it's rather long.


    Update: This doesn't seem to work with jQuery. When I examine the EventListener, I see that the callback is

    function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}
    

    I believe this belongs to jQuery, and is not the actual callback. jQuery stores the actual callback in the properties of the EventTarget:

    $(document.body).click(function () {
        console.log("jquery click");
    });
    

    To remove an event listener, the actual callback needs to be passed to the removeEventListener() method. So in order to make this work with jQuery, it needs further modification. I might fix that in the future.

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

    There exists nice jQuery Events extension :

    (topic source)

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

    WebKit Inspector in Chrome or Safari browsers now does this. It will display the event listeners for a DOM element when you select it in the Elements pane.

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

    (Rewriting the answer from this question since it's relevant here.)

    When debugging, if you just want to see the events, I recommend either...

    1. Visual Event
    2. The Elements section of Chrome's Developer Tools: select an element and look for "Event Listeners" on the bottom right (similar in Firefox)

    If you want to use the events in your code, and you are using jQuery before version 1.8, you can use:

    $(selector).data("events")
    

    to get the events. As of version 1.8, using .data("events") is discontinued (see this bug ticket). You can use:

    $._data(element, "events")
    

    Another example: Write all click events on a certain link to the console:

    var $myLink = $('a.myClass');
    console.log($._data($myLink[0], "events").click);
    

    (see http://jsfiddle.net/HmsQC/ for a working example)

    Unfortunately, using $._data this is not recommended except for debugging since it is an internal jQuery structure, and could change in future releases. Unfortunately I know of no other easy means of accessing the events.

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