我正在尝试使用 jQuery 的 $._data()
获取附加到元素的事件列表( seen here ,但我找不到 API 中任何文档的链接)。如何获取绑定(bind)到我的元素的函数的名称?我在返回的数据中没有看到它。另外,如果函数实际上绑定(bind)到父元素,那么如果我只有子元素,是否可以访问函数名称?当然,这些必须由 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'));
});
最佳答案
您的问题分为两个部分,我将尽力回答。第一个问题:
How can get the name of the function bound to my element?
这个相当简单,而且你的 fiddle 实际上走在正确的道路上。当您绑定(bind)事件处理程序时,处理程序的事件类型将添加到 jQuery 的内部 _data
对象中。因此,例如,如果您这样做:
$('div').on('click', function() { ... })
然后,jQuery 将在内部创建一个对象 {}
并添加一个键,click
到该对象。像这样:
{'click': []}
关键点指向一个对象数组,这些对象是您使用 click
类型绑定(bind)的所有事件处理程序。
如果您要添加这样的自定义事件:
$('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: [
{
handler: function() { alert(1) }
/* additional properties */
},
{
handler: function() { alert(2) }
/* additional properties */
}
]}
从视觉上(在我们的控制台中),您可以看到第一个对象是警报 1 的函数,第二个对象是警报 2 的函数。但是,如果您需要以编程方式检查怎么办?为此,我们需要命名我们的匿名函数
,如下所示:
$('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);
});
这将输出:
控制台
>警报1
>警报2
此外,您还可以传递对函数的引用,如下所示:
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
至于你的第二个问题是:
Also, if the function is actually bound to a parent element, is there anyway to access the functions name if I only have the the child?
我认为您指的是 jQuery 的事件委托(delegate)
。像这样的事情:
$('#parentElement').on('click', '#childElement', function() { .. do something } );
然后以某种方式获取基于#childElement
命名的函数。简短的回答是否定的,这是不可能的。当你说当然这些必须由 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 开发者工具中查看绑定(bind)到某个元素的所有事件处理程序。打开它,单击一个元素,然后选择右侧的“事件监听器”选项卡。如果绑定(bind)了事件处理程序,它应该显示在那里。像这样的事情:
祝你好运!
关于javascript - 通过父级获取绑定(bind)到元素的函数列表(通过 .on() ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24154328/