Làm cách nào để tìm trình lắng nghe sự kiện trên nút DOM khi gỡ lỗi hoặc từ mã JavaScript?


841

Tôi có một trang trong đó một số trình lắng nghe sự kiện được gắn vào hộp nhập và chọn hộp. Có cách nào để tìm ra trình lắng nghe sự kiện nào đang quan sát một nút DOM cụ thể và cho sự kiện nào không?

Các sự kiện được đính kèm bằng cách sử dụng:

  1. Nguyên mẫu Event.observe ;
  2. DOM addEventListener;
  3. Là thuộc tính yếu tố element.onclick.

3
Làm thế nào là các sự kiện gắn liền ở nơi đầu tiên? Bạn có đang sử dụng một thư viện (ví dụ Prototype, jQuery, v.v.) không?
Lưỡi liềm tươi

Điều quan trọng cần lưu ý là nhiều chức năng gọi lại có thể được đính kèm cho cùng một loại sự kiện thông qua element.addEventListener(type, callback, [bubble]), trong khi element.onclick = functionsẽ ghi đè lên mỗi khi bạn chỉ định.
Braden hay nhất

Câu trả lời:


507

Nếu bạn chỉ cần kiểm tra những gì đang xảy ra trên một trang, bạn có thể thử bookmarklet Visual Event .

Cập nhật : Visual Event 2 có sẵn.


1
Hoàn hảo! EventBugPlugin Beats Fireorms .
Robin Maben

22
Điều này thêm một phần tử vào trang, nhiều trong số đó là hình ảnh. Tính hữu dụng của nó bị giảm đi rất nhiều trên một trang có nhiều trình xử lý sự kiện (của tôi có 17k và Visual Event mất khoảng 3 phút để tải).
Tony R

15
Tôi tin rằng tiện ích mở rộng Chrome @ssharma đã đề cập là tiện ích có sẵn tại đây
kmote

1
Sự kiện Visial không hoạt động nếu trang đề cập đến thư viện js của bên thứ ba. Nó gây ra lỗi: XMLHttpRequest không thể tải A.com/js/jquery-ui-1.10.3.custom.js?_=1384831682813 . Origin B.com không được phép bởi Access-Control-Allow-Origin.
hiway

5
Công cụ dành cho nhà phát triển nội bộ của Chrome và FF (F12) có trình xem sự kiện tích hợp! Chrome: trên tab "Thành phần", chọn và thành phần và xem bên phải có: Kiểu, Tính toán, Trình lắng nghe Sự kiện
oriadam

365

Nó phụ thuộc vào cách các sự kiện được đính kèm. Để minh họa giả định chúng ta có trình xử lý nhấp chuột sau:

var handler = function() { alert('clicked!') };

Chúng tôi sẽ gắn nó vào phần tử của chúng tôi bằng các phương pháp khác nhau, một số cho phép kiểm tra và một số thì không.

Phương pháp A) xử lý sự kiện đơn

element.onclick = handler;
// inspect
alert(element.onclick); // alerts "function() { alert('clicked!') }"

Phương pháp B) nhiều trình xử lý sự kiện

if(element.addEventListener) { // DOM standard
    element.addEventListener('click', handler, false)
} else if(element.attachEvent) { // IE
    element.attachEvent('onclick', handler)
}
// cannot inspect element to find handlers

Phương pháp C): jQuery

$(element).click(handler);
  • 1.3.x

    // inspect
    var clickEvents = $(element).data("events").click;
    jQuery.each(clickEvents, function(key, value) {
        alert(value) // alerts "function() { alert('clicked!') }"
    })
    
  • 1.4.x (lưu trữ trình xử lý bên trong một đối tượng)

    // inspect
    var clickEvents = $(element).data("events").click;
    jQuery.each(clickEvents, function(key, handlerObj) {
        alert(handlerObj.handler) // alerts "function() { alert('clicked!') }"
        // also available: handlerObj.type, handlerObj.namespace
    })
    

(Xem jQuery.fn.datajQuery.data)

Phương pháp D): Nguyên mẫu (lộn xộn)

$(element).observe('click', handler);
  • 1.5.x

    // inspect
    Event.observers.each(function(item) {
        if(item[0] == element) {
            alert(item[2]) // alerts "function() { alert('clicked!') }"
        }
    })
    
  • 1.6 đến 1.6.0.3, bao gồm (rất khó ở đây)

    // inspect. "_eventId" is for < 1.6.0.3 while 
    // "_prototypeEventID" was introduced in 1.6.0.3
    var clickEvents = Event.cache[element._eventId || (element._prototypeEventID || [])[0]].click;
    clickEvents.each(function(wrapper){
        alert(wrapper.handler) // alerts "function() { alert('clicked!') }"
    })
    
  • 1.6.1 (tốt hơn một chút)

    // inspect
    var clickEvents = element.getStorage().get('prototype_event_registry').get('click');
    clickEvents.each(function(wrapper){
        alert(wrapper.handler) // alerts "function() { alert('clicked!') }"
    })
    

3
Thx cho cập nhật này. Thật không may khi bạn phải lặp lại từng loại xử lý.
Keith Bentrup

4
Trên "Phương pháp B" (addEventListener) đây là câu trả lời về trạng thái của các phương tiện liệt kê cho trình xử lý đã đăng ký với API Sự kiện DOM thuần túy: stackoverflow.com/questions/7810534/,
Nickolay

@ John: cảm ơn vì nhận xét. Bạn có một ví dụ về "JavaScript thực" để tìm nạp người nghe được thêm trước đó qua addEventListener?
Lưỡi liềm tươi

6
@Jan, điều này dường như không hoạt động cho jQuery 1.7.2, có cách tiếp cận nào khác cho phiên bản đó không?
tomdemuyt

14
@tomdemuyt Trong jQuery, các sự kiện hiện được lưu trữ trong một mảng dữ liệu nội bộ thay vì có thể truy cập thông qua .data('events')như trước đây. Để truy cập dữ liệu sự kiện nội bộ, sử dụng $._data(elem, 'events'). Lưu ý rằng hàm này được đánh dấu "chỉ sử dụng nội bộ" trong nguồn jQuery, vì vậy không có hứa hẹn rằng nó sẽ luôn hoạt động trong tương lai, nhưng tôi tin rằng nó đã hoạt động kể từ jQuery 1.7 và vẫn hoạt động.
Matt Browne

351

Hỗ trợ Chrome, Firefox, Vivaldi và Safari getEventListeners(domElement)trong bảng điều khiển Công cụ dành cho nhà phát triển của họ.

Đối với hầu hết các mục đích gỡ lỗi, điều này có thể được sử dụng.

Dưới đây là một tài liệu tham khảo rất tốt để sử dụng nó: https://developers.google.com/web/tools/chrome-devtools/console/utilities#geteventlistener


1
+1. Mã dành riêng cho trình duyệt không phải là vấn đề đối với tôi, vì tôi đang cố gắng để có một trang mà tôi không kiểm soát để hoạt động chính xác.
Grault

9
hay, nhưng chỉ hoạt động trong dòng lệnh của bảng điều khiển Chrome :(
gillyspy 20/12/13

5
@Raghav ah cảm ơn, cách sử dụng KHÔNG: như tôi nghĩ đầu tiên :)getEventListeners(object) obj getEventListeners()
jave.web 15/03/2015

11
Bạn có thể đã tiết kiệm cho tôi 3 giờ nếu bạn đã giải thích cách lấy mã nguồn của người tổ chức sự kiện. Đó là "tài liệu tham khảo" không giải thích bất cứ điều gì. Trong trường hợp bất cứ ai khác bị mất đây là : var list = getEventListeners(document.getElementById("YOURIDHERE")); console.log(list["focus"][0]["listener"].toString()). Thay đổi "tiêu điểm" thành sự kiện bạn muốn kiểm tra và số lượng nếu có nhiều người nghe trên cùng một sự kiện.
doABarrelRoll721

46
MIPO: getEventListeners($0)sẽ nhận được các trình lắng nghe sự kiện cho yếu tố bạn đã tập trung vào trong các công cụ phát triển Chrome. Tôi sử dụng tất cả các thời gian. Yêu không phải sử dụng các hàm querySelector hoặc get__By_
mã hóa

91

WebKit Inspector trong trình duyệt Chrome hoặc Safari hiện thực hiện điều này. Nó sẽ hiển thị các trình lắng nghe sự kiện cho một phần tử DOM khi bạn chọn nó trong ngăn Element.


9
Tôi không chắc nó hiển thị tất cả các trình xử lý sự kiện; chỉ là trình xử lý sự kiện HTML duy nhất.
huyz

3
Tôi nên đề cập đến plugin EventBug cho Fireorms để hoàn thiện < softwareishard.com/blog/carget/eventorms >
Nickolay

Điều này chỉ làm cho ngày của tôi, một số mã nguyên mẫu cũ có nhiều chức năng liên kết với cùng một sự kiện trên cùng một yếu tố và tôi đang cố gắng theo dõi chúng. Cảm ơn Ishan rất nhiều.
siliconrockstar

70

Có thể liệt kê tất cả các trình lắng nghe sự kiện trong JavaScript: Không khó lắm; bạn chỉ cần hack prototypephương thức của các phần tử HTML ( trước khi thêm người nghe).

function reportIn(e){
    var a = this.lastListenerInfo[this.lastListenerInfo.length-1];
    console.log(a)
}


HTMLAnchorElement.prototype.realAddEventListener = HTMLAnchorElement.prototype.addEventListener;

HTMLAnchorElement.prototype.addEventListener = function(a,b,c){
    this.realAddEventListener(a,reportIn,c); 
    this.realAddEventListener(a,b,c); 
    if(!this.lastListenerInfo){  this.lastListenerInfo = new Array()};
    this.lastListenerInfo.push({a : a, b : b , c : c});
};

Bây giờ mọi phần tử neo ( a) sẽ có một thuộc lastListenerInfotính chứa tất cả các trình nghe của nó. Và nó thậm chí hoạt động để loại bỏ người nghe với chức năng ẩn danh.


4
Phương pháp này sẽ không hoạt động nếu bạn đang viết tập lệnh người dùng hoặc tập lệnh nội dung. Không chỉ có khả năng được sandbox trong những ngày này mà làm thế nào bạn có thể đảm bảo thứ tự thực hiện?
huyz

phương pháp này hoạt động với chrome / 19 và FF / 12. thứ tự thực hiện có thể được đảm bảo nếu bạn móc cái này trước các tập lệnh khác
Tzury Bar Yochay

8
Bạn không thể sửa đổi Node.prototypethay thế? Đó là nơi HTMLAnchorElementkế thừa .addEventListenertừ mọi cách. '
Esailija

3
Bạn đang giả sử rằng tác nhân người dùng thực hiện kế thừa nguyên mẫu cho các đối tượng máy chủ DOM và cho phép bạn sửa đổi chúng. Cả hai đều là những ý tưởng hay: không sửa đổi các đối tượng bạn không sở hữu .
RobG

1
Điều này khá vô dụng - nó cho thấy những gì eventListener đã được thêm vào, có thể tốt trong một số trường hợp, nhưng không phải là những gì đã bị xóa. Vì vậy, nếu bạn đang cố gắng gỡ lỗi những gì đã bị xóa và những gì không, đơn giản là không có cách nào.
gotofritz

52

Sử dụng getEventListener trong Google Chrome :

getEventListeners(document.getElementByID('btnlogin'));
getEventListeners($('#btnlogin'));

1
Uncaught ReferenceError: getEventListener không được xác định
Bryan Grace

3
getEventListener chỉ hoạt động trong bảng điều khiển devtools của Chrome. Và đây là một bản sao của câu trả lời phức tạp hơn này: stackoverflow.com/a/16544813/1026
Nickolay

41

(Viết lại câu trả lời từ câu hỏi này vì nó có liên quan ở đây.)

Khi gỡ lỗi, nếu bạn chỉ muốn xem các sự kiện, tôi khuyên bạn nên ...

  1. Sự kiện trực quan
  2. Phần Yếu tố trong Công cụ dành cho nhà phát triển của Chrome: chọn một yếu tố và tìm "Trình lắng nghe sự kiện" ở góc dưới bên phải (tương tự trong Firefox)

Nếu bạn muốn sử dụng các sự kiện trong mã của mình và bạn đang sử dụng jQuery trước phiên bản 1.8 , bạn có thể sử dụng:

$(selector).data("events")

để có được các sự kiện. Kể từ phiên bản 1.8, việc sử dụng .data ("sự kiện") đã bị ngưng (xem vé lỗi này ). Bạn có thể dùng:

$._data(element, "events")

Một ví dụ khác: Viết tất cả các sự kiện nhấp chuột vào một liên kết nhất định đến bảng điều khiển:

var $myLink = $('a.myClass');
console.log($._data($myLink[0], "events").click);

(xem http://jsfiddle.net/HmsQC/ để biết ví dụ hoạt động)

Thật không may, sử dụng dữ liệu $ ._ không được khuyến nghị ngoại trừ việc gỡ lỗi vì đây là cấu trúc jQuery nội bộ và có thể thay đổi trong các bản phát hành trong tương lai. Thật không may, tôi biết không có phương tiện dễ dàng khác để truy cập các sự kiện.


1
$._data(elem, "events")dường như không hoạt động với jQuery 1.10, ít nhất là đối với các sự kiện đã đăng ký sử dụng $(elem).on('event', ...). Có ai biết làm thế nào để gỡ lỗi những?
Marius Gedminas

4
Tôi không tích cực, nhưng tôi nghĩ thông số đầu tiên $._datacó thể cần phải là một phần tử chứ không phải là một đối tượng jQuery. Vì vậy, tôi cần sửa ví dụ của mình ở trênconsole.log($._data($myLink[0], "events").click);
Luke

29

1: Prototype.observesử dụng Element.addEventListener (xem mã nguồn )

2: Bạn có thể ghi đè Element.addEventListenerđể ghi nhớ các trình nghe đã thêm (thuộc tính tiện dụng EventListenerListđã bị xóa khỏi đề xuất thông số DOM3). Chạy mã này trước khi bất kỳ sự kiện nào được đính kèm:

(function() {
  Element.prototype._addEventListener = Element.prototype.addEventListener;
  Element.prototype.addEventListener = function(a,b,c) {
    this._addEventListener(a,b,c);
    if(!this.eventListenerList) this.eventListenerList = {};
    if(!this.eventListenerList[a]) this.eventListenerList[a] = [];
    this.eventListenerList[a].push(b);
  };
})();

Đọc tất cả các sự kiện bằng cách:

var clicks = someElement.eventListenerList.click;
if(clicks) clicks.forEach(function(f) {
  alert("I listen to this function: "+f.toString());
});

Và đừng quên ghi đè Element.removeEventListenerđể xóa sự kiện khỏi tùy chỉnh Element.eventListenerList.

3: Element.onclicktài sản cần được chăm sóc đặc biệt ở đây:

if(someElement.onclick)
  alert("I also listen tho this: "+someElement.onclick.toString());

4: đừng quên Element.onclickthuộc tính nội dung: đây là hai điều khác nhau:

someElement.onclick = someHandler; // IDL attribute
someElement.setAttribute("onclick","otherHandler(event)"); // content attribute

Vì vậy, bạn cũng cần phải xử lý nó:

var click = someElement.getAttribute("onclick");
if(click) alert("I even listen to this: "+click);

Bookmarklet Visual Event (được đề cập trong câu trả lời phổ biến nhất) chỉ đánh cắp bộ đệm của trình xử lý thư viện tùy chỉnh:

Hóa ra, không có phương thức tiêu chuẩn nào được cung cấp bởi giao diện DOM được đề xuất của W3C để tìm hiểu xem trình lắng nghe sự kiện nào được gắn vào một phần tử cụ thể. Mặc dù điều này có vẻ là một sự giám sát, có một đề xuất bao gồm một thuộc tính được gọi là eventListenerList cho đặc tả DOM cấp 3, nhưng không may bị xóa trong các bản nháp sau này. Vì vậy, chúng tôi buộc phải xem xét các thư viện Javascript riêng lẻ, thường duy trì bộ đệm của các sự kiện đính kèm (để sau đó chúng có thể được xóa và thực hiện các tóm tắt hữu ích khác).

Như vậy, để Visual Event hiển thị các sự kiện, nó phải có khả năng phân tích thông tin sự kiện ra khỏi thư viện Javascript.

Việc ghi đè phần tử có thể gây nghi ngờ (nghĩa là vì có một số tính năng cụ thể của DOM như bộ sưu tập trực tiếp, không thể được mã hóa trong JS), nhưng nó cung cấp cho hỗ trợ eventListenerList một cách tự nhiên và nó hoạt động trong Chrome, Firefox và Opera (không hoạt động trong IE7 ).


23

Bạn có thể gói các phương thức DOM gốc để quản lý trình lắng nghe sự kiện bằng cách đặt phương thức này lên đầu <head>:

<script>
    (function(w){
        var originalAdd = w.addEventListener;
        w.addEventListener = function(){
            // add your own stuff here to debug
            return originalAdd.apply(this, arguments);
        };

        var originalRemove = w.removeEventListener;
        w.removeEventListener = function(){
            // add your own stuff here to debug
            return originalRemove.apply(this, arguments);
        };
    })(window);
</script>

H / T @ les2


Vui lòng sửa cho tôi nếu tôi sai, nhưng không phải chỉ dành cho người nghe sự kiện gắn liền với cửa sổ?
Maciej Krawchot

@MaciejKrawchot yep và những bong bóng đó
Jon z

18

Các công cụ phát triển Firefox hiện làm điều này. Các sự kiện được hiển thị bằng cách nhấp vào nút "ev" ở bên phải màn hình của mỗi thành phần, bao gồm các sự kiện jQueryDOM .

Ảnh chụp màn hình nút nghe sự kiện của công cụ phát triển Firefox trong tab thanh tra


Tôi đã xem xét một trong các yếu tố dom trên trang mà bookmarklet Visual Event 2 đang hiển thị một sự kiện có dây và tôi đã thấy nút "ev" nhỏ ở bên phải, như bạn hiển thị.
Eric

Trình nghe sự kiện của Firefox có thể tìm ra các sự kiện được ủy quyền của jQuery trong khi Chrome cần plugin để làm điều đó.
Nick Tsai

12

Nếu bạn có Fireorms , bạn có thể sử dụng console.dir(object or array)để in một cây đẹp trong nhật ký giao diện điều khiển của bất kỳ vô hướng, mảng hoặc đối tượng JavaScript nào.

Thử:

console.dir(clickEvents);

hoặc là

console.dir(window);

9
Tính năng mới trong firebird
Javier Constanzo

10

Giải pháp hoàn toàn hoạt động dựa trên câu trả lời của Jan Turon - hoạt động như getEventListeners()từ bảng điều khiển:

(Có một lỗi nhỏ với các bản sao. Dù sao nó cũng không bị hỏng nhiều.)

(function() {
  Element.prototype._addEventListener = Element.prototype.addEventListener;
  Element.prototype.addEventListener = function(a,b,c) {
    if(c==undefined)
      c=false;
    this._addEventListener(a,b,c);
    if(!this.eventListenerList)
      this.eventListenerList = {};
    if(!this.eventListenerList[a])
      this.eventListenerList[a] = [];
    //this.removeEventListener(a,b,c); // TODO - handle duplicates..
    this.eventListenerList[a].push({listener:b,useCapture:c});
  };

  Element.prototype.getEventListeners = function(a){
    if(!this.eventListenerList)
      this.eventListenerList = {};
    if(a==undefined)
      return this.eventListenerList;
    return this.eventListenerList[a];
  };
  Element.prototype.clearEventListeners = function(a){
    if(!this.eventListenerList)
      this.eventListenerList = {};
    if(a==undefined){
      for(var x in (this.getEventListeners())) this.clearEventListeners(x);
        return;
    }
    var el = this.getEventListeners(a);
    if(el==undefined)
      return;
    for(var i = el.length - 1; i >= 0; --i) {
      var ev = el[i];
      this.removeEventListener(a, ev.listener, ev.useCapture);
    }
  };

  Element.prototype._removeEventListener = Element.prototype.removeEventListener;
  Element.prototype.removeEventListener = function(a,b,c) {
    if(c==undefined)
      c=false;
    this._removeEventListener(a,b,c);
      if(!this.eventListenerList)
        this.eventListenerList = {};
      if(!this.eventListenerList[a])
        this.eventListenerList[a] = [];

      // Find the event in the list
      for(var i=0;i<this.eventListenerList[a].length;i++){
          if(this.eventListenerList[a][i].listener==b, this.eventListenerList[a][i].useCapture==c){ // Hmm..
              this.eventListenerList[a].splice(i, 1);
              break;
          }
      }
    if(this.eventListenerList[a].length==0)
      delete this.eventListenerList[a];
  };
})();

Sử dụng:

someElement.getEventListeners([name]) - danh sách trả về của người nghe sự kiện, nếu tên được đặt mảng trả về của người nghe cho sự kiện đó

someElement.clearEventListeners([name]) - xóa tất cả các trình lắng nghe sự kiện, nếu tên được đặt chỉ xóa các trình lắng nghe cho sự kiện đó


3
Đây là một câu trả lời hay, nhưng tôi không thể làm cho nó hoạt động trên các yếu tố bodydocument.
David Bradshaw

Giải pháp thực sự tốt đẹp!
Dzhakhar Ukhaev

@Peter Mortensen, tại sao bạn đổi tên Jan? :)
n00b

1
@David Bradshaw: vì cơ thể, tài liệu và cửa sổ có nguyên mẫu riêng và không phải nguyên mẫu Element ...
Stefan Steiger

1
@ n00b: Có lỗi. Đó là lý do tại sao hmmm. Bạn sử dụng toán tử dấu phẩy trong câu lệnh if cho người nghe và useCaption ... Toán tử dấu phẩy đánh giá từng toán hạng của nó (từ trái sang phải) và trả về giá trị của toán hạng cuối cùng. Vì vậy, bạn loại bỏ eventListener đầu tiên phù hợp trong useCapture, không phân biệt loại sự kiện ... Đó phải là && thay vì dấu phẩy.
Stefan Steiger

8

Opera 12 (không phải công cụ Chrome Webkit mới nhất dựa trên) Dragonfly đã có điều này trong một thời gian và rõ ràng được hiển thị trong cấu trúc DOM. Theo tôi đó là một trình gỡ lỗi ưu việt và là lý do duy nhất còn lại tại sao tôi vẫn sử dụng phiên bản dựa trên Opera 12 (không có phiên bản v13, v14 và v15 Webkit vẫn thiếu Dragonfly)

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


4

Nguyên mẫu 1.7.1 cách

function get_element_registry(element) {
    var cache = Event.cache;
    if(element === window) return 0;
    if(typeof element._prototypeUID === 'undefined') {
        element._prototypeUID = Element.Storage.UID++;
    }
    var uid =  element._prototypeUID;           
    if(!cache[uid]) cache[uid] = {element: element};
    return cache[uid];
}

4

Gần đây tôi đã làm việc với các sự kiện và muốn xem / kiểm soát tất cả các sự kiện trong một trang. Xem xét các giải pháp khả thi, tôi quyết định đi theo con đường của riêng mình và tạo ra một hệ thống tùy chỉnh để theo dõi các sự kiện. Vì vậy, tôi đã làm ba điều.

Đầu tiên, tôi cần một thùng chứa cho tất cả những người nghe sự kiện trong trang: đó là EventListenersđối tượng. Nó có ba phương pháp hữu ích: add(), remove(), và get().

Tiếp theo, tôi đã tạo ra một EventListenerđối tượng để giữ thông tin cần thiết cho sự kiện này, ví dụ: target, type, callback, options, useCapture, wantsUntrusted, và thêm một phương pháp remove()để loại bỏ người nghe.

Cuối cùng, tôi đã mở rộng nguồn gốc addEventListener()removeEventListener()các phương thức để làm cho chúng hoạt động với các đối tượng tôi đã tạo ( EventListenerEventListeners).

Sử dụng:

var bodyClickEvent = document.body.addEventListener("click", function () {
    console.log("body click");
});

// bodyClickEvent.remove();

addEventListener()tạo một EventListenerđối tượng, thêm nó vào EventListenersvà trả về EventListenerđối tượng, để nó có thể được gỡ bỏ sau đó.

EventListeners.get()có thể được sử dụng để xem người nghe trong trang. Nó chấp nhận một EventTargethoặc một chuỗi (loại sự kiện).

// EventListeners.get(document.body);
// EventListeners.get("click");

Bản giới thiệu

Hãy nói rằng chúng tôi muốn biết mọi người nghe sự kiện trong trang hiện tại này. Chúng tôi có thể làm điều đó (giả sử bạn đang sử dụng tiện ích mở rộng trình quản lý tập lệnh, Tampermonkey trong trường hợp này). Kịch bản sau đây thực hiện điều này:

// ==UserScript==
// @name         New Userscript
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @include      https://stackoverflow.com/*
// @grant        none
// ==/UserScript==

(function() {
    fetch("https://raw.githubusercontent.com/akinuri/js-lib/master/EventListener.js")
        .then(function (response) {
            return response.text();
        })
        .then(function (text) {
            eval(text);
            window.EventListeners = EventListeners;
        });
})(window);

Và khi chúng tôi liệt kê tất cả những người nghe, nó nói có 299 người nghe sự kiện. Có vẻ như có một số bản sao, nhưng tôi không biết liệu chúng có thực sự trùng lặp hay không. Không phải mọi loại sự kiện đều được nhân đôi, vì vậy tất cả những "bản sao" đó có thể là một người nghe riêng lẻ.

ảnh chụp màn hình của bảng điều khiển liệt kê tất cả người nghe sự kiện trong trang này

Mã có thể được tìm thấy tại kho lưu trữ của tôi . Tôi không muốn đăng nó ở đây vì nó khá dài.


Cập nhật: Điều này dường như không hoạt động với jQuery. Khi tôi kiểm tra EventListener, tôi thấy rằng cuộc gọi lại là

function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}

Tôi tin rằng điều này thuộc về jQuery và không phải là cuộc gọi lại thực tế. jQuery lưu trữ cuộc gọi lại thực tế trong các thuộc tính của EventTarget:

$(document.body).click(function () {
    console.log("jquery click");
});

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

Để loại bỏ một người nghe sự kiện, cuộc gọi lại thực tế cần phải được chuyển đến removeEventListener()phương thức. Vì vậy, để làm cho điều này hoạt động với jQuery, nó cần sửa đổi thêm. Tôi có thể sửa nó trong tương lai.


Hoạt động tuyệt vời! Cảm ơn
mt025

3

Tôi đang cố gắng làm điều đó trong jQuery 2.1 và với $().click() -> $(element).data("events").click;phương thức "", nó không hoạt động.

Tôi nhận ra rằng chỉ các hàm $ ._ data () hoạt động trong trường hợp của tôi:

	$(document).ready(function(){

		var node = $('body');
		
        // Bind 3 events to body click
		node.click(function(e) { alert('hello');  })
			.click(function(e) { alert('bye');  })
			.click(fun_1);

        // Inspect the events of body
		var events = $._data(node[0], "events").click;
		var ev1 = events[0].handler // -> function(e) { alert('hello')
		var ev2 = events[1].handler // -> function(e) { alert('bye')
		var ev3 = events[2].handler // -> function fun_1()
        
		$('body')
			.append('<p> Event1 = ' + eval(ev1).toString() + '</p>')
			.append('<p> Event2 = ' + eval(ev2).toString() + '</p>')
			.append('<p> Event3 = ' + eval(ev3).toString() + '</p>');        
	
	});

	function fun_1() {
		var txt = 'text del missatge';	 
		alert(txt);
	}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
</body>



1

thay đổi các chức năng này sẽ cho phép bạn đăng nhập các trình nghe được thêm vào:

EventTarget.prototype.addEventListener
EventTarget.prototype.attachEvent
EventTarget.prototype.removeEventListener
EventTarget.prototype.detachEvent

đọc phần còn lại của người nghe với

console.log(someElement.onclick);
console.log(someElement.getAttribute("onclick"));
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.