如何记录jQuery中某个元素触发的所有事件?


94

我想查看用户与之交互时由输入字段触发的所有事件。包括以下内容:

  1. 点击它。
  2. 单击它。
  3. 跳入它。
  4. 远离它。
  5. Ctrl+ CCtrl+V键盘上的。
  6. 右键单击->粘贴。
  7. 右键单击->剪切。
  8. 右键单击->复制。
  9. 从另一个应用程序中拖放文本。
  10. 用Javascript修改它。
  11. 使用调试工具(如Firebug)对其进行修改。

我想使用显示它console.log。这在Javascript / jQuery中是可能的,如果可以,我该怎么做?


您的问题很有趣,但是您在一条评论中说:“我一直在寻找的是所有已触发事件的列表,所以我知道哪些事件可供我使用” –为什么您不只是问那个?MSDN的doco对此非常有用:msdn.microsoft.com/en-us/library/ms533051(v=VS.85).aspx-并非所有浏览器都支持列出的所有事件,但是如果您检查doco是否具有事件'on_xyz_',它将告诉您“此事件在HTML 4.0中定义。”或“没有适用于此事件的公共标准”或其他内容。
nnnnnn

Answers:


63
$(element).on("click mousedown mouseup focus blur keydown change",function(e){
     console.log(e);
});

如果事件被触发,那将为您提供很多(但不是全部)信息……除了像这样手动编码之外,我想不出任何其他方式来做到这一点。


奇怪的是您和Shawn都拼错了function,并且用同样的方式:)。
Daniel T.

1
看来此方法将绑定所有本机事件。我猜测无法显示自定义事件,例如,如果某个插件触发了一些自定义事件?
Daniel T.

1
我接受这个作为答案,但是对我的问题的真正答案是“是和不是”。我一直在寻找的是要触发的所有事件的列表,因此我知道哪些事件可供我使用。在这种情况下,我可以看到何时触发事件,但是我必须事先知道事件的名称。
Daniel T.

3
@Joseph:关于您先前的评论“焦点不是本地事件”-嗯...是的,早在jQuery(就此而言,在Chrome和FF之前)就已经存在了。另外,您可能要添加blur到事件列表中。
nnnnnn

3
monitorEvents(document)是真正的答案
neaumusic 2015年

204

我不知道为什么没人使用这个...(也许是因为这只是Webkit的事情)

打开控制台:

monitorEvents(document.body); // logs all events on the body

monitorEvents(document.body, 'mouse'); // logs mouse events on the body

monitorEvents(document.body.querySelectorAll('input')); // logs all events on inputs

7
它不涵盖自定义事件,但确实有助于了解事件堆栈。
sidonaldson

这是正确的答案。您不想在生产代码中使用console.log,可以使用控制台调试事件
neaumusic 2015年

1
Googleing monitorEvents对此也没有提供任何相关信息,我也非常怀疑这是非常不规范的
vsync

3
@vsync尝试用引号将“ monitorEvents”。它是控制台对象的一部分,但取决于浏览器。它仅是调试工具,因为它取决于控制台...因此成为标准无关紧要
sidonaldson

2
请注意,您还可以使用类似的方式monitorEvents($0, 'mouse');来记录已检查(右键单击>“检查”)元素的所有事件。(briangrinstead.com/blog/chrome-developer-tools-monitorevents
rinogo

32

使用.data('events')集合有一种不错的通用方法:

function getEventsList($obj) {
    var ev = new Array(),
        events = $obj.data('events'),
        i;
    for(i in events) { ev.push(i); }
    return ev.join(' ');
}

$obj.on(getEventsList($obj), function(e) {
    console.log(e);
});

当特定事件被触发时,这将记录jQuery已经绑定到元素的每个事件。这段代码对我有很多帮助。

顺便说一句:如果您想查看在对象上引发的所有可能的事件,请使用firebug:只需在html选项卡中的DOM元素上单击鼠标右键,然后选中“日志事件”。然后,每个事件都会记录到控制台(这有时有点烦人,因为它记录了每次鼠标移动...)。


18
$('body').on("click mousedown mouseup focus blur keydown change mouseup click dblclick mousemove mouseover mouseout mousewheel keydown keyup keypress textInput touchstart touchmove touchend touchcancel resize scroll zoom focus blur select change submit reset",function(e){
     console.log(e);
}); 

3
最完整的答案
leymannx

12

我知道答案已经被接受,但是我认为可能有一种稍微可靠的方法,您不必事先知道事件的名称。据我所知,这仅适用于本机事件,不适用于由插件创建的自定义事件。我选择省略jQuery来简化一些事情。

let input = document.getElementById('inputId');

Object.getOwnPropertyNames(input)
  .filter(key => key.slice(0, 2) === 'on')
  .map(key => key.slice(2))
  .forEach(eventName => {
    input.addEventListener(eventName, event => {
      console.log(event.type);
      console.log(event);
    });
  });

我希望这对阅读本文的人有所帮助。

编辑

所以我在这里看到了另一个类似的问题,所以另一个建议是做以下事情:

monitorEvents(document.getElementById('inputId'));

这是一堆最优雅的解决方案。我想不可能发现自定义事件,因为这些事件可以通过dispatchEvent()发出。但是,这以紧凑,无依赖的少量代码覆盖了其他所有内容。
罗伯托

10

我知道是旧线程。我还需要一些东西来监视事件,并编写了这个非常方便(出色)的解决方案。您可以使用此挂钩监视所有事件(在Windows编程中,这称为挂钩)。该挂钩不会影响您的软件/程序的操作。

控制台日志中,您可以看到以下内容:

控制台日志

您看到的解释:

在控制台日志中,您将看到您选择的所有事件(请参见下面的“如何使用”),并显示对象类型,类名,id,<:函数名>,<:eventname>。对象的格式类似于css。

单击按钮或任何绑定的事件时,您将在控制台日志中看到它。

我写的代码:

function setJQueryEventHandlersDebugHooks(bMonTrigger, bMonOn, bMonOff)
{
   jQuery.fn.___getHookName___ = function()    
       {
          // First, get object name
         var sName = new String( this[0].constructor ),
         i = sName.indexOf(' ');
         sName = sName.substr( i, sName.indexOf('(')-i );    

         // Classname can be more than one, add class points to all
         if( typeof this[0].className === 'string' )
         {
           var sClasses = this[0].className.split(' ');
           sClasses[0]='.'+sClasses[0];
           sClasses = sClasses.join('.');
           sName+=sClasses;
         }
         // Get id if there is one
         sName+=(this[0].id)?('#'+this[0].id):'';
         return sName;
       };

   var bTrigger        = (typeof bMonTrigger !== "undefined")?bMonTrigger:true,
       bOn             = (typeof bMonOn !== "undefined")?bMonOn:true,
       bOff            = (typeof bMonOff !== "undefined")?bMonOff:true,
       fTriggerInherited = jQuery.fn.trigger,
       fOnInherited    = jQuery.fn.on,
       fOffInherited   = jQuery.fn.off;

   if( bTrigger )
   {
    jQuery.fn.trigger = function()
    {
     console.log( this.___getHookName___()+':trigger('+arguments[0]+')' );
     return fTriggerInherited.apply(this,arguments);
    };
   }

   if( bOn )
   {
    jQuery.fn.on = function()
    {
     if( !this[0].__hooked__ ) 
     {
       this[0].__hooked__ = true; // avoids infinite loop!
       console.log( this.___getHookName___()+':on('+arguments[0]+') - binded' );
       $(this).on( arguments[0], function(e)
       {
         console.log( $(this).___getHookName___()+':'+e.type );
       });
     }
     var uResult = fOnInherited.apply(this,arguments);
     this[0].__hooked__ = false; // reset for another event
     return uResult;
    };
   }

   if( bOff )
   {
    jQuery.fn.off = function()
    {
     if( !this[0].__unhooked__ ) 
     {
       this[0].__unhooked__ = true; // avoids infinite loop!
       console.log( this.___getHookName___()+':off('+arguments[0]+') - unbinded' );
       $(this).off( arguments[0] );
     }

     var uResult = fOffInherited.apply(this,arguments);
     this[0].__unhooked__ = false; // reset for another event
     return uResult;
    };
   }
}

示例如何使用它:

监视所有事件:

setJQueryEventHandlersDebugHooks();

仅监视所有触发器:

setJQueryEventHandlersDebugHooks(true,false,false);

仅监视所有ON事件:

setJQueryEventHandlersDebugHooks(false,true,false);

仅监视所有未绑定的绑定:

setJQueryEventHandlersDebugHooks(false,false,true);

备注/注意:

  • 仅用于调试,在产品最终版本中使用时将其关闭
  • 如果要查看所有事件,则必须在加载jQuery之后直接调用此函数
  • 如果只想查看较少的事件,则可以在需要时调用该函数
  • 如果要自动执行,请放置()();。围绕功能

希望能帮助到你!;-)


嗨@AmirFo,感谢您的尝试。因为您没有提供任何示例,但是您无法查看问题是否出在您的代码或我的问题中。因为有其他人成功使用了此示例,所以您可能做错了什么。您是否检查过代码中的错误?
Codebeat

没有错误。我触发了一些事件,但是控制台中没有日志!我正在Ubuntu,Linux中使用最新版的chrome。
阿米尔·佛

@AmirFo:您是否也在Firefox中尝试过?什么版本的jQuery?
Codebeat

@AmirFo:您是如何触发事件的?您是否在触发事件之前将任何事件绑定到DOM元素?
Codebeat

4

https://github.com/robertleeplummerjr/wiretap.js

new Wiretap({
  add: function() {
      //fire when an event is bound to element
  },
  before: function() {
      //fire just before an event executes, arguments are automatic
  },
  after: function() {
      //fire just after an event executes, arguments are automatic
  }
});

1
您能否提供更多有关其工作原理以及确切功能的信息?如何将其附加到元素上?
约西亚

该脚本已修改HTMLElement.prototype.addEventListener,可能不应该在生产中使用,但是对于调试目的,它已经对我有很大帮助。
君特Zöchbauer

1
这不适用于1个元素,它适用于所有元素。它利用窗口的事件处理程序,并监听发生的一切。它与本机事件处理程序和jQuery一起使用。
罗伯特·普鲁默

2

只需将其添加到页面中,就没有其他后顾之忧了,将为您解决其他问题:

$('input').live('click mousedown mouseup focus keydown change blur', function(e) {
     console.log(e);
});

您也可以使用console.log('Input event:'+ e.type)使其更容易。


3
奇怪的是,您和约瑟都是怎么拼错的function,并且以相同的方式:)。
Daniel T.

大声笑,嘿...他写了一些,我有了进步。;)
Shawn Khameneh 2011年

1
不要让我评论其他答案,您可以使用.data(“ events”)来获取事件列表。
肖恩·哈梅内

它是如何工作的?我试过了$('input').data('events'),它返回未定义。
Daniel T.

这将返回当前的绑定事件,其中包括自定义事件。如果没有事件绑定,它将返回未定义。
肖恩·哈梅内

1

第1步:检查eventsHTML elementdeveloper console

在此处输入图片说明

步骤2:聆听events我们要捕获的内容:

$(document).on('ch-ui-container-closed ch-ui-container-opened', function(evt){
 console.log(evt);
});

祝好运...


1

我最近从现有的SO帖子中找到并修改了此代码段,但我无法再次找到它,但我发现它非常有用

// specify any elements you've attached listeners to here
const nodes = [document]

// https://developer.mozilla.org/en-US/docs/Web/Events
const logBrowserEvents = () => {
  const AllEvents = {
    AnimationEvent: ['animationend', 'animationiteration', 'animationstart'],
    AudioProcessingEvent: ['audioprocess'],
    BeforeUnloadEvent: ['beforeunload'],
    CompositionEvent: [
      'compositionend',
      'compositionstart',
      'compositionupdate',
    ],
    ClipboardEvent: ['copy', 'cut', 'paste'],
    DeviceLightEvent: ['devicelight'],
    DeviceMotionEvent: ['devicemotion'],
    DeviceOrientationEvent: ['deviceorientation'],
    DeviceProximityEvent: ['deviceproximity'],
    DragEvent: [
      'drag',
      'dragend',
      'dragenter',
      'dragleave',
      'dragover',
      'dragstart',
      'drop',
    ],
    Event: [
      'DOMContentLoaded',
      'abort',
      'afterprint',
      'beforeprint',
      'cached',
      'canplay',
      'canplaythrough',
      'change',
      'chargingchange',
      'chargingtimechange',
      'checking',
      'close',
      'dischargingtimechange',
      'downloading',
      'durationchange',
      'emptied',
      'ended',
      'error',
      'fullscreenchange',
      'fullscreenerror',
      'input',
      'invalid',
      'languagechange',
      'levelchange',
      'loadeddata',
      'loadedmetadata',
      'noupdate',
      'obsolete',
      'offline',
      'online',
      'open',
      'open',
      'orientationchange',
      'pause',
      'play',
      'playing',
      'pointerlockchange',
      'pointerlockerror',
      'ratechange',
      'readystatechange',
      'reset',
      'seeked',
      'seeking',
      'stalled',
      'submit',
      'success',
      'suspend',
      'timeupdate',
      'updateready',
      'visibilitychange',
      'volumechange',
      'waiting',
    ],
    FocusEvent: [
      'DOMFocusIn',
      'DOMFocusOut',
      'Unimplemented',
      'blur',
      'focus',
      'focusin',
      'focusout',
    ],
    GamepadEvent: ['gamepadconnected', 'gamepaddisconnected'],
    HashChangeEvent: ['hashchange'],
    KeyboardEvent: ['keydown', 'keypress', 'keyup'],
    MessageEvent: ['message'],
    MouseEvent: [
      'click',
      'contextmenu',
      'dblclick',
      'mousedown',
      'mouseenter',
      'mouseleave',
      'mousemove',
      'mouseout',
      'mouseover',
      'mouseup',
      'show',
    ],
    // https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Mutation_events
    MutationNameEvent: ['DOMAttributeNameChanged', 'DOMElementNameChanged'],
    MutationEvent: [
      'DOMAttrModified',
      'DOMCharacterDataModified',
      'DOMNodeInserted',
      'DOMNodeInsertedIntoDocument',
      'DOMNodeRemoved',
      'DOMNodeRemovedFromDocument',
      'DOMSubtreeModified',
    ],
    OfflineAudioCompletionEvent: ['complete'],
    OtherEvent: ['blocked', 'complete', 'upgradeneeded', 'versionchange'],
    UIEvent: [
      'DOMActivate',
      'abort',
      'error',
      'load',
      'resize',
      'scroll',
      'select',
      'unload',
    ],
    PageTransitionEvent: ['pagehide', 'pageshow'],
    PopStateEvent: ['popstate'],
    ProgressEvent: [
      'abort',
      'error',
      'load',
      'loadend',
      'loadstart',
      'progress',
    ],
    SensorEvent: ['compassneedscalibration', 'Unimplemented', 'userproximity'],
    StorageEvent: ['storage'],
    SVGEvent: [
      'SVGAbort',
      'SVGError',
      'SVGLoad',
      'SVGResize',
      'SVGScroll',
      'SVGUnload',
    ],
    SVGZoomEvent: ['SVGZoom'],
    TimeEvent: ['beginEvent', 'endEvent', 'repeatEvent'],
    TouchEvent: [
      'touchcancel',
      'touchend',
      'touchenter',
      'touchleave',
      'touchmove',
      'touchstart',
    ],
    TransitionEvent: ['transitionend'],
    WheelEvent: ['wheel'],
  }

  const RecentlyLoggedDOMEventTypes = {}

  Object.keys(AllEvents).forEach((DOMEvent) => {
    const DOMEventTypes = AllEvents[DOMEvent]

    if (Object.prototype.hasOwnProperty.call(AllEvents, DOMEvent)) {
      DOMEventTypes.forEach((DOMEventType) => {
        const DOMEventCategory = `${DOMEvent} ${DOMEventType}`

        nodes.forEach((node) => {
          node.addEventListener(
            DOMEventType,
            (e) => {
              if (RecentlyLoggedDOMEventTypes[DOMEventCategory]) return

              RecentlyLoggedDOMEventTypes[DOMEventCategory] = true

              // NOTE: throttle continuous events
              setTimeout(() => {
                RecentlyLoggedDOMEventTypes[DOMEventCategory] = false
              }, 1000)

              const isActive = e.target === document.activeElement

              // https://developer.mozilla.org/en-US/docs/Web/API/DocumentOrShadowRoot/activeElement
              const hasActiveElement = document.activeElement !== document.body

              const msg = [
                DOMEventCategory,
                'target:',
                e.target,
                ...(hasActiveElement
                  ? ['active:', document.activeElement]
                  : []),
              ]

              if (isActive) {
                console.info(...msg)
              }
            },
            true,
          )
        })
      })
    }
  })
}
logBrowserEvents()
// export default logBrowserEvents

1
function bindAllEvents (el) {
  for (const key in el) {
      if (key.slice(0, 2) === 'on') {
          el.addEventListener(key.slice(2), e => console.log(e.type));
      }
  }
}
bindAllEvents($('.yourElement'))

为了美观起见,它使用了一些ES6,但也可以轻松地将其翻译为旧版浏览器。在事件监听器附带的函数中,当前它只是注销发生了哪种事件,但这是您可以打印出其他信息的位置,或者使用上的开关盒e.type,您只能打印特定事件的信息。


0

这是一种非jquery的方法,可使用您的代码在控制台中监视事件,而无需使用monitorEvents(),因为它仅在Chrome开发者控制台中有效。您也可以通过编辑no_watch数组选择不监视某些事件。

    function getEvents(obj) {
    window["events_list"] = [];
    var no_watch = ['mouse', 'pointer']; // Array of event types not to watch
    var no_watch_reg = new RegExp(no_watch.join("|"));

    for (var prop in obj) {
        if (prop.indexOf("on") === 0) {
            prop = prop.substring(2); // remove "on" from beginning
            if (!prop.match(no_watch_reg)) {
                window["events_list"].push(prop);
                window.addEventListener(prop, function() {
                    console.log(this.event); // Display fired event in console
                } , false);
            }
        }
    }
    window["events_list"].sort(); // Alphabetical order 

}

getEvents(document); // Put window, document or any html element here
console.log(events_list); // List every event on element
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.