2012-02-20 26 views
6

Tôi đã tạo một chức năng nhà máy phát hiện sự kiện đa mục đích. Với nó, tôi có thể biến đối tượng thành sự kiện phát. Mã cho nhà máy phát sự kiện ở bên dưới nếu có ai muốn xem hoặc sử dụng nó.Lấy một mảng của tất cả các sự kiện DOM có thể

Câu hỏi của tôi là làm cách nào để có danh sách các sự kiện từ DOM. Xin lưu ý tôi không cố gắng để có được một danh sách các sự kiện bị ràng buộc. Tôi muốn có một danh sách tất cả các sự kiện có thể. Tôi muốn thêm phương thức "ống" vào bộ phát. Phương thức này sẽ lấy một đối tượng DOM và liên kết với tất cả các sự kiện có thể xảy ra, sau đó khi bất kỳ sự kiện nào kích hoạt mỗi sự kiện sẽ kích hoạt một sự kiện có cùng tên trong bộ phát.

Tôi không tưởng tượng có cách nào để thực hiện việc này. Tôi đã chuẩn bị để tạo một mảng các tên sự kiện được mã hoá cứng, nhưng nếu tôi có thể lấy mảng cho DOM thay vì sẽ tốt hơn nhiều và vẫn hoạt động nếu W3C chuẩn hóa nhiều loại sự kiện hơn.

P.S. Nếu bạn làm việc cho W3C thì đây là loại crap khiến mọi người ghét DOM. Vui lòng ngừng xử lý JavaScript như ngôn ngữ đồ chơi. Nó không phải là một ngôn ngữ đồ chơi và cần nhiều hơn đồ chơi DOM của bạn.

/** 
* 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

Tôi đã hỏi một câu hỏi tương tự: [Có thể lập trình bắt tất cả các sự kiện trên trang trong trình duyệt không?] (Http://stackoverflow.com/questions/5107232/is-it-possible-to-programmatically -catch-all-events-on-the-page-in-the-browser). –

Trả lời

5

Đây là phiên bản hoạt động trong Chrome, Safari và 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:

Và đây là phiên bản mà làm việc trong IE9 +, Chrome, Safari và 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: kết quả là một dãy tên sự kiện như ["onwebkitpointerlockerror", "onwebkitpointerlockchange", "onwebkitfullscreenerror", "onwebkitfullscreenchange", "onselectionchange", "onselectstart", "onsearch", "onreset", "onpaste", "onbeforepaste", "oncopy"] ... ect.

5

Tất cả sự kiện DOM bắt đầu bằng on. Bạn có thể lặp qua bất kỳ phiên bản Element nào và liệt kê tất cả các thuộc tính bắt đầu bằng on.

Ví dụ. Sao chép-dán đoạn mã sau vào giao diện điều khiển (Firefox, sử dụng comprehensions mảng;)):

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

phương pháp khác để có được những sự kiện là bằng cách nhìn vào the specification, mà tiết lộ:

// 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

Lưu ý.Danh sách sự kiện trước đây là ** chưa hoàn thành **. Ví dụ, phần tử [''] (http://dev.w3.org/html5/spec/Overview.html#the-body-element) cũng định nghĩa một tập hợp các sự kiện. Chỉ cần tìm kiếm thuộc tính '[TreatNonCallableAsNull]? on' trong spec để tìm tất cả các sự kiện (HTML5). –

+0

Tôi đã cố gắng lặp qua các sự kiện DOM mức 0 đã và chúng không hiển thị trong vòng lặp for vì các phương thức * không thể đếm được khi được để trống. Xin lưu ý rằng tôi không cố gắng nắm bắt các ràng buộc hiện có. Tôi đang cố gắng để có được một danh sách năng động của các ràng buộc có thể. –

+0

@RobertHurst Trong các trình duyệt phù hợp (hiện đại), tất cả các sự kiện đều có thể đếm được. Khi chúng chưa được định nghĩa, chúng phải là 'null', theo định nghĩa. Vì các sự kiện được biết trước **, tôi khuyên bạn nên tạo danh sách các sự kiện và triển khai nó. Đó là hiệu quả hơn nhiều so với looping thông qua các thuộc tính của nhiều yếu tố, và lọc các tên tài sản. –

0

tôi đã đọc thông số kỹ thuật và tôi đã xác nhận rằng điều này hiện không thể thực hiện được. Cảm ơn W3C vì đã không cung cấp cho chúng tôi môi trường cơ bản nhất!

Tôi đã xoay sở để giải quyết vấn đề mà không phải hy sinh bất cứ điều gì. Như tôi đã nói trước khi ống mang bất kỳ sự kiện nào từ bộ phát khác (chẳng hạn như nút DOM) vào bộ phát hiện tại. Tuy nhiên tôi không cần phải làm bất cứ điều gì cho đến khi ai đó cố gắng lắng nghe một sự kiện. Nội bộ những gì tôi làm là liên kết với các phát ra đường ống khi mọi người liên kết với bộ phát hiện tại.

Tôi đã released the library nếu bạn tò mò muốn xem những gì tôi đã làm. Mã cho đường ống nằm trong phương pháp pipe() và phương pháp on().

Các vấn đề liên quan