简体   繁体   English

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

[英]How do you log all events fired by an element in jQuery?

I'd like to see all the events fired by an input field as a user interacts with it.我希望看到输入字段在用户与其交互时触发的所有事件。 This includes stuff like:这包括以下内容:

  1. Clicking on it.点击它。
  2. Clicking off it.点击关闭它。
  3. Tabbing into it.进入它。
  4. Tabbing away from it.远离它。
  5. Ctrl + C and Ctrl + V on the keyboard.键盘上的 Ctrl + CCtrl + V。
  6. Right click -> Paste.右键单击 -> 粘贴。
  7. Right click -> Cut.右键单击 -> 剪切。
  8. Right click -> Copy.右键单击-> 复制。
  9. Dragging and dropping text from another application.从另一个应用程序拖放文本。
  10. Modifying it with Javascript.用 Javascript 修改它。
  11. Modifying it with a debug tool, like Firebug.使用调试工具(如 Firebug)修改它。

I'd like to display it using console.log .我想使用console.log显示它。 Is this possible in Javascript/jQuery, and if so, how do I do it?这在 Javascript/jQuery 中是否可行,如果可以,我该怎么做?

I have no idea why no-one uses this... (maybe because it's only a webkit thing)我不知道为什么没有人使用它......(也许是因为它只是一个 webkit 的东西)

Open console:打开控制台:

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
$(element).on("click mousedown mouseup focus blur keydown change",function(e){
     console.log(e);
});

That will get you a lot (but not all) of the information on if an event is fired... other than manually coding it like this, I can't think of any other way to do that.这会给你很多(但不是全部)关于是否触发事件的信息......除了像这样手动编码之外,我想不出任何其他方法来做到这一点。

There is a nice generic way using the .data('events') collection:使用 .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);
});

This logs every event that has been already bound to the element by jQuery the moment this specific event gets fired.当这个特定事件被触发时,它会记录每个已经被 jQuery 绑定到元素的事件。 This code was pretty damn helpful for me many times.这段代码多次对我很有帮助。

Btw: If you want to see every possible event being fired on an object use firebug: just right click on the DOM element in html tab and check "Log Events".顺便说一句:如果您想查看对象上触发的每个可能的事件,请使用 firebug:只需右键单击 html 选项卡中的 DOM 元素并选中“日志事件”。 Every event then gets logged to the console (this is sometimes a bit annoying because it logs every mouse movement...).然后每个事件都会被记录到控制台(这有时有点烦人,因为它会记录每个鼠标移动......)。

$('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);
}); 

I know the answer has already been accepted to this, but I think there might be a slightly more reliable way where you don't necessarily have to know the name of the event beforehand.我知道答案已经被接受,但我认为可能有一种更可靠的方法,您不必事先知道事件的名称。 This only works for native events though as far as I know, not custom ones that have been created by plugins.据我所知,这仅适用于本机事件,而不适用于由插件创建的自定义事件。 I opted to omit the use of jQuery to simplify things a little.我选择省略 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);
    });
  });

I hope this helps anyone who reads this.我希望这可以帮助任何阅读本文的人。

EDIT编辑

So I saw another question here that was similar, so another suggestion would be to do the following:所以我在这里看到了另一个类似的问题,所以另一个建议是执行以下操作:

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

Old thread, I know.旧线程,我知道。 I needed also something to monitor events and wrote this very handy (excellent) solution.我还需要一些东西来监视事件并编写了这个非常方便(优秀)的解决方案。 You can monitor all events with this hook (in windows programming this is called a hook).您可以使用此钩子监视所有事件(在 Windows 编程中,这称为钩子)。 This hook does not affects the operation of your software/program.这个钩子不会影响你的软件/程序的运行。

In the console log you can see something like this:控制台日志中,您可以看到如下内容:

控制台日志

Explanation of what you see:对所见的解释:

In the console log you will see all events you select (see below "how to use" ) and shows the object-type, classname(s), id, <:name of function>, <:eventname>.在控制台日志中,您将看到您选择的所有事件(请参阅下面的“如何使用” )并显示对象类型、类名、id、<:函数名称>、<:事件名称>。 The formatting of the objects is css-like.对象的格式类似于 css。

When you click a button or whatever binded event, you will see it in the console log.当您单击按钮或任何绑定事件时,您将在控制台日志中看到它。

The code I wrote:我写的代码:

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;
    };
   }
}

Examples how to use it:如何使用它的示例:

Monitor all events:监控所有事件:

setJQueryEventHandlersDebugHooks();

Monitor all triggers only:仅监控所有触发器:

setJQueryEventHandlersDebugHooks(true,false,false);

Monitor all ON events only:仅监控所有 ON 事件:

setJQueryEventHandlersDebugHooks(false,true,false);

Monitor all OFF unbinds only:仅监控所有 OFF 解除绑定:

setJQueryEventHandlersDebugHooks(false,false,true);

Remarks/Notice:备注/通知:

  • Use this for debugging only, turn it off when using in product final version仅用于调试,在产品最终版本中使用时将其关闭
  • If you want to see all events, you have to call this function directly after jQuery is loaded如果要查看所有事件,必须在 jQuery 加载后直接调用该函数
  • If you want to see only less events, you can call the function on the time you need it如果您只想查看较少的事件,可以在需要时调用该函数
  • If you want to auto execute it, place ( )();如果你想自动执行它,放置 ( )(); around function围绕功能

Hope it helps!希望能帮助到你! ;-) ;-)

https://github.com/robertleeplummerjr/wiretap.js 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
  }
});

Just add this to the page and no other worries, will handle rest for you:只需将其添加到页面中,别担心,将为您处理休息:

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

You can also use console.log('Input event:' + e.type) to make it easier.您还可以使用 console.log('Input event:' + e.type) 使其更容易。

STEP 1: Check the events for an HTML element on the developer console :步骤 1:在developer console上检查HTML elementevents

在此处输入图片说明

STEP 2: Listen to the events we want to capture: STEP 2:监听我们想要捕获的events

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

Good Luck...祝你好运...

I recently found and modified this snippet from an existing SO post that I have not been able to find again but I've found it very useful我最近从现有的 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
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'))

This uses a bit of ES6 for prettiness, but can easily be translated for legacy browsers as well.为了美观,这使用了一些 ES6,但也可以很容易地为旧版浏览器进行翻译。 In the function attached to the event listeners, it's currently just logging out what kind of event occurred but this is where you could print out additional information, or using a switch case on the e.type , you could only print information on specific events在附加到事件侦听器的函数中,它目前只是记录发生了什么样的事件,但在这里您可以打印出附加信息,或者在e.type上使用 switch case,您只能打印有关特定事件的信息

Here is a non-jquery way to monitor events in the console with your code and without the use of monitorEvents() because that only works in Chrome Developer Console.这是一种使用您的代码在控制台中监视事件的非 jquery 方法,无需使用 monitorEvents(),因为它仅适用于 Chrome 开发者控制台。 You can also choose to not monitor certain events by editing the no_watch array.您还可以通过编辑 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

How to listen for all events on an Element (Vanilla JS)如何侦听Element上的所有事件(Vanilla JS)


For all native events , we can retrieve a list of supported events by iterating over the target.onevent properties and installing our listener for all of them.对于所有原生事件,我们可以通过遍历target.onevent属性并为所有事件安装我们的侦听器来检索支持的事件列表。

for (const key in target) {
    if(/^on/.test(key)) {
        const eventType = key.substr(2);
        target.addEventListener(eventType, listener);
    }
}

The only other way that events are emitted which I know of is via EventTarget.dispatchEvent , which every Node and thefore every Element inherits.我所知道的唯一发出事件的其他方式是通过EventTarget.dispatchEvent ,每个Node和之前的每个Element继承它。
To listen for all these manually triggered events , we can proxy the dispatchEvent method globally and install our listener just-in-time for the event whose name we just saw ✨ ^^为了监听所有这些手动触发的事件,我们可以全局代理dispatchEvent方法,并为我们刚刚看到的事件名称安装我们的监听器 ✨ ^^

const dispatchEvent_original = EventTarget.prototype.dispatchEvent;
EventTarget.prototype.dispatchEvent = function (event) {
    if (!alreadyListenedEventTypes.has(event.type)) {
        target.addEventListener(event.type, listener, ...otherArguments);
        alreadyListenedEventTypes.add(event.type);
    }
    dispatchEvent_original.apply(this, arguments);
};

🔥 function snippet 🔥 🔥函数片段🔥

function addEventListenerAll(target, listener, ...otherArguments) {

    // install listeners for all natively triggered events
    for (const key in target) {
        if (/^on/.test(key)) {
            const eventType = key.substr(2);
            target.addEventListener(eventType, listener, ...otherArguments);
        }
    }

    // dynamically install listeners for all manually triggered events, just-in-time before they're dispatched ;D
    const dispatchEvent_original = EventTarget.prototype.dispatchEvent;
    function dispatchEvent(event) {
        target.addEventListener(event.type, listener, ...otherArguments);  // multiple identical listeners are automatically discarded
        dispatchEvent_original.apply(this, arguments);
    }
    EventTarget.prototype.dispatchEvent = dispatchEvent;
    if (EventTarget.prototype.dispatchEvent !== dispatchEvent) throw new Error(`Browser is smarter than you think!`);

}


// usage example
const input = document.querySelector('input');
addEventListenerAll(input, (evt) => {
    console.log(evt.type);
});
input.focus();
input.click();
input.dispatchEvent(new Event('omg!', { bubbles: true }));


// usage example with `useCapture`
// (also receives `bubbles: false` events, but in reverse order)
addEventListenerAll(
    input,
    (evt) => { console.log(evt.type); },
    true
);
document.body.dispatchEvent(new Event('omfggg!', { bubbles: false }));
$(document).on("click mousedown mouseup focus blur keydown change",function(e){
    console.log(e);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM