2012-02-20 8 views
6

私は多目的ファクトリーイベントエミッターファクトリー関数を作成しました。それを使ってオブジェクトをイベントエミッタにすることができます。誰かが見たり使いたい場合は、イベントエミッターファクトリーのコードは以下のとおりです。すべてのDOMイベントの配列を取得する

私の質問は、DOMからイベントのリストを取得する方法です。 私はバインドされたイベントのリストを取得しようとしていません。私は可能なすべての出来事のリストが欲しいです。エミッタに「パイプ」メソッドを追加したいと思います。このメソッドは、DOMオブジェクトを取り、すべての可能なイベントにバインドし、それらのイベントのいずれかが起動すると、それぞれがエミッタ内の同じ名前のイベントをトリガします。

これを行う方法はありません。ハードコードされたイベント名の配列を作成する準備ができていますが、代わりにDOMの配列を取得できれば、W3Cがより多くのイベントタイプを標準化していれば、それははるかに優れています。

P.S.あなたがW3Cのために働くならば、これはみんながDOMを嫌うようなものです。おもしろい言葉のようにJavaScriptをやめてください。おもちゃの言語ではなく、おもちゃのDOM以上のものが必要です。

/** 
* Creates a event emitter 
*/ 
function EventEmitter() { 
    var api, callbacks; 

    //vars 
    api = { 
     "on": on, 
     "trigger": trigger 
    }; 
    callbacks = {}; 

    //return the api 
    return api; 

    /** 
    * Binds functions to events 
    * @param event 
    * @param callback 
    */ 
    function on(event, callback) { 
     var api; 

     if(typeof event !== 'string') { throw new Error('Cannot bind to event emitter. The passed event is not a string.'); } 
     if(typeof callback !== 'function') { throw new Error('Cannot bind to event emitter. The passed callback is not a function.'); } 

     //return the api 
     api = { 
      "clear": clear 
     }; 

     //create the event namespace if it doesn't exist 
     if(!callbacks[event]) { callbacks[event] = []; } 

     //save the callback 
     callbacks[event].push(callback); 

     //return the api 
     return api; 

     function clear() { 
      var i; 
      if(callbacks[event]) { 
       i = callbacks[event].indexOf(callback); 
       callbacks[event].splice(i, 1); 

       if(callbacks[event].length < 1) { 
        delete callbacks[event]; 
       } 

       return true; 
      } 
      return false; 
     } 
    } 

    /** 
    * Triggers a given event and optionally passes its handlers all additional parameters 
    * @param event 
    */ 
    function trigger(event ) { 
     var args; 

     if(typeof event !== 'string' && !Array.isArray(event)) { throw new Error('Cannot bind to event emitter. The passed event is not a string or an array.'); } 

     //get the arguments 
     args = Array.prototype.slice.apply(arguments).splice(1); 

     //handle event arrays 
     if(Array.isArray(event)) { 

      //for each event in the event array self invoke passing the arguments array 
      event.forEach(function(event) { 

       //add the event name to the begining of the arguments array 
       args.unshift(event); 

       //trigger the event 
       trigger.apply(this, args); 

       //shift off the event name 
       args.shift(); 

      }); 

      return; 
     } 

     //if the event has callbacks then execute them 
     if(callbacks[event]) { 

      //fire the callbacks 
      callbacks[event].forEach(function(callback) { callback.apply(this, args); }); 
     } 
    } 
} 
+0

私は同様の質問をしました。[ブラウザでページ上のすべてのイベントをプログラムで捕捉することはできますか?](http://stackoverflow.com/questions/5107232/is-it-possible-to-programmatically -catch-all-events-the-the-browser-in-the-browser)を使用します。 –

答えて

5

ここは、Chrome、Safari、FFで動作するバージョンです。

Object.getOwnPropertyNames(document).concat(Object.getOwnPropertyNames(Object.getPrototypeOf(Object.getPrototypeOf(document)))).filter(function(i){return !i.indexOf('on')&&(document[i]==null||typeof document[i]=='function');}) 

UPD

そして、ここでは、IE9 +、クロム、SafariとFFで動作するバージョンです。

Object.getOwnPropertyNames(document).concat(Object.getOwnPropertyNames(Object.getPrototypeOf(Object.getPrototypeOf(document)))).concat(Object.getOwnPropertyNames(Object.getPrototypeOf(window))).filter(function(i){return !i.indexOf('on')&&(document[i]==null||typeof document[i]=='function');}).filter(function(elem, pos, self){return self.indexOf(elem) == pos;}) 

PS:結果はイベントの配列です["onwebkitpointerlockerror", "onwebkitpointerlockchange", "onwebkitfullscreenerror", "onwebkitfullscreenchange", "onselectionchange", "onselectstart", "onsearch", "onreset", "onpaste", "onbeforepaste", "oncopy"] ...電気ショック療法のような名前。

5

すべてのDOMイベントはonで始まります。任意のElementインスタンスをループし、onで始まるすべてのプロパティをリストすることができます。

例。 (配列内包を使用して、Firefoxの;)コンソールに次のコードをコピー&ペースト):

// event handler IDL attributes 
    [TreatNonCallableAsNull] attribute Function? onabort; 
    [TreatNonCallableAsNull] attribute Function? onblur; 
    [TreatNonCallableAsNull] attribute Function? oncanplay; 
    [TreatNonCallableAsNull] attribute Function? oncanplaythrough; 
    [TreatNonCallableAsNull] attribute Function? onchange; 
    [TreatNonCallableAsNull] attribute Function? onclick; 
    [TreatNonCallableAsNull] attribute Function? oncontextmenu; 
    [TreatNonCallableAsNull] attribute Function? oncuechange; 
    [TreatNonCallableAsNull] attribute Function? ondblclick; 
    [TreatNonCallableAsNull] attribute Function? ondrag; 
    [TreatNonCallableAsNull] attribute Function? ondragend; 
    [TreatNonCallableAsNull] attribute Function? ondragenter; 
    [TreatNonCallableAsNull] attribute Function? ondragleave; 
    [TreatNonCallableAsNull] attribute Function? ondragover; 
    [TreatNonCallableAsNull] attribute Function? ondragstart; 
    [TreatNonCallableAsNull] attribute Function? ondrop; 
    [TreatNonCallableAsNull] attribute Function? ondurationchange; 
    [TreatNonCallableAsNull] attribute Function? onemptied; 
    [TreatNonCallableAsNull] attribute Function? onended; 
    [TreatNonCallableAsNull] attribute Function? onerror; 
    [TreatNonCallableAsNull] attribute Function? onfocus; 
    [TreatNonCallableAsNull] attribute Function? oninput; 
    [TreatNonCallableAsNull] attribute Function? oninvalid; 
    [TreatNonCallableAsNull] attribute Function? onkeydown; 
    [TreatNonCallableAsNull] attribute Function? onkeypress; 
    [TreatNonCallableAsNull] attribute Function? onkeyup; 
    [TreatNonCallableAsNull] attribute Function? onload; 
    [TreatNonCallableAsNull] attribute Function? onloadeddata; 
    [TreatNonCallableAsNull] attribute Function? onloadedmetadata; 
    [TreatNonCallableAsNull] attribute Function? onloadstart; 
    [TreatNonCallableAsNull] attribute Function? onmousedown; 
    [TreatNonCallableAsNull] attribute Function? onmousemove; 
    [TreatNonCallableAsNull] attribute Function? onmouseout; 
    [TreatNonCallableAsNull] attribute Function? onmouseover; 
    [TreatNonCallableAsNull] attribute Function? onmouseup; 
    [TreatNonCallableAsNull] attribute Function? onmousewheel; 
    [TreatNonCallableAsNull] attribute Function? onpause; 
    [TreatNonCallableAsNull] attribute Function? onplay; 
    [TreatNonCallableAsNull] attribute Function? onplaying; 
    [TreatNonCallableAsNull] attribute Function? onprogress; 
    [TreatNonCallableAsNull] attribute Function? onratechange; 
    [TreatNonCallableAsNull] attribute Function? onreset; 
    [TreatNonCallableAsNull] attribute Function? onscroll; 
    [TreatNonCallableAsNull] attribute Function? onseeked; 
    [TreatNonCallableAsNull] attribute Function? onseeking; 
    [TreatNonCallableAsNull] attribute Function? onselect; 
    [TreatNonCallableAsNull] attribute Function? onshow; 
    [TreatNonCallableAsNull] attribute Function? onstalled; 
    [TreatNonCallableAsNull] attribute Function? onsubmit; 
    [TreatNonCallableAsNull] attribute Function? onsuspend; 
    [TreatNonCallableAsNull] attribute Function? ontimeupdate; 
    [TreatNonCallableAsNull] attribute Function? onvolumechange; 
    [TreatNonCallableAsNull] attribute Function? onwaiting; 

    // special event handler IDL attributes that only apply to Document objects 
    [TreatNonCallableAsNull,LenientThis] attribute Function? onreadystatechange; 
+0

注。以前のイベントのリストは**完全ではありません**。たとえば、[''要素](http://dev.w3.org/html5/spec/Overview.html#the-body-element)も一連のイベントを定義します。 '[TreatNonCallableAsNull]属性関数を検索するだけです。すべての(HTML5)イベントを見つけるための仕様に「on」を追加しました。 –

+0

私はすでにDOMレベル0のイベントをループしてみましたが、for *ループはfor *ループには表示されません。私は既存のバインディングをキャプチャしようとしていないことに注意してください。私は可能なバインディングの動的リストを取得しようとしています。 –

+0

@RobertHurst準拠(現代)のブラウザでは、すべてのイベントが列挙可能です。まだ定義されていないときは、定義ごとに「ヌル」でなければなりません。イベントは**事前に**知っているので、イベントのリストを作成して実装することをお勧めします。これは、多くの要素のプロパティをループし、プロパティ名をフィルタリングするよりもはるかに効率的です。 –

0

私は」:

[i for(i in document)].filter(function(i){return i.substring(0,2)=='on'&&(document[i]==null||typeof document[i]=='function');}) 

別の方法を、イベントを取得するには明らかにされ、the specificationを見ることです仕様を読んで、これが現在可能ではないことを確認しました。最も基本的な環境を提供してくれていないW3Cに感謝します!

私は何も犠牲にすることなく問題を回避することができました。先に述べたように、パイプは別のエミッタ(DOMノードなど)からのイベントを現在のエミッタに伝達します。しかし、誰かがイベントを聞くまで私は何もする必要はありません。内部的に私がやっているのは、現在のエミッタにバインドされているパイプエミッタにバインドすることです。

私はreleased the libraryあなたの好奇心が私が何をしたかを知っています。パイプのコードはpipe()メソッドとon()メソッドです。

関連する問題