jQuery find events handlers registered with an object

后端 未结 16 3120
予麋鹿
予麋鹿 2020-11-21 07:16

I need to find which event handlers are registered over an object.

For example:

$(\"#el\").click(function() {...});
$(\"#el\").mouseover(function() {         


        
相关标签:
16条回答
  • 2020-11-21 08:03

    Shameless plug, but you can use findHandlerJS

    To use it you just have to include findHandlersJS (or just copy&paste the raw javascript code to chrome's console window) and specify the event type and a jquery selector for the elements you are interested in.

    For your example you could quickly find the event handlers you mentioned by doing

    findEventHandlers("click", "#el")
    findEventHandlers("mouseover", "#el")
    

    This is what gets returned:

    • element
      The actual element where the event handler was registered in
    • events
      Array with information about the jquery event handlers for the event type that we are interested in (e.g. click, change, etc)
      • handler
        Actual event handler method that you can see by right clicking it and selecting Show function definition
      • selector
        The selector provided for delegated events. It will be empty for direct events.
      • targets
        List with the elements that this event handler targets. For example, for a delegated event handler that is registered in the document object and targets all buttons in a page, this property will list all buttons in the page. You can hover them and see them highlighted in chrome.

    You can try it here

    0 讨论(0)
  • 2020-11-21 08:04

    As of jQuery 1.8, the event data is no longer available from the "public API" for data. Read this jQuery blog post. You should now use this instead:

    jQuery._data( elem, "events" );
    

    elem should be an HTML Element, not a jQuery object, or selector.

    Please note, that this is an internal, 'private' structure, and shouldn't be modified. Use this for debugging purposes only.

    In older versions of jQuery, you might have to use the old method which is:

    jQuery( elem ).data( "events" );
    
    0 讨论(0)
  • 2020-11-21 08:04

    You can do it by crawling the events (as of jQuery 1.8+), like this:

    $.each($._data($("#id")[0], "events"), function(i, event) {
      // i is the event type, like "click"
      $.each(event, function(j, h) {
        // h.handler is the function being called
      });
    });
    

    Here's an example you can play with:

    $(function() {
      $("#el").click(function(){ alert("click"); });
      $("#el").mouseover(function(){ alert("mouseover"); });
    
      $.each($._data($("#el")[0], "events"), function(i, event) {
        output(i);
        $.each(event, function(j, h) {
            output("- " + h.handler);
        });
      });
    });
    
    function output(text) {
        $("#output").html(function(i, h) {
            return h + text + "<br />";
        });
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="el">Test</div>
    <code>
        <span id="output"></span>
    </code>

    0 讨论(0)
  • 2020-11-21 08:05

    As of 1.9 there is no documented way to retrieve the events, other than to use the Migrate plugin to restore the old behavior. You could use the _.data() method as jps mentions, but that is an internal method. So just do the right thing and use the Migrate plugin if you need this functionality.

    From the jQuery documentation on .data("events")

    Prior to 1.9, .data("events") could be used to retrieve jQuery's undocumented internal event data structure for an element if no other code had defined a data element with the name "events". This special case has been removed in 1.9. There is no public interface to retrieve this internal data structure, and it remains undocumented. However, the jQuery Migrate plugin restores this behavior for code that depends upon it.

    0 讨论(0)
  • 2020-11-21 08:05

    I have to say many of the answers are interesting, but recently I had a similar problem and the solution was extremely simple by going the DOM way. It is different because you don't iterate but aim directly at the event you need, but below I'll give a more general answer.

    I had an image in a row:

    <table>
      <td><tr><img class="folder" /></tr><tr>...</tr></td>
    </table>
    

    And that image had a click event handler attached to it:

    imageNode.click(function () { ... });
    

    My intention was to expand the clickable area to the whole row, so I first got all images and relative rows:

    tableNode.find("img.folder").each(function () {
      var tr;
    
      tr = $(this).closest("tr");
      // <-- actual answer
    });
    

    Now in the actual anwer line I just did as follows, giving an answer to the original question:

    tr.click(this.onclick);
    

    So I fetched the event handler directly from the DOM element and put it into the jQuery click event handler. Works like a charm.

    Now, to the general case. In the old pre-jQuery days you could get all events attached to an object with two simple yet powerful functions gifted to us mortals by Douglas Crockford:

    function walkTheDOM(node, func)
    {
      func(node);
      node = node.firstChild;
      while (node)
      {
        walkTheDOM(node, func);
        node = node.nextSibling;
      }
    }
    
    function purgeEventHandlers(node)
    {
      walkTheDOM(node, function (n) {
        var f;
    
        for (f in n)
        {
          if (typeof n[f] === "function")
          {
            n[f] = null;
          }
        }
      });
    }
    
    0 讨论(0)
  • 2020-11-21 08:06

    In a modern browser with ECMAScript 5.1 / Array.prototype.map, you can also use

    jQuery._data(DOCUMENTELEMENT,'events')["EVENT_NAME"].map(function(elem){return elem.handler;});
    

    in your browser console, which will print the source of the handlers, comma delimited. Useful for glancing at what all is running on a particular event.

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