我正在尝试使用jQuery&{39} $._data()
seen here获取附加到元素的事件列表,但我找不到API中任何文档的链接。如何获取绑定到我的元素的函数的名称?我没有在返回的数据中看到它。此外,如果函数实际上绑定到父元素,如果我只有孩子,是否仍然可以访问函数名称?当然这些必须通过jQuery存储在内部。
var fnPar = function(){
alert("test");
};
var fnChl = function(){
alert("test");
};
$(function(){
$("body").on("click", "#par", function(){
fnPar();
});
$("#par").on("click", "#chl", function(){
fnChl();
});
console.log($._data($('#par')[0], 'events'));
console.log($._data($('#chl')[0], 'events'));
});
答案 0 :(得分:4)
我的问题中有两部分我会尝试回答。第一个问题:
如何获取绑定到元素的函数名称?
这个是相当直接的,你实际上是在你的小提琴的正确道路上。绑定事件处理程序时,处理程序的事件类型将添加到jQuery的内部_data
对象中。所以,例如,如果你这样做:
$('div').on('click', function() { ... })
然后在内部,jQuery将创建一个对象{}
并向其添加一个键click
。像这样:
{'click': []}
关键点指向一组对象,这些对象是您使用click
类型绑定的所有事件处理程序。
如果你要添加这样的自定义事件:
$('div').on('myfancyhandler', function() {...})
并调用$._data($('div')[0], 'events')
,您会看到一个返回的对象:
{'myfancyhandler': []}
因此,当您调用$._data( el , 'events')
时,您可以访问处理程序属性(指向处理程序的数组),如下所示:
// Bind two event handlers - click and our custom myfancyhandler event
$('div').on('click myfancyhandler', function() { });
// Returns object {click: [], myfancyhandler: []}
var handlers = $._data($('div')[0], 'events');
// Access handler (function passed for callback)
var handler = handlers.click[0].handler; // dot notation, square bracket works too
现在,假设你做了这样的事情:
$('div').on('click', function(){ alert(1) });
$('div').on('click', function(){ alert(2) });
var handlers = $._data($('div')[0], 'events');
_data
对象将有一个click属性,其中包含数组中的两个项目,如下所示:
{click: [
{
handler: function() { alert(1) }
/* additional properties */
},
{
handler: function() { alert(2) }
/* additional properties */
}
]}
在视觉上(在我们的控制台中),您可以看到第一个对象是警报1的函数,第二个函数警告2.但是,如果您需要以编程方式检查,该怎么办?为此,我们需要将anonymous functions
命名为:{/ p>
$('div').on('click', function alert1(){ alert(1) });
$('div').on('click', function alert2(){ alert(2) });
var handlers = $._data($('div')[0], 'events');
哪会让我们回复:
{click: [
{
handler: function alert1() { alert(1) }
/* additional properties */
},
{
handler: function alert2() { alert(2) }
/* additional properties */
}
]}
然后我们可以检查(并得到名称):
var handlers = $._data($('div')[0], 'events');
handlers.click.forEach(function(obj, idx){
console.log(obj.handler.name);
});
那会输出:
<强>控制台强>
> alert1
> alert2
此外,您可以传递对此函数的引用,如下所示:
function ourCoolHandler() { .. does something .. }
// Bind our cool handler
$('div').on('keyup', ourCoolHandler);
// Get event object
var evtObj = $._data($('div')[0], 'events')
// Get function name from handler object
console.log(evtObj.keyup[0].handler.name) // ourCoolHandler
关于你的第二个问题,即:
另外,如果函数实际上绑定到父元素,那么如果我只有子元素,是否仍然可以访问函数名称?
我认为你指的是jQuery的event delegation
。像这样:
$('#parentElement').on('click', '#childElement', function() { .. do something } );
然后以某种方式获得基于#childElement
命名的函数。简短的回答是否定的,这是不可能做到的。当你说Surely these must be stored internally somewhere by jQuery.
事实上,让我们来看看当我们这样做时会发生什么:
$('#parentElement').on('click', '#childElement', function doSomething() { .. do something } );
jQuery找到#parentElement
并注册一个点击处理程序。但是,它看到您只想在selector
为#childElement
时处理点击事件。 (如果省略,则始终触发事件。)现在,如果我们执行以下操作:
$._data($('#childElement')[0], 'events');
什么都不会被退回。但是,如果我们这样做:
$._data($('#parentElement')[0], 'events');
使用我们的点击处理程序返回一个对象。看起来像这样:
{
click:
// 0 index array
0: {
handler: function doSomething,
selector: '#childElement'
}
delegateCount: 1
}
正如您在返回的对象中看到的那样,这是jQuery存储子元素的位置。当delegateCount
大于0时会过滤这些事件,并会针对传入的selector
对其进行过滤。
现在我说的简短回答是否定的。更长的答案是你可以 - 你可以(理论上)遍历DOM并检查每个元素以查看它是否具有事件对象,具有delegateCount,以及选择器是否与子元素匹配。但是,这需要很多逻辑来实现。
最后,最后一招:您可以在Chrome Developer Tool中看到绑定到元素的所有事件处理程序。打开它,单击一个元素,然后选择&#34;事件监听器&#34;选项卡在右侧。如果绑定了一个事件处理程序,它应该显示在那里。像这样:
祝你好运!
答案 1 :(得分:0)
它们存储在handler
对象中。 handler
是.on(events, handler)
可以通过以下方式访问:
var functionNameGoesHere = function () {
alert("test");
};
$(function () {
$("#par").on("click", function () {
functionNameGoesHere();
});
var elem = $('#par')[0];
var data = jQuery.hasData( elem ) && jQuery._data( elem );
console.log(data.events.click[0].handler); //function() {functionNameGoesHere();}
});
小提琴: http://jsfiddle.net/KyleMuir/DHF4a/
有关抽出与元素相关的所有事件的所有处理程序的更通用方法,请查看以下答案:Accessing functions bound to event handlers with jQuery