jQuery 查找使用对象注册的事件处理程序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2518421/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 13:41:16  来源:igfitidea点击:

jQuery find events handlers registered with an object

jqueryeventsdom

提问by ages04

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

我需要找到在对象上注册了哪些事件处理程序。

For example:

例如:

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

$("#el")has clickand mouseoverregistered.

$("#el")已注册单击鼠标悬停

Is there a function to find out that, and possibly iterate over the event handlers?

是否有一个函数可以找出并可能遍历事件处理程序?

If it is not possible on a jQuery object through proper methods, is it possible on a plain DOM object?

如果通过适当的方法在 jQuery 对象上是不可能的,那么在普通的 DOM 对象上是否可能?

回答by jps

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 1.8 开始,事件数据不再可从数据的“公共 API”获得。阅读这篇 jQuery 博客文章。您现在应该改用它:

jQuery._data( elem, "events" );

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

elem应该是一个 HTML 元素,而不是一个 jQuery 对象或选择器。

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 中,您可能必须使用旧方法,即:

jQuery( elem ).data( "events" );

回答by Nick Craver

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

您可以通过抓取事件(从 jQuery 1.8+ 开始)来实现,如下所示:

$.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>

回答by PhistucK

For jQuery 1.8+, this will no longer work because the internal data is placed in a different object.

对于 jQuery 1.8+,这将不再起作用,因为内部数据被放置在不同的对象中。

The latest unofficial (but works in previous versions as well, at least in 1.7.2) way of doing it now is - $._data(element, "events")

最新的非官方(但也适用于以前的版本,至少在 1.7.2 中)现在的做法是 - $._data(element, "events")

The underscore ("_") is what makes the difference here. Internally, it is calling $.data(element, name, null, true), the last (fourth) parameter is an internal one ("pvt").

下划线(“_”)是这里的区别所在。在内部,它正在调用$.data(element, name, null, true),最后一个(第四个)参数是一个内部参数(“pvt”)。

回答by Rui

Shameless plug, but you can use findHandlerJS

无耻的插件,不过可以用findHandlerJS

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

要使用它,您只需要包含findHandlersJS(或只需将原始 javascript 代码复制并粘贴到 chrome 的控制台窗口)并为您感兴趣的元素指定事件类型和 jquery 选择器。

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.
  • element
    在其中注册事件处理程序的实际元素
  • events
    数组,包含我们感兴趣的事件类型(例如单击、更改等)的 jquery 事件处理程序的信息
    • handler
      实际事件处理程序方法,您可以通过右键单击它并选择 Show function definition 来查看
    • selector
      为委托事件提供的选择器。对于直接事件,它将为空。
    • 目标
      包含此事件处理程序所针对的元素的列表。例如,对于在文档对象中注册并以页面中的所有按钮为目标的委托事件处理程序,此属性将列出页面中的所有按钮。您可以将它们悬停并查看它们以 chrome 突出显示。

You can try it here

你可以在这里试试

回答by Anton

I use eventbugplugin to firebug for this purpose.

为此,我使用eventbug插件来触发错误

回答by algorhythm

I've combined both solutions from @jps to one function:

我已将来自@jps 的两种解决方案组合到一个函数中:

jQuery.fn.getEvents = function() {
    if (typeof(jQuery._data) === 'function') {
        return jQuery._data(this.get(0), 'events') || {};
    }

    // jQuery version < 1.7.?
    if (typeof(this.data) === 'function') {
        return this.data('events') || {};
    }

    return {};
};

But beware, this function can only return events that were set using jQuery itself.

但请注意,此函数只能返回使用 jQuery 本身设置的事件。

回答by Tom G

To check for events on an element:

要检查元素上的事件:

var events = $._data(element, "events")

Note that this will only work with direct event handlers, if you are using $(document).on("event-name", "jq-selector", function() { //logic }), you will want to see the getEvents function at the bottom of this answer

请注意,这仅适用于直接事件处理程序,如果您使用 $(document).on("event-name", "jq-selector", function() { //logic }),您将希望看到此答案底部的 getEvents 函数

For example:

例如:

 var events = $._data(document.getElementById("myElemId"), "events")

or

或者

 var events = $._data($("#myElemId")[0], "events")

Full Example:

完整示例:

<html>
    <head>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js" type="text/javascript"></script>
        <script>
            $(function() {
                $("#textDiv").click(function() {
                    //Event Handling
                });
                var events = $._data(document.getElementById('textDiv'), "events");
                var hasEvents = (events != null);
            });
        </script>
    </head>
    <body>
        <div id="textDiv">Text</div>
    </body>
</html>

A more complete way to check, that includes dynamic listeners, installed with $(document).on

一种更完整的检查方法,包括使用 $(document).on 安装的动态侦听器

function getEvents(element) {
    var elemEvents = $._data(element, "events");
    var allDocEvnts = $._data(document, "events");
    for(var evntType in allDocEvnts) {
        if(allDocEvnts.hasOwnProperty(evntType)) {
            var evts = allDocEvnts[evntType];
            for(var i = 0; i < evts.length; i++) {
                if($(element).is(evts[i].selector)) {
                    if(elemEvents == null) {
                        elemEvents = {};
                    }
                    if(!elemEvents.hasOwnProperty(evntType)) {
                        elemEvents[evntType] = [];
                    }
                    elemEvents[evntType].push(evts[i]);
                }
            }
        }
    }
    return elemEvents;
}

Example usage:

用法示例:

getEvents($('#myElemId')[0])

回答by oligofren

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.

从 1.9 开始,除了使用 Migrate 插件恢复旧行为之外,没有记录的方法来检索事件。您可以使用 _.data() 方法作为 jps 提及,但这是一个内部方法。因此,如果您需要此功能,请做正确的事情并使用 Migrate 插件。

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

来自 jQuery 文档 .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.

在 1.9 之前,如果没有其他代码定义名为“events”的数据元素,则 .data("events") 可用于检索元素的 jQuery 未记录的内部事件数据结构。这种特殊情况已在 1.9 中删除。没有公共接口来检索这个内部数据结构,它仍然没有记录。但是,jQuery Migrate 插件会为依赖它的代码恢复这种行为。

回答by Erutan409

I created a custom jQuery selector that checks against both jQuery's cache of assigned event handlers as well as elements that use the native method for adding them:

我创建了一个自定义 jQuery 选择器,它检查 jQuery 的分配事件处理程序的缓存以及使用本机方法添加它们的元素:

(function($){

    $.find.selectors[":"].event = function(el, pos, match) {

        var search = (function(str){
            if (str.substring(0,2) === "on") {str = str.substring(2);}
            return str;
        })(String(match[3]).trim().toLowerCase());

        if (search) {
            var events = $._data(el, "events");
            return ((events && events.hasOwnProperty(search)) || el["on"+search]);
        }

        return false;

    };

})(jQuery);

Example:

例子:

$(":event(click)")

This will return elements that have a click handler attached to them.

这将返回附加了点击处理程序的元素。

回答by Jesan Fafon

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

在带有 ECMAScript 5.1 / 的现代浏览器中Array.prototype.map,您还可以使用

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.

在您的浏览器控制台中,它将打印处理程序的来源,以逗号分隔。用于查看在特定事件上运行的所有内容。