2012-01-28 2 views
68

tôi đã xem xét những câu hỏi này:Hãy nghe sự kiện gắn liền đến nút sử dụng addEventListener

tuy nhiên không ai trong số họ trả lời như thế nào để có được một danh sách của người nghe sự kiện được gắn vào nút sử dụng addEventListener, mà không sửa đổi nguyên mẫu addEventListener trước khi sự kiện lắng nghe ers được tạo ra.

VisualEvent không hiển thị tất cả trình xử lý sự kiện (iphone cụ thể) và tôi muốn thực hiện việc này (phần nào) theo chương trình.

+0

trùng lặp có thể xảy ra của [Làm thế nào để tìm nghe sự kiện trên DOM nút khi gỡ lỗi hoặc từ mã JS?] (http://stackoverflow.com/questions/446892/how-to-find-event-listeners-on-a-dom-node-when-debugging-or-from-the -js-code) – Nickolay

+0

"hơi lập trình" và thực tế là [câu trả lời được chấp nhận] (http://stackoverflow.com/a/15666321/1026) cho câu hỏi này là một tính năng của devtools làm cho bản sao này trùng lặp với câu hỏi được liệt kê. Đối với những người tìm kiếm giải pháp JS, [câu trả lời là "không có một"] (http://stackoverflow.com/a/10030771/1026) – Nickolay

Trả lời

95

Chrome DevTools, Safari Inspector và hỗ trợ Firebug getEventListeners(node).

getEventListeners(document)

+0

Tính năng này có hoạt động cho các sự kiện 'orientationchange' không? – JohnK

+2

Tôi muốn lưu ý rằng phương thức getEventListeners không hỗ trợ phiên bản Firefox 35. – MURATSPLAT

+0

Nó có thể không hoạt động trên Firefox, nhưng sau đó một lần nữa devs phát triển trên nhiều trình duyệt/Điều này chắc chắn HELPS nếu một trong những nhu cầu để sửa đổi một trang web hiện có ... A LOT! – JasonXA

47

Bạn không thể.

Cách duy nhất để có danh sách tất cả người nghe sự kiện được gắn với nút là chặn cuộc gọi của trình nghe tập tin đính kèm.

DOM4 addEventListener

Says

Nối một event listener vào danh sách liên quan đến người nghe sự kiện với kiểu thiết lập để gõ, nghe thiết lập để người nghe, và chụp thiết lập để nắm bắt, trừ khi có đã là một sự kiện người nghe trong danh sách đó có cùng loại, người nghe và bản ghi.

Có nghĩa là người nghe sự kiện sẽ được thêm vào "danh sách người nghe sự kiện". Đó là tất cả. Không có khái niệm về danh sách này nên cũng như cách bạn nên truy cập danh sách này.

+7

Bất kỳ cơ hội nào cung cấp một số lý do hoặc lý do tại sao nó phải hoạt động đường? Rõ ràng trình duyệt biết tất cả những người nghe là gì. – Fuser97381

+2

@ user973810: Bạn muốn anh ấy biện minh cho điều này như thế nào? API DOM không cung cấp cách nào để làm điều đó và không có cách nào không chuẩn để thực hiện nó trong các trình duyệt hiện tại. Về lý do này, tôi không thực sự biết. Có vẻ như một điều hợp lý để muốn làm. –

+0

Tôi đã nhìn thấy một vài chủ đề nằm xung quanh về việc thêm một API cho DOM cho việc này. – Raynos

1

Bạn có thể có được tất cả các sự kiện jQuery sử dụng $ ._ dữ liệu ($ ('[chọn]') [0], 'sự kiện'); thay đổi [chọn] thành những gì bạn cần.

Có một plugin thu thập tất cả các sự kiện được đính kèm bởi jQuery được gọi là eventsReport.

Ngoài ra tôi cũng viết plugin của riêng mình để thực hiện việc này với định dạng tốt hơn.

Nhưng dù sao có vẻ như chúng tôi không thể thu thập sự kiện được thêm bằng phương pháp addEventListener. Có thể chúng ta có thể bọc cuộc gọi addEventListener để lưu trữ các sự kiện được thêm sau cuộc gọi bọc của chúng tôi.

Dường như cách tốt nhất để xem các sự kiện được thêm vào phần tử có công cụ dev.

Nhưng bạn sẽ không thấy các sự kiện được ủy quyền ở đó. Vì vậy, ở đó chúng ta cần jQuery eventsReport.

CẬP NHẬT: NGAY BÂY GIỜ Chúng tôi CÓ THỂ xem các sự kiện được thêm bằng phương pháp addEventListener XEM TRẢ LỜI TRẢ LỜI ĐẾN CÂU HỎI NÀY.

+0

Đây là giao diện riêng tư và không dùng nữa và nó có thể biến mất sớm nên không dựa vào điều đó. – mgol

+1

Vâng, nhưng thời gian tôi trả lời, không có khả năng như vậy trong các công cụ Dev. Vì vậy, không có gì để lựa chọn. – Rantiev

+0

Không được dùng nữa @Rantiev, bạn có thể xóa câu trả lời đó không? –

15

Kể từ khi không có cách nào tự nhiên để làm điều này, đây là giải pháp ít xâm nhập tôi tìm thấy (không thêm bất kỳ phương pháp nguyên mẫu 'cũ'):

var ListenerTracker=new function(){ 
    var is_active=false; 
    // listener tracking datas 
    var _elements_ =[]; 
    var _listeners_ =[]; 
    this.init=function(){ 
     if(!is_active){//avoid duplicate call 
      intercep_events_listeners(); 
     } 
     is_active=true; 
    }; 
    // register individual element an returns its corresponding listeners 
    var register_element=function(element){ 
     if(_elements_.indexOf(element)==-1){ 
      // NB : split by useCapture to make listener easier to find when removing 
      var elt_listeners=[{/*useCapture=false*/},{/*useCapture=true*/}]; 
      _elements_.push(element); 
      _listeners_.push(elt_listeners); 
     } 
     return _listeners_[_elements_.indexOf(element)]; 
    }; 
    var intercep_events_listeners = function(){ 
     // backup overrided methods 
     var _super_={ 
      "addEventListener"  : HTMLElement.prototype.addEventListener, 
      "removeEventListener" : HTMLElement.prototype.removeEventListener 
     }; 

     Element.prototype["addEventListener"]=function(type, listener, useCapture){ 
      var listeners=register_element(this); 
      // add event before to avoid registering if an error is thrown 
      _super_["addEventListener"].apply(this,arguments); 
      // adapt to 'elt_listeners' index 
      useCapture=useCapture?1:0; 

      if(!listeners[useCapture][type])listeners[useCapture][type]=[]; 
      listeners[useCapture][type].push(listener); 
     }; 
     Element.prototype["removeEventListener"]=function(type, listener, useCapture){ 
      var listeners=register_element(this); 
      // add event before to avoid registering if an error is thrown 
      _super_["removeEventListener"].apply(this,arguments); 
      // adapt to 'elt_listeners' index 
      useCapture=useCapture?1:0; 
      if(!listeners[useCapture][type])return; 
      var lid = listeners[useCapture][type].indexOf(listener); 
      if(lid>-1)listeners[useCapture][type].splice(lid,1); 
     }; 
     Element.prototype["getEventListeners"]=function(type){ 
      var listeners=register_element(this); 
      // convert to listener datas list 
      var result=[]; 
      for(var useCapture=0,list;list=listeners[useCapture];useCapture++){ 
       if(typeof(type)=="string"){// filtered by type 
        if(list[type]){ 
         for(var id in list[type]){ 
          result.push({"type":type,"listener":list[type][id],"useCapture":!!useCapture}); 
         } 
        } 
       }else{// all 
        for(var _type in list){ 
         for(var id in list[_type]){ 
          result.push({"type":_type,"listener":list[_type][id],"useCapture":!!useCapture}); 
         } 
        } 
       } 
      } 
      return result; 
     }; 
    }; 
}(); 
ListenerTracker.init(); 
+1

Tôi thích giải pháp này. Điều này xứng đáng nhiều upvotes hơn. – Ju66ernaut

+0

Bạn cũng nên làm cho nó chặn trình nghe sự kiện cửa sổ. Ngoài ra, điều này hoạt động tuyệt vời! –