Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 通过父级(via.on())获取绑定到元素的函数列表_Javascript_Jquery_Javascript Events - Fatal编程技术网

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

Javascript 通过父级(via.on())获取绑定到元素的函数列表,javascript,jquery,javascript-events,Javascript,Jquery,Javascript Events,我正在尝试使用jQuery的$。\u data()(,但在API中找不到指向任何文档的链接)获取附加到元素的事件列表。如何获取绑定到我的元素的函数名?我在返回的数据中没有看到它。另外,如果函数实际上绑定到父元素,那么如果我只有子元素,是否仍然可以访问函数名?当然,这些必须由jQuery存储在内部的某个地方 var fnPar = function(){ alert("test"); }; var fnChl = function(){ alert("test"); }; $(functi

我正在尝试使用jQuery的
$。\u data()
(,但在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'));

});

它们是针对
处理程序
对象存储的。
处理程序
是(事件,处理程序)

这可以通过以下方式访问:

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();}
});
小提琴:


有关提取与元素关联的所有事件的所有处理程序的更通用的方法,请查看以下答案:

它们是针对
处理程序
对象存储的。
处理程序
是(事件,处理程序)

这可以通过以下方式访问:

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();}
});
小提琴:


有关提取与元素关联的所有事件的所有处理程序的更通用方法,请查看以下答案:

您的问题有两个部分,我将尝试回答。第一个问题:

如何获取绑定到我的元素的函数名

这是一个相当直截了当的问题,你的小提琴实际上走在了正确的道路上。绑定事件处理程序时,处理程序的事件类型将添加到jQuery的内部
\u数据
对象中。例如,如果您这样做:

$('div').on('click', function() { ... })
然后在内部,jQuery将创建一个对象
{}
,并添加一个键,
单击该键。像这样:

{'click': []}
指向对象数组的关键点,这些对象都是使用
click
类型绑定的事件处理程序

如果要添加如下自定义事件:

$('div').on('myfancyhandler', function() {...})
并调用
$。\u data($('div')[0],'events')
,您将看到返回的对象如下:

{'myfancyhandler': []}
因此,当您调用
$.\u 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');
{click: [
    {
        handler: function() { alert(1) }
        /* additional properties */
    },
    {
        handler: function() { alert(2) }
        /* additional properties */
    }
]}
var handlers = $._data($('div')[0], 'events');
handlers.click.forEach(function(obj, idx){
    console.log(obj.handler.name);
});
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
$('#parentElement').on('click', '#childElement', function() { .. do something } );
$._data($('#childElement')[0], 'events');
$._data($('#parentElement')[0], 'events');
{
    click:
        // 0 index array
        0: {
            handler: function doSomething,
            selector: '#childElement'
        }
        delegateCount: 1
}
现在,假设你这样做:

// 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');
{click: [
    {
        handler: function() { alert(1) }
        /* additional properties */
    },
    {
        handler: function() { alert(2) }
        /* additional properties */
    }
]}
var handlers = $._data($('div')[0], 'events');
handlers.click.forEach(function(obj, idx){
    console.log(obj.handler.name);
});
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
$('#parentElement').on('click', '#childElement', function() { .. do something } );
$._data($('#childElement')[0], 'events');
$._data($('#parentElement')[0], 'events');
{
    click:
        // 0 index array
        0: {
            handler: function doSomething,
            selector: '#childElement'
        }
        delegateCount: 1
}
\u data
对象将具有一次单击属性,数组中有两项,如下所示:

// 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');
{click: [
    {
        handler: function() { alert(1) }
        /* additional properties */
    },
    {
        handler: function() { alert(2) }
        /* additional properties */
    }
]}
var handlers = $._data($('div')[0], 'events');
handlers.click.forEach(function(obj, idx){
    console.log(obj.handler.name);
});
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
$('#parentElement').on('click', '#childElement', function() { .. do something } );
$._data($('#childElement')[0], 'events');
$._data($('#parentElement')[0], 'events');
{
    click:
        // 0 index array
        0: {
            handler: function doSomething,
            selector: '#childElement'
        }
        delegateCount: 1
}
从视觉上(在我们的控制台中),您可以看到第一个对象是通知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 */
    }
]}
我们可以这样检查(并获得名称):

// 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');
{click: [
    {
        handler: function() { alert(1) }
        /* additional properties */
    },
    {
        handler: function() { alert(2) }
        /* additional properties */
    }
]}
var handlers = $._data($('div')[0], 'events');
handlers.click.forEach(function(obj, idx){
    console.log(obj.handler.name);
});
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
$('#parentElement').on('click', '#childElement', function() { .. do something } );
$._data($('#childElement')[0], 'events');
$._data($('#parentElement')[0], 'events');
{
    click:
        // 0 index array
        0: {
            handler: function doSomething,
            selector: '#childElement'
        }
        delegateCount: 1
}
这将产生:

控制台
>警报1

>警报2

此外,您可以像这样传递对函数的引用:

// 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');
{click: [
    {
        handler: function() { alert(1) }
        /* additional properties */
    },
    {
        handler: function() { alert(2) }
        /* additional properties */
    }
]}
var handlers = $._data($('div')[0], 'events');
handlers.click.forEach(function(obj, idx){
    console.log(obj.handler.name);
});
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
$('#parentElement').on('click', '#childElement', function() { .. do something } );
$._data($('#childElement')[0], 'events');
$._data($('#parentElement')[0], 'events');
{
    click:
        // 0 index array
        0: {
            handler: function doSomething,
            selector: '#childElement'
        }
        delegateCount: 1
}
至于你的第二个问题,是:

另外,如果函数实际上绑定到父元素,那么如果我只有子元素,是否仍然可以访问函数名

我想您指的是jQuery的
事件委派
。大概是这样的:

// 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');
{click: [
    {
        handler: function() { alert(1) }
        /* additional properties */
    },
    {
        handler: function() { alert(2) }
        /* additional properties */
    }
]}
var handlers = $._data($('div')[0], 'events');
handlers.click.forEach(function(obj, idx){
    console.log(obj.handler.name);
});
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
$('#parentElement').on('click', '#childElement', function() { .. do something } );
$._data($('#childElement')[0], 'events');
$._data($('#parentElement')[0], 'events');
{
    click:
        // 0 index array
        0: {
            handler: function doSomething,
            selector: '#childElement'
        }
        delegateCount: 1
}
然后根据
#childElement
以某种方式获得名为的函数。简单的回答是不,这是不可能的。你说得对,
这些肯定是jQuery内部存储的。

事实上,让我们来看看当我们这样做时会发生什么:

$('#parentElement').on('click', '#childElement', function doSomething() { .. do something } );
jQuery找到
#parentElement
并注册一个单击处理程序。但是,它发现您只希望在
选择器
#childElement
时处理click事件。(如果省略此项,则始终会触发事件。)现在,如果我们执行以下操作:

// 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');
{click: [
    {
        handler: function() { alert(1) }
        /* additional properties */
    },
    {
        handler: function() { alert(2) }
        /* additional properties */
    }
]}
var handlers = $._data($('div')[0], 'events');
handlers.click.forEach(function(obj, idx){
    console.log(obj.handler.name);
});
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
$('#parentElement').on('click', '#childElement', function() { .. do something } );
$._data($('#childElement')[0], 'events');
$._data($('#parentElement')[0], 'events');
{
    click:
        // 0 index array
        0: {
            handler: function doSomething,
            selector: '#childElement'
        }
        delegateCount: 1
}
一概不退还。但是,如果我们这样做:

// 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');
{click: [
    {
        handler: function() { alert(1) }
        /* additional properties */
    },
    {
        handler: function() { alert(2) }
        /* additional properties */
    }
]}
var handlers = $._data($('div')[0], 'events');
handlers.click.forEach(function(obj, idx){
    console.log(obj.handler.name);
});
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
$('#parentElement').on('click', '#childElement', function() { .. do something } );
$._data($('#childElement')[0], 'events');
$._data($('#parentElement')[0], 'events');
{
    click:
        // 0 index array
        0: {
            handler: function doSomething,
            selector: '#childElement'
        }
        delegateCount: 1
}
单击处理程序返回一个对象。看起来像这样的东西:

// 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');
{click: [
    {
        handler: function() { alert(1) }
        /* additional properties */
    },
    {
        handler: function() { alert(2) }
        /* additional properties */
    }
]}
var handlers = $._data($('div')[0], 'events');
handlers.click.forEach(function(obj, idx){
    console.log(obj.handler.name);
});
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
$('#parentElement').on('click', '#childElement', function() { .. do something } );
$._data($('#childElement')[0], 'events');
$._data($('#parentElement')[0], 'events');
{
    click:
        // 0 index array
        0: {
            handler: function doSomething,
            selector: '#childElement'
        }
        delegateCount: 1
}
正如您在返回的对象中所看到的,jQuery在这里存储子元素。当
delegateCount
大于0时,将过滤事件,并根据传入的
选择器对其进行过滤

现在我前面说过,简短的答案是否定的。较长的答案是你可以——你可以(理论上)遍历DOM,检查每个元素,看看它是否有一个事件对象,是否有一个delegateCount,以及选择器是否匹配子元素。不过,这需要实现很多逻辑

最后,还有最后一个技巧:您可以在ChromeDeveloper工具中看到绑定到元素的所有事件处理程序。打开它,单击一个元素,然后选择右侧的“事件侦听器”选项卡。如果有一个事件处理程序绑定,它应该显示在那里。大概是这样的:

// 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');
{click: [
    {
        handler: function() { alert(1) }
        /* additional properties */
    },
    {
        handler: function() { alert(2) }
        /* additional properties */
    }
]}
var handlers = $._data($('div')[0], 'events');
handlers.click.forEach(function(obj, idx){
    console.log(obj.handler.name);
});
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
$('#parentElement').on('click', '#childElement', function() { .. do something } );
$._data($('#childElement')[0], 'events');
$._data($('#parentElement')[0], 'events');
{
    click:
        // 0 index array
        0: {
            handler: function doSomething,
            selector: '#childElement'
        }
        delegateCount: 1
}


祝你好运

你的问题有两个部分我会尽力回答。第一个问题:

如何获取绑定到我的元素的函数名

这是一个相当直截了当的问题,你的小提琴实际上走在了正确的道路上。绑定事件处理程序时,处理程序的事件类型将添加到jQuery的内部
\u数据
对象中。例如,如果您这样做:

$('div').on('click', function() { ... })
然后在内部,jQuery将创建一个对象
{}
,并添加一个键,
单击该键。像这样:

{'click': []}
指向对象数组的关键点,这些对象都是使用
click
类型绑定的事件处理程序

如果要添加如下自定义事件:

$('div').on('myfancyhandler', function() {...})
并调用
$。\u data($('div')[0],'events')
,您将看到返回的对象如下:

{'myfancyhandler': []}
因此,当您调用
$.\u 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');
{click: [
    {
        handler: function() { alert(1) }
        /* additional properties */
    },
    {
        handler: function() { alert(2) }
        /* additional properties */
    }
]}
var handlers = $._data($('div')[0], 'events');
handlers.click.forEach(function(obj, idx){
    console.log(obj.handler.name);
});
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
$('#parentElement').on('click', '#childElement', function() { .. do something } );
$._data($('#childElement')[0], 'events');
$._data($('#parentElement')[0], 'events');
{
    click:
        // 0 index array
        0: {
            handler: function doSomething,
            selector: '#childElement'
        }
        delegateCount: 1
}
现在,假设你这样做:

// 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');
{click: [
    {
        handler: function() { alert(1) }
        /* additional properties */
    },
    {
        handler: function() { alert(2) }
        /* additional properties */
    }
]}
var handlers = $._data($('div')[0], 'events');
handlers.click.forEach(function(obj, idx){
    console.log(obj.handler.name);
});
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
$('#parentElement').on('click', '#childElement', function() { .. do something } );
$._data($('#childElement')[0], 'events');
$._data($('#parentElement')[0], 'events');
{
    click:
        // 0 index array
        0: {
            handler: function doSomething,
            selector: '#childElement'
        }
        delegateCount: 1
}
\u data
对象将具有一次单击属性,数组中有两项,如下所示:

// 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');
{click: [
    {
        handler: function() { alert(1) }
        /* additional properties */
    },
    {
        handler: function() { alert(2) }
        /* additional properties */
    }
]}
var handlers = $._data($('div')[0], 'events');
handlers.click.forEach(function(obj, idx){
    console.log(obj.handler.name);
});
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
$('#parentElement').on('click', '#childElement', function() { .. do something } );
$._data($('#childElement')[0], 'events');
$._data($('#parentElement')[0], 'events');
{
    click:
        // 0 index array
        0: {
            handler: function doSomething,
            selector: '#childElement'
        }
        delegateCount: 1
}
从视觉上(在我们的控制台中),您可以看到第一个对象是通知1的函数,第二个是通知1的函数