2014-09-06 123 views
6

我希望能夠捕獲所有既被創建又被分派的事件,並在發生時觸發一些回調。捕獲所有事件(javascript)

此外,我希望能夠在事件與事件偵聽器配對的任何時候觸發回調。

問題包括:動態添加的元素,阻止傳播或冒泡的事件以及動態生成的自定義事件。我想有必要做一個dispatchEvent的原型設計,不過我不確定。這甚至有可能嗎?

+1

所以,第一個問題:爲什麼?這很棒,你想這樣做,但它也很奇怪。 – 2014-09-06 01:19:03

+1

無論你的問題是什麼,都需要這個,他們可能是一個更好的選擇。您可以輕鬆處理合成事件,也可以動態創建元素(每當元素創建時都可以檢測) – Markasoftware 2014-09-06 01:22:56

+4

這聽起來很酷。不要聽其他讓你失望的人。 – 2014-09-06 01:23:19

回答

2

一些事件基礎:

  1. 事件是「上」的DOM對象(通常的元件),其是事件目標調度。
  2. 事件可以首先傳播到捕獲階段的子元素。這個階段很少使用,因爲直到最近才被一些廣泛使用的瀏覽器所支持。
  3. 事件可以在冒泡階段傳播到父元素。這個階段是常用的。
  4. 有些事件不會傳播,它們既沒有捕獲或冒泡階段(例如焦點,模糊和提交事件)。一些瀏覽器中傳播的事件不會在其他瀏覽器中傳播。
  5. 響應事件的DOM元素具有事件處理程序。它可以設置爲偵聽特定事件並在事件到達元素時調用偵聽器函數,在捕獲,冒泡期間或元素是事件目標時。
  6. 聽衆可以取消傳播,例如,在鏈接中跨度的click事件取消傳播這樣的鏈接沒有得到的點擊

鑑於上述情況,它實際上是不可能來「捕獲所有事件」使用Events API。這將需要爲每個元素上的每個事件類型建立一個監聽器,並且不可能捕獲自定義事件,因爲您必須知道它們才能設置合適的監聽器。

我想有將需要dispatchEvent的原型或東西

dispatchEvent是事件實例的方法,它沒有指定是一個構造函數(有沒有爲它的要求有一個內部的[[Construct]]方法),因此不實際使用。瀏覽器不需要爲宿主對象實現原型繼承(儘管大部分都是這樣),並且宿主對象和方法的實現細節在很大程度上是隱藏的,所以這不是一個選項。

你可以嘗試擴展事件API,但你真的should not mess with host objects

看來你很關心動態添加的元素。有一種叫做"event delegation"的策略,在這個策略中你可以計算出需要監聽的事件,然後將監聽器設置爲儘可能靠近事件目標,就像你可以在不改變的元素上一樣(例如,如果你動態添加和刪除表格行或其他元素的容器div),以獲取您需要響應的特定事件類型。

您還可以修改DOM dispatch自定義事件以添加偵聽器或其他任何函數。

1

如果您確實想要這樣做,那麼您可以覆蓋addEventListener以跟蹤正在註冊和觸發的事件。

var myEventManager = (function() { 
    var old = EventTarget.prototype.addEventListener, 
     listeners = [], 
     events = []; 

    EventTarget.prototype.addEventListener = function(type, listener) { 

     function new_listener(listener) { 
      return function(e) { 
       events.push(e);     // remember event 
       return listener.call(this, e); // call original listener 
      }; 
     } 

     listeners.push([type, listener]);  // remember call 
     return old.call(this, type, new_listener(listener)); // call original 
    }; 

    return { 
     get_events: function() { return events; }, 
     get_listeners: function() {return listeners; } 
    }; 

}()); 

不過,也有無數的理由不這樣做,並非最不重要的事實,你會很快耗盡內存爲你記錄數千個事件,如鼠標移動。這也不會捕獲以諸如elt.onclick等方式設置的事件監聽器。當然,它也不會捕獲通過舊的IE attachEvent API設置的聽衆。最重要的是,它不會幫助你在內部生成和偵聽的事件,例如鼠標點擊複選框。 (完整的解決方案,還需要處理removeEventListener。)

您還可以覆蓋createEventdispatch以類似的方式,但同樣,這將只捕獲明確創建或JS代碼分派的事件。

如果你真的想做你想要的東西,我想你需要分叉Chrome。