如何绑定DOM元素的所有事件?

64

如何使用jQuery将DOM元素的所有事件(例如clickkeypressmousedown)绑定在一起,而不需要逐个列出每个事件?

示例:

$('#some-el').bind('all events', function(e) {
    console.log(e.type);
});
7个回答

55

有一种简单(但不准确)的方法来测试所有事件:

function getAllEvents(element) {
    var result = [];
    for (var key in element) {
        if (key.indexOf('on') === 0) {
            result.push(key.slice(2));
        }
    }
    return result.join(' ');
}
然后像这样绑定所有事件:
var el = $('#some-el');
el.bind(getAllEvents(el[0]), function(e) {
    /* insert your code */
});

3
在Chrome 12和FF 5中,对于textarea或input类型的按钮完全没有任何作用。 - Bobby
2
@Bobby,代码中缺少了“.slice(2)” - 我已经修复了它。 - Jo Liss
这个答案已经过时了,对于新的JQuery版本,请使用事件列表而不是"getAllEvents"函数调用:"blur change click contextmenu dblclick error focus focusin focusout keydown keypress keyup load mousedown mouseenter mouseleave mousemove mouseout mouseover mouseup resize scroll select submit unload"。 - ElLocoCocoLoco

54

您也可以重新定义jQuery.event.trigger以捕获每个事件,但我认为,这种方法只适用于探索外部API,不适合生产:

var oldJQueryEventTrigger = jQuery.event.trigger;
jQuery.event.trigger = function( event, data, elem, onlyHandlers ) { 
  console.log( event, data, elem, onlyHandlers ); 
  oldJQueryEventTrigger( event, data, elem, onlyHandlers ); 
}

3
这正好做到了我所希望的事情。+1 - MLK.DEV

10

这是一个用于jQuery的小扩展:

$.fn.onAny = function(cb){
  for(var k in this[0])
    if(k.search('on') === 0)
      this.on(k.slice(2), function(e){
        // Probably there's a better way to call a callback function with right context, $.proxy() ?
        cb.apply(this,[e]);
      });
  return this;
};    

用法:

$('#foo').onAny(function(e){
  console.log(e.type);
});  

你也可以直接使用浏览器控制台(来自这个回答):

monitorEvents($0, 'mouse'); // log all events of an inspected element
monitorEvents(document.body); // log all events on the body
monitorEvents(document.body, 'mouse'); // log mouse events on the body
monitorEvents(document.body.querySelectorAll('input')); // log all events on inputs

9
如果您想将多个事件绑定到同一个函数,请使用空格进行分隔。
$("#test").bind("blur focus focusin focusout load resize scroll unload click " +
    "dblclick mousedown mouseup mousemove mouseover mouseout mouseenter " + 
     "mouseleave change select submit keydown keypress keyup error", function(e){
    $("#r").empty().text(e.type);
});

Simple example on jsfiddle


上下文菜单在列表中缺失 - ElLocoCocoLoco

9

jQuery改变了它保存事件的方式,提取列表有几种方法, 具体取决于你使用的版本。我已经在插件中封装了“最新”的版本,但基本上你需要:

var events = $._data($('yourelement')[0], "events");

这将提供一个嵌套列表,列出所有绑定事件,按“基本”事件(无命名空间)分组。
然而,我刚意识到您想要所有本机的 jQuery 事件 - 您可以检查 $.event,其中一些事件在 $.event.special 下,但 已接受的答案 可能仍然是您最好的选择。您还可以查看 jQuery 列出的可能绑定函数

3

我认为jQuery不支持任何通配符(这将是困难和充满危险的),但标准事件列表是有限的(尽管遗憾地有点分散在DOM2事件规范DOM2 HTML规范DOM3事件规范中),你可以简单地列出它们。jQuery允许您绑定多个事件名称(以空格分隔),例如:

$('#some-el').bind('click dblclick mouseover mouseout' /* etc.*/,function(e){
    console.log(e.type);
});

以下是所有可能的事件列表(来自jquery源代码):blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu - Armin
不幸的是,有一些特定于浏览器的事件,比如“剪切”和“粘贴”。当然还有自定义事件。 - André Laszlo
@Armin,jQuery似乎没有提到onwheel事件。 - user31782

0

我拿了Mark Coleman的脚本并根据我的需求进行了一些增强。

我想与您分享它:http://jsfiddle.net/msSy3/65/

var lastEvent = null,
    countEvent = 0;
$("#test").bind("blur focus focusin focusout load resize scroll unload click" + " dblclick mousedown mouseup mousemove mouseover mouseout mouseenter " + "mouseleave change select submit keydown keypress keyup error", function (e) {
    if (lastEvent !== e.type) {
        countEvent++;
        $("#r").prepend("<span>" + countEvent + ": " + e.type + "<br></span>");
        $("#r > span:nth-child(21)").remove();
        lastEvent = e.type;
    }
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接