Làm cách nào để ghi nhật ký tất cả các sự kiện được kích hoạt bởi một phần tử trong jQuery?


93

Tôi muốn xem tất cả các sự kiện được kích hoạt bởi một trường đầu vào khi người dùng tương tác với nó. Điều này bao gồm những thứ như:

  1. Nhấp vào nó.
  2. Nhấp vào nó.
  3. Đánh dấu vào nó.
  4. Tránh xa nó.
  5. Ctrl+ CCtrl+ Vtrên bàn phím.
  6. Nhấp chuột phải -> Dán.
  7. Nhấp chuột phải -> Cắt.
  8. Nhấp chuột phải -> Sao chép.
  9. Kéo và thả văn bản từ một ứng dụng khác.
  10. Sửa đổi nó bằng Javascript.
  11. Sửa đổi nó bằng một công cụ gỡ lỗi, như Firebug.

Tôi muốn hiển thị nó bằng cách sử dụng console.log. Điều này có thể xảy ra trong Javascript / jQuery không và nếu có, tôi phải làm như thế nào?


Câu hỏi của bạn quả là thú vị, nhưng bạn đã nói trong một nhận xét rằng "Điều tôi đang tìm kiếm nhiều hơn là danh sách tất cả các sự kiện bị sa thải để tôi biết những sự kiện nào có sẵn để tôi tham gia" - tại sao bạn không chỉ hỏi điều đó? Doco của MSDN khá tốt cho việc này: msdn.microsoft.com/en-us/library/ms533051(v=VS.85).aspx - không phải tất cả các sự kiện được liệt kê đều được hỗ trợ trong tất cả các trình duyệt, nhưng nếu bạn kiểm tra doco cho event 'on_xyz_' nó sẽ cho bạn biết "Sự kiện này được xác định trong HTML 4.0.", hoặc "Không có tiêu chuẩn công cộng nào áp dụng cho sự kiện này", hoặc bất cứ điều gì.
nnnnnn

Câu trả lời:


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

Điều đó sẽ cung cấp cho bạn rất nhiều (nhưng không phải tất cả) thông tin về việc nếu một sự kiện được kích hoạt ... ngoài việc mã hóa nó theo cách thủ công như thế này, tôi không thể nghĩ ra cách nào khác để làm điều đó.


Kỳ lạ là bạn và Shawn đều viết sai chính tả functionvà theo cùng một cách :).
Daniel T.

1
Có vẻ như phương thức này sẽ liên kết tất cả các sự kiện gốc. Tôi đoán không có cách nào để hiển thị các sự kiện tùy chỉnh, ví dụ: nếu một plugin kích hoạt một số sự kiện tùy chỉnh?
Daniel T.

1
Tôi chấp nhận đây là câu trả lời, nhưng câu trả lời thực sự cho câu hỏi của tôi là "có và không". Những gì tôi đang tìm kiếm nhiều hơn là một danh sách tất cả các sự kiện bị sa thải để tôi biết những sự kiện nào có sẵn để tôi tham gia. Trong trường hợp này, tôi có thể biết khi nào các sự kiện được kích hoạt, nhưng tôi phải biết trước tên của nó.
Daniel T.

3
@Joseph: liên quan đến nhận xét trước đó của bạn "tiêu điểm không phải là một sự kiện gốc" - ừm ... vâng, nó đã có từ rất lâu trước jQuery (và trước cả Chrome và FF, vì vấn đề đó). Ngoài ra, bạn có thể muốn thêm blurvào danh sách các sự kiện của mình.
nnnnnn

3
monitorEvents (tài liệu) là câu trả lời thực
neaumusic

203

Tôi không biết tại sao không ai sử dụng cái này ... (có thể vì nó chỉ là một thứ trên webkit)

Mở bảng điều khiển:

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
Nó không bao gồm các sự kiện tùy chỉnh nhưng nó thực sự giúp hiểu được ngăn xếp sự kiện.
sidonaldson

Đây là câu trả lời chính xác. Bạn không muốn sử dụng console.log trong mã sản xuất, đó là tốt để sử dụng giao diện điều khiển để gỡ lỗi các sự kiện
neaumusic

1
Googleing monitorEventskhông đưa ra thông tin có liên quan về vấn đề này, cũng có thể, tôi rất nghi ngờ điều này là rất phi tiêu chuẩn
vsync

3
@vsync hãy thử "monitorEvents" trong dấu ngoặc kép. Nó là một phần của đối tượng console nhưng phụ thuộc vào trình duyệt. Nó chỉ là một công cụ gỡ lỗi vì nó phụ thuộc vào giao diện điều khiển ... do đó, là tiêu chuẩn là không thích hợp
sidonaldson

2
Lưu ý rằng bạn cũng có thể sử dụng một cái gì đó như monitorEvents($0, 'mouse');để ghi lại tất cả các sự kiện của phần tử được kiểm tra (Nhấp chuột phải> "Kiểm tra"). ( briangrinstead.com/blog/chrome-developer-tools-monitorevents )
rinogo

32

Có một cách chung hay là sử dụng bộ sưu tập .data ('sự kiện'):

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

Điều này ghi lại mọi sự kiện đã được jQuery liên kết với phần tử tại thời điểm sự kiện cụ thể này được kích hoạt. Mã này rất hữu ích cho tôi nhiều lần.

Btw: Nếu bạn muốn xem mọi sự kiện có thể xảy ra trên một đối tượng, hãy sử dụng firebug: chỉ cần nhấp chuột phải vào phần tử DOM trong tab html và kiểm tra "Log Events". Mọi sự kiện sau đó đều được ghi vào bảng điều khiển (điều này đôi khi hơi khó chịu vì nó ghi lại mọi chuyển động của chuột ...).


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
Hầu hết các câu trả lời hoàn chỉnh
leymannx

12

Tôi biết câu trả lời đã được chấp nhận cho điều này, nhưng tôi nghĩ có thể có một cách đáng tin cậy hơn một chút mà bạn không nhất thiết phải biết trước tên của sự kiện. Điều này chỉ hoạt động cho các sự kiện gốc mặc dù theo như tôi biết, không phải các sự kiện tùy chỉnh đã được tạo bởi plugin. Tôi đã chọn bỏ qua việc sử dụng jQuery để đơn giản hóa mọi thứ một chút.

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

Tôi hy vọng điều này sẽ giúp bất cứ ai đọc điều này.

BIÊN TẬP

Vì vậy, tôi đã thấy một câu hỏi khác ở đây tương tự, vì vậy một đề xuất khác sẽ là làm như sau:

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

Đây là giải pháp thanh lịch nhất của nhóm. Tôi cho rằng sẽ không thể phát hiện ra các sự kiện tùy chỉnh vì những sự kiện đó có thể được phát ra thông qua sendEvent (). Tuy nhiên, điều này bao gồm mọi thứ khác trong một bit mã nhỏ gọn, không phụ thuộc.
Roberto

10

Chủ đề cũ, tôi biết. Tôi cũng cần một cái gì đó để theo dõi các sự kiện và đã viết giải pháp rất tiện dụng (tuyệt vời) này. Bạn có thể giám sát tất cả các sự kiện với hook này (trong lập trình windows, hook này được gọi là hook). Móc này không ảnh hưởng đến hoạt động của phần mềm / chương trình của bạn.

Trong nhật ký bảng điều khiển, bạn có thể thấy một cái gì đó như sau:

nhật ký giao diện điều khiển

Giải thích về những gì bạn thấy:

Trong nhật ký bảng điều khiển, bạn sẽ thấy tất cả các sự kiện bạn chọn (xem phần "cách sử dụng" bên dưới ) và hiển thị kiểu đối tượng, (các) tên lớp, id, <: tên hàm>, <: tên sự kiện>. Định dạng của các đối tượng giống như css.

Khi bạn nhấp vào một nút hoặc bất kỳ sự kiện liên kết nào, bạn sẽ thấy nó trong nhật ký bảng điều khiển.

Mã tôi đã viết:

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

Ví dụ về cách sử dụng nó:

Giám sát tất cả các sự kiện:

setJQueryEventHandlersDebugHooks();

Chỉ giám sát tất cả các trình kích hoạt:

setJQueryEventHandlersDebugHooks(true,false,false);

Chỉ giám sát tất cả các sự kiện BẬT:

setJQueryEventHandlersDebugHooks(false,true,false);

Chỉ giám sát tất cả các mối liên kết TẮT:

setJQueryEventHandlersDebugHooks(false,false,true);

Nhận xét / Thông báo:

  • Chỉ sử dụng tính năng này để gỡ lỗi, hãy tắt tính năng này khi sử dụng trong phiên bản cuối cùng của sản phẩm
  • Nếu bạn muốn xem tất cả các sự kiện, bạn phải gọi hàm này trực tiếp sau khi jQuery được tải
  • Nếu bạn chỉ muốn xem ít sự kiện hơn, bạn có thể gọi hàm vào thời điểm bạn cần
  • Nếu bạn muốn tự động thực thi nó, hãy đặt () (); chức năng xung quanh

Hy vọng nó giúp! ;-)


Xin chào @AmirFo, cảm ơn bạn đã cố gắng. Vì bạn không cung cấp bất kỳ ví dụ nào về những gì bạn đã làm, nên không thể xem vấn đề là do mã của bạn hay của tôi. Bởi vì có những người khác đã sử dụng ví dụ này một cách thành công, có thể bạn đã làm sai điều gì đó. Bạn đã kiểm tra mã của mình để tìm lỗi chưa?
Codebeat

Không có lỗi. Tôi đã kích hoạt một số sự kiện, nhưng không có nhật ký nào xuất hiện trong bảng điều khiển! Tôi đang sử dụng phiên bản chrome mới nhất trong ubuntu, linux.
Amir Fo

@AmirFo: Bạn cũng đã thử nó trong Firefox? Phiên bản jQuery?
Codebeat

@AmirFo: Bạn đã kích hoạt các sự kiện như thế nào? Bạn có liên kết bất kỳ sự kiện nào với các phần tử DOM trước khi kích hoạt nó không?
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
Bạn có thể cung cấp thêm một số thông tin về cách hoạt động và những gì nó hoạt động chính xác? Làm cách nào để gắn nó vào một phần tử?
Josiah

Tập lệnh này sửa đổi HTMLElement.prototype.addEventListenervà có lẽ không nên được sử dụng trong quá trình sản xuất, nhưng nó đã giúp ích rất nhiều cho tôi cho mục đích gỡ lỗi.
Günter Zöchbauer

1
Điều này không hoạt động với 1 phần tử, nó hoạt động cho TẤT CẢ CHÚNG. Nó chạm vào trình xử lý sự kiện của cửa sổ và lắng nghe mọi thứ xảy ra. Nó hoạt động với trình xử lý sự kiện gốc và jQuery.
Robert Plummer

2

Chỉ cần thêm điều này vào trang và không phải lo lắng gì khác, phần còn lại sẽ giải quyết cho bạn:

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

Bạn cũng có thể sử dụng console.log ('Sự kiện đầu vào:' + e.type) để dễ dàng hơn.


3
Kỳ lạ là bạn và Joseph đều viết sai chính tả function, và theo cùng một cách :).
Daniel T.

lol, hey ... anh ấy đã viết ra một số và tôi đã cải thiện. ;)
Shawn Khameneh

1
Sẽ không để tôi bình luận câu trả lời khác, bạn có thể sử dụng .data ("sự kiện") để lấy danh sách các sự kiện.
Shawn Khameneh

Làm thế nào nó hoạt động? Tôi đã thử $('input').data('events')và nó trả về không xác định.
Daniel T.

Điều đó sẽ trả về các sự kiện liên kết hiện tại, bao gồm các sự kiện tùy chỉnh. Nếu không có sự kiện nào bị ràng buộc, nó sẽ trả về không xác định.
Shawn Khameneh

1

BƯỚC 1: Kiểm tra eventsmột HTML elementtrên developer console:

nhập mô tả hình ảnh ở đây

BƯỚC 2: Lắng nghe eventschúng tôi muốn nắm bắt:

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

Chúc may mắn...


1

Gần đây tôi đã tìm thấy và sửa đổi đoạn mã này từ một bài đăng SO hiện có mà tôi không thể tìm lại được nhưng tôi thấy nó rất hữu ích

// 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'))

Điều này sử dụng một chút ES6 để làm đẹp, nhưng cũng có thể dễ dàng được dịch cho các trình duyệt cũ. Trong chức năng được đính kèm với trình nghe sự kiện, hiện chỉ cần đăng xuất loại sự kiện đã xảy ra nhưng đây là nơi bạn có thể in ra thông tin bổ sung hoặc sử dụng hộp chuyển đổi trên e.type, bạn chỉ có thể in thông tin về các sự kiện cụ thể


0

Đây là một cách không cần truy vấn để theo dõi các sự kiện trong bảng điều khiển bằng mã của bạn và không sử dụng monitorEvents () vì cách đó chỉ hoạt động trong Bảng điều khiển dành cho nhà phát triển Chrome. Bạn cũng có thể chọn không theo dõi các sự kiện nhất định bằng cách chỉnh sửa mảng 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.