我需要找出一个对象上注册的事件处理程序。
例如:
$("#el").click(function() {...});
$("#el").mouseover(function() {...});
$("#el")
已注册了click和mouseover事件。
有没有一种方法可以查找它们,并可能迭代事件处理程序?
如果无法通过适当的方法在jQuery对象上实现,那么在普通DOM对象上是否可行?
从jQuery 1.8开始,事件数据不再在“公共API”中提供。请阅读jQuery博客文章。现在应该使用以下内容:
jQuery._data( elem, "events" );
elem
应该是一个 HTML 元素,而不是 jQuery 对象或选择器。
请注意,这是一种内部的“私有”结构,不应进行修改。仅用于调试目的。
在旧版本的 jQuery 中,你可能需要使用旧的方法:
jQuery( elem ).data( "events" );
$._data($(elem).get(0), "events")
。 - bullgarevar events = (jQuery._data || jQuery.data)(elem, 'events');
- oriadam你可以通过爬取事件(自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
});
});
这里有一个你可以自己尝试的例子:
$(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>
jQuery._data(jQuery("#el")[0], "events");
而不是“公共数据”方法:jQuery("#el").data("events")
。实际上已经很长时间没有将events
对象存储在.data()
中了,我们通过从“公共API”中删除此“代理”来删除了一些字节的代码。 - gnarf对于 jQuery 1.8+ 版本,由于内部数据被放置在不同的对象中,原来的方法将不再起作用。
现在最新的非官方方法(但在以前的版本中也有效,至少在 1.7.2 版本中有效)是 -
$._data(element, "events")
这里下划线("_")很关键。在内部,它调用了 $.data(element, name, null, true)
,最后(第四个)参数是内部参数(“pvt”)。
jQuery._data( element, "events" )
是获取此信息的“正确”方式。 - gnarf我不好意思做广告,但你可以使用findHandlerJS
你只需要包含findHandlersJS(或者只需将原始javascript代码复制并粘贴到Chrome浏览器的控制台窗口),然后指定事件类型和jQuery选择器,以查找你感兴趣的元素的事件处理程序。
例如,你可以通过以下方式快速查找你提到的事件处理程序:
findEventHandlers("click", "#el")
findEventHandlers("mouseover", "#el")
这是返回的内容:
您可以在此处进行尝试
我将@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 {};
};
但要注意,该函数只能返回使用jQuery设置的事件。
检查元素上的事件:
var events = $._data(element, "events")
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])
getEvents
方法总体来说很好,但问题是,在IE11中它会给出重复的条目(我知道,又是IE,但公司需要它...)。编辑:$._data 包含元素的重复事件,即使在FF中它不包含任何事件...奇怪的IE世界。但是要注意可能存在重复事件的可能性。 - Dominik SzymańskijQuery._data( elem, "events" );
... - Ian(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);
例子:
$(":event(click)")
在具备ECMAScript 5.1 / Array.prototype.map
的现代浏览器中,您还可以使用
jQuery._data(DOCUMENTELEMENT,'events')["EVENT_NAME"].map(function(elem){return elem.handler;});
var events = (jQuery._data || jQuery.data)(elem, 'events');
- oriadam