检查元素上是否存在事件

197

有没有一种方法在jQuery中检查事件是否存在?我正在开发一个使用自定义命名空间事件的插件,并希望能够检查事件是否已经绑定到元素上。


1
所以,在1.8中,所有这些都是错误的吗? - Skylar Saveland
4
@SkylarSaveland 方法$.data(element, "events")从未被官方认可。但在jQuery 1.8.0中,该方法通过 $._data(element, "events")被废弃了。 在这里阅读更多信息。 - Anton
8个回答

145
$('body').click(function(){ alert('test' )})

var foo = $.data( $('body').get(0), 'events' ).click
// you can query $.data( object, 'events' ) and get an object back, then see what events are attached to it.

$.each( foo, function(i,o) {
    alert(i) // guid of the event
    alert(o) // the function definition of the event handler
});

你可以通过将对象引用(不是 jQuery 对象)传递给 $.data,然后将第二个参数设置为 'events',这样会返回一个包含所有事件(如 'click')的对象。你可以循环浏览该对象,以查看事件处理程序执行了什么操作。


3
我更喜欢你的第一个例子,$ .data(elem,'events')提供了更多的信息。 - Corey Hart
17
为什么不直接使用 $('body').data('events')? - James
3
出错信息为"$ .data($('#myDiv').get(0),"events")未定义"。 - zakdances
8
这仅适用于通过jQuery助手绑定的事件。 - Alex Ciminian
21
在jQuery 1.8及以上版本中,$.data()不再起作用。对我来说,$._data()在jQuery 1.10.1中可以使用。请参考Tom Gerken的答案以获得可行的解决方案。 - jbandi
显示剩余3条评论

98

你可以使用:

$("#foo").unbind('click');
为了确保所有点击事件都被解除绑定,然后再附加你的事件。

1
如果您使用live注册事件,则无法提供帮助。 - Rohit Banga
33
问题在于检查元素上是否存在事件,而不是如何解除现有事件绑定... - Avi
53
@Avi,这仍然是个好答案,因为在许多情况下提问者的问题是:“如何避免注册两次处理程序?”。请问您需要将其翻译成哪种语言? - hans
如果您不想破坏其他地方注册的事件,那么这将无法正常工作。 - Galvani
8
同意:这不是对原帖的严格回答,但正是我所需要的 ;) - tibi
1
自jQuery 3.0起,.unbind()已被弃用。自jQuery 1.7以来,它已被.off()方法取代,因此其使用已经不建议了。 - Bonez024

57

检查元素上的事件:

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

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

例如:

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

或者

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

完整示例:

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

一种更完整的检查方式,包括使用$(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;
}

使用示例:

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

我认为你可以简化这个代码,使用以下方式:var eventBound = (events != null); - George Shaw
这个解决方案适用于jQuery 1.8.0及更高版本。非常感谢Ton Gerken :) - Blue Smith
1
这应该是被接受的答案,它处理动态应用的事件处理程序,即使代码很复杂。谢谢! - Joosh1337

28

使用 jQuery事件过滤器

你可以像这样使用它

$("a:Event(click)")

33
谢谢,几个月前看了Meder的回答后,我开发了这个插件。我感激他的回答。 - Corey Hart
22
从1.8版本开始,这个插件已经不再起作用了。 - Corey Hart
8
我喜欢这个,发布一个插件 OP 作为他提出问题的答案 :) - Andy

5
我编写了一个名为hasEventListener的插件,可以完美实现这一功能。
希望这能有所帮助。

1
问题是,它是如何工作的?我已经花了几个小时,但仍然不清楚。我只想检查它是否有点击事件,并返回一个布尔值,而不是一个对象,但你提供的大多数方法,至少是例子,都更加复杂。有趣的是:http://www.codingjack.com/playground/jquick/#haseventlistener,但我没有使用jquick,但我喜欢那种简洁明了的风格。 - Nicholas Petersen

5
以下代码将为您提供给定选择器上的所有点击事件:
jQuery(selector).data('events').click

您可以使用each或for等迭代方法进行遍历,例如检查长度以进行验证:

jQuery(selector).data('events').click.length

希望这能对某些人有所帮助。 :)


3
在jQuery版本号大于等于1.8时不再起作用。请参考Tom Gerken的答案获取可行的解决方案。 - jbandi

0

这对我很有用,它显示了发生的事件的对象和类型。

    var foo = $._data( $('body').get(0), 'events' );
    $.each( foo, function(i,o) {
    console.log(i); // guide of the event
    console.log(o); // the function definition of the event handler
    });

-1

我最终做了这个

typeof ($('#mySelector').data('events').click) == "object"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接