javascript - 通过父级获取绑定(bind)到元素的函数列表(通过 .on() )

标签 javascript jquery jquery-events

我正在尝试使用 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)了事件处理程序,它应该显示在那里。像这样的事情:

enter image description here

祝你好运!

关于javascript - 通过父级获取绑定(bind)到元素的函数列表(通过 .on() ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24154328/

相关文章:

javascript - jQuery - 在 Fancybox 中触发点击

jquery - 导入错误: You have an error in your SQL syntax;

javascript - 如何修复此 JQuery 函数以获取被单击元素的父 li 元素的 data-value 值?

javascript - 链接环绕在 Jquery 中的图像点击事件

javascript - 检测浏览器是否支持右键事件覆盖

javascript - 谷歌地图回调后Angular2双向绑定(bind)停止工作

javascript - 使用 Javascript 动态创建表以显示数据库 SELECT 查询输出

javascript - 如何与jasmine.execute同步?

jquery - $.extend 中第一个 bool 参数的用途是什么

javascript - 如何使此 slider 自动