2012-02-20 4 views
6

다목적 ​​팩토리 이벤트 이미 터 팩토리 함수를 만들었습니다. 그것으로 객체를 이벤트 이미 터로 변환 할 수 있습니다. 누구든지 모양을 원한다면 이벤트 이미 터 팩토리 코드가 아래에 있습니다.모든 DOM 이벤트의 배열 가져 오기

내 질문은 어떻게 DOM에서 이벤트 목록을 얻을 수 있습니다. 참고 : 바인딩 된 이벤트 목록을 가져 오지 않으려 고합니다. 가능한 모든 이벤트의 목록을 원합니다. 에미 터에 "파이프"방법을 추가하고 싶습니다. 이 메소드는 DOM 객체를 취하여 가능한 모든 이벤트에 바인딩 한 다음 해당 이벤트 중 하나가 실행되면 각각이 이미 터에서 같은 이름의 이벤트를 트리거합니다.

나는 이것을 할 방법이 없다고 생각합니다. 하드 코딩 된 이벤트 이름 배열을 만들 준비가되었지만 대신 DOM에 대한 배열을 얻을 수 있다면 W3C가 더 많은 이벤트 유형을 표준화하는 경우 훨씬 더 좋을 것이며 여전히 작동합니다.

P. W3C에서 일하는 사람은 모두가 DOM을 싫어하게 만드는 종류의 쓰레기입니다. 장난감 언어처럼 자바 스크립트 처리를 중단하십시오. 그것은 장난감 언어가 아니며 장난감 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

비슷한 질문을했습니다 : [프로그래밍 방식으로 브라우저의 페이지에서 모든 이벤트를 catch 할 수 있습니까?] (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 +, 크롬, 사파리와 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으로 시작됩니다. 인스턴스를 반복하고 on으로 시작하는 모든 속성을 나열 할 수 있습니다.

예. (배열 함축을 사용하여, 파이어 폭스) 콘솔에 다음 코드를 복사하여 붙여 넣기) :

// 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] attribute 함수를 검색하기 만하면됩니까? (HTML5) 이벤트를 찾기 위해 스펙에서 'on'을 선택했다. –

+0

나는 이미 DOM 수준 0 이벤트를 통해 루핑을 시도했지만 null로 남겨지면 * 메소드가 열거되지 않기 때문에 for 루프에 표시되지 않습니다. 기존 바인딩을 포착하려하지 않습니다. 가능한 바인딩의 동적 목록을 가져 오려고합니다. –

+0

@RobertHurst 표준 (최신) 브라우저에서 모든 이벤트를 열거 할 수 있습니다. 아직 정의되지 않은 경우 정의에 따라 'null'이어야합니다. 이벤트는 ** 미리 ** 알고 있기 때문에 이벤트 목록을 작성하고 구현하는 것이 좋습니다. 이는 많은 요소의 속성을 반복하고 속성 이름을 필터링하는 것보다 훨씬 효율적입니다. –

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() 메서드에 있습니다.

관련 문제