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

age*_*s04 538 jquery events dom

我需要找到在对象上注册的事件处理程序.

例如:

$("#el").click(function() {...});
$("#el").mouseover(function() {...});
Run Code Online (Sandbox Code Playgroud)

$("#el")点击鼠标悬停注册.

是否有一个函数来找出它,并可能迭代事件处理程序?

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

jps*_*jps 673

从jQuery 1.8开始,数据的"公共API"不再提供事件数据.阅读这篇jQuery博客文章.你现在应该使用它:

jQuery._data( elem, "events" );
Run Code Online (Sandbox Code Playgroud)

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

请注意,这是一个内部的"私有"结构,不应修改.仅用于调试目的.

在旧版本的jQuery中,您可能必须使用以下旧方法:

jQuery( elem ).data( "events" );
Run Code Online (Sandbox Code Playgroud)

  • 但你仍然可以使用`$ ._ data($(elem).get(0),"events")` (216认同)
  • 真?对我来说,这对我来说是1.10/2.0. (15认同)
  • 这不再有效.从1.9开始,这已被删除. (13认同)
  • http://blog.jquery.com/2011/11/08/building-a-slimmer-jquery/ .data("events"):jQuery将其事件相关数据存储在名为(等待)事件的数据对象中在每个元素上.这是一个内部数据结构,因此在1.8中,这将从用户数据名称空间中删除,因此它不会与同名项目冲突.jQuery的事件数据仍然可以通过jQuery._data(元素,"事件")访问,但请注意,这是一个未记录的内部数据结构,不应修改. (10认同)
  • jquery 1.8发布的新jsfiddle在这里http://jsfiddle.net/9n6gh/ (6认同)
  • 它返回未定义。 (3认同)
  • 无缝支持这两个选项:`var events = (jQuery._data || jQuery.data)(elem, 'events');` (2认同)

Nic*_*ver 82

您可以通过抓取事件(从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
  });
});
Run Code Online (Sandbox Code Playgroud)

这是一个你可以玩的例子:

$(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 />";
    });
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • 对于jQuery 1.8+,你必须**使用'私有数据'方法:`jQuery._data(jQuery("#el")[0],"events");`而不是'public data'方法: `的jQuery( "#报").数据( "事件")`.`event`对象实际上并没有存储在`.data()`中很长一段时间,我们通过从"公共API"中删除这个"代理"来修剪掉几个字节的代码. (15认同)
  • 这是正确的答案.关键的一点是下半场.如果我不得不搜索所有代码,这有助于我在不到一分钟的时间内找到一个问题.谢谢! (2认同)
  • 适用于1.4,但不适用于jQuery 1.8.2. (2认同)

Phi*_*ucK 36

对于jQuery 1.8+,这将不再有效,因为内部数据放在不同的对象中.

最新的非官方(但在以前的版本中也有效,至少在1.7.2中)现在这样做的方式是 - $._data(element, "events")

下划线("_")就是这里的不同之处.在内部,它正在调用$.data(element, name, null, true),最后一个(第四个)参数是内部参数("pvt").

  • @Michal - http://api.jquery.com/jQuery.data/说它接受一个元素,而不是一个选择器. (2认同)
  • FWIW - 指出它"内部"使用参数调用其他数据函数,我们可能不需要文档.但是,是的,`jQuery._data(element,"events")`是现在获取此信息的'正确'方式. (2认同)

Rui*_*Rui 34

无耻的插件,但你可以使用findHandlerJS

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

对于您的示例,您可以快速找到您提到的事件处理程序

findEventHandlers("click", "#el")
findEventHandlers("mouseover", "#el")
Run Code Online (Sandbox Code Playgroud)

这是返回的内容:

  • element
    注册事件处理程序的实际元素
  • events
    包含有关我们感兴趣的事件类型的jquery事件处理程序的信息的数组(例如,单击,更改等)
    • 处理
      程序通过右键单击并选择显示函数定义可以看到的实际事件处理程序方法
    • selector
      为委派事件提供的选择器.对于直接事件,它将是空的.
    • targets
      包含此事件处理程序所针对的元素的列表.例如,对于在文档对象中注册并指向页面中所有按钮的委托事件处理程序,此属性将列出页面中的所有按钮.您可以将它们悬停在Chrome中以突出显示它们.

你可以在这里试试


Ant*_*ton 12

为此,我使用eventbug插件来firebug.

  • 此外,Chrome开发者工具在"元素"标签下有"事件监听器","源"标签下有"事件监听器断点". (11认同)

alg*_*thm 9

我将@jps的两个解决方案合并到一个函数中:

jQuery.fn.getEvents = function() {
    if (typeof(jQuery._data) == 'function') {
        return jQuery._data(this.get(0), 'events') || {};
    } else if (typeof(this.data) == 'function') { // jQuery version < 1.7.?
        return this.data('events') || {};
    }
    return {};
};
Run Code Online (Sandbox Code Playgroud)

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


Tom*_*m G 6

要检查元素上的事件:

var events = $._data(element, "events")
Run Code Online (Sandbox Code Playgroud)

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

例如:

 var events = $._data(document.getElementById("myElemId"), "events")
Run Code Online (Sandbox Code Playgroud)

或者

 var events = $._data($("#myElemId")[0], "events")
Run Code Online (Sandbox Code Playgroud)

完整示例:

<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>
Run Code Online (Sandbox Code Playgroud)

一种更完整的检查方法,包括使用 $(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;
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

getEvents($('#myElemId')[0])
Run Code Online (Sandbox Code Playgroud)


oli*_*ren 5

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

从jQuery文档开始 .data("events")

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

  • 您似乎误解了Migrate插件的重点.jQuery删除了已弃用的功能,而Migrate插件旨在帮助**将**开发人员的代码迁移到更新的版本,以便他们可以立即利用新功能和改进,但不会丢失功能.这是为了帮助编码人员看到他们需要做什么才能正确使用新版本的jQuery.你不应该在生产中使用它来恢复**功能.此外,许多事情都没有记录在jQuery文档中并且是最新的 - 他们之前已经指出过,所以这不是理由 (3认同)
  • 私有的,未记录的方式永远不会是“正确的”方式。正确的方法(即已记录的,公开的和预期的)是使用Migrate插件。 (2认同)