2011-07-09 12 views

Trả lời

12

FileReader có phương pháp như addEventHandler vì nó là defined để thực hiện các giao diện EventTarget. EventTarget được xác định bởi thông số DOM Events nhưng bạn không cần phải là đối tượng DOM để triển khai. window, XMLHttpRequestFileReader là các đối tượng Mô hình đối tượng trình duyệt khác triển khai EventTarget. Không may là không có cách nào dễ dàng để thực hiện các mục tiêu sự kiện của trình duyệt ... bạn có thể thử kế thừa từ đối tượng trình duyệt bằng cách sử dụng một thuộc tính prototype, nhưng điều đó không đáng tin cậy nói chung. Tuy nhiên, không quá khó để viết mã để tự mình triển khai tất cả các phương thức trong JavaScript đơn giản:

function CustomEventTarget() { this._init(); } 

CustomEventTarget.prototype._init= function() { 
    this._registrations= {}; 
}; 
CustomEventTarget.prototype._getListeners= function(type, useCapture) { 
    var captype= (useCapture? '1' : '0')+type; 
    if (!(captype in this._registrations)) 
     this._registrations[captype]= []; 
    return this._registrations[captype]; 
}; 

CustomEventTarget.prototype.addEventListener= function(type, listener, useCapture) { 
    var listeners= this._getListeners(type, useCapture); 
    var ix= listeners.indexOf(listener); 
    if (ix===-1) 
     listeners.push(listener); 
}; 

CustomEventTarget.prototype.removeEventListener= function(type, listener, useCapture) { 
    var listeners= this._getListeners(type, useCapture); 
    var ix= listeners.indexOf(listener); 
    if (ix!==-1) 
     listeners.splice(ix, 1); 
}; 

CustomEventTarget.prototype.dispatchEvent= function(evt) { 
    var listeners= this._getListeners(evt.type, false).slice(); 
    for (var i= 0; i<listeners.length; i++) 
     listeners[i].call(this, evt); 
    return !evt.defaultPrevented; 
}; 

Thận trọng: mã trên nằm ngoài đầu và chưa được kiểm tra, nhưng có thể hoạt động. Tuy nhiên, nó có những hạn chế như chỉ hỗ trợ giá trị trả về dispatchEvent nếu đối tượng Event hỗ trợ thuộc tính DOM Cấp 3 defaultPrevented và không hỗ trợ DOM Cấp 3 stopImmediatePropagation() (không thể triển khai trừ khi bạn dựa vào đối tượng Sự kiện của riêng mình để hiển thị thuộc tính cho nó). Ngoài ra không có triển khai thực hiện phân cấp hoặc chụp/bong bóng.

Vì vậy, IMO: bạn không đạt được nhiều bằng cách cố gắng viết mã tham gia vào mô hình Sự kiện DOM. Đối với công việc gọi lại plain-JS, tôi chỉ cần thực hiện việc tạo danh sách listener của riêng bạn.

+0

Tôi có mô hình sự kiện của riêng mình - một hàm liên kết các trình xử lý với một "loại sự kiện", lưu trữ chúng trong một băm và một hàm kích hoạt "sự kiện" trên các đối tượng kế thừa mô hình này (và một số phương thức tiện ích khác). Bạn có nói rằng mô hình sự kiện mặc định không có bất kỳ lợi ích có giá trị nào đối với tôi không? – jayarjo

+1

Vâng, những lợi ích là khá nhỏ tôi muốn nói - bạn có thể không thực sự được 100% tương thích với các triển khai khác của 'Event' do không thể đọc một cách đáng tin cậy liệu' preventDefault'/'stopPropagation' /' stopImmediatePropagation' có được gọi. Vì vậy, lợi ích duy nhất là sự quen thuộc của giao diện Sự kiện DOM ... nhưng nó được cho là một giao diện khá phức tạp. – bobince

+1

Tôi đã tình cờ gặp vấn đề này: http://www.w3.org/TR/DOM-Level-3-Events/#interface-CustomEvent, trong đó W3C đề xuất nó để tạo các loại sự kiện cụ thể cho ứng dụng. Theo như tôi thấy chưa được hỗ trợ rộng rãi, nhưng có vẻ như đó là nơi mà toàn bộ điều đang hướng tới. – jayarjo

0

Tôi cho rằng đó là javascript; thông thường bất kỳ đối tượng nào có thể lấy tham chiếu đến phần tử DOM sẽ có thể gửi một sự kiện bằng hàm element.dispatchEvent; xem:

https://developer.mozilla.org/en/DOM/document.createEvent

https://developer.mozilla.org/en/DOM/element.dispatchEvent

+0

Có, đến đây từ các trang này. Tôi có nghĩa là FileReader dường như không liên quan đến bất kỳ phần tử DOM nào hoặc có tham chiếu đến nó. Nhưng đồng thời nó có một phương thức dispatchEvent trong chính nó và có thể gửi các sự kiện (các sự kiện DOM mà tôi đoán). Một chút bối rối phải không? Tôi tự hỏi nếu có một cách để tạo ra một đối tượng với các thuộc tính tương tự. – jayarjo

+0

Vâng, tôi không có bất kỳ sự thực thi nào của FileReader xung quanh tay, vì vậy nó chỉ là đầu cơ, nhưng nếu phần tử DOM được giữ bên trong như một phương thức riêng, và dispatchEvent của FileReader chỉ chuyển tiếp cuộc gọi đến dispatchEvent của nội bộ Phần tử DOM, làm sao chúng ta biết được? – phtrivier

+0

Bạn ngụ ý gì bởi phần tử DOM nội bộ? Có một thuật ngữ thế giới thực như thế này hay bạn đang suy đoán lại? :) Tôi đoán nếu có bất kỳ yếu tố DOM nội bộ, sau đó FileReader sẽ không cần phải chuyển tiếp bất cứ điều gì. Nó có thể là chính nó. – jayarjo

3

bobince has the right idea, nhưng mã của anh ấy chỉ là một ví dụ. Để thực hiện thử nghiệm chiến đấu thực tế, Mr. Doob has one that he uses in three.js.

+2

Nếu bạn không quan tâm đến việc mô phỏng API ECMAScript, hãy xem xét [tín hiệu] (http://millermedeiros.github.com/js-signals/) và [thịt xông khói] (https://github.com/raimohanska/ bacon.js). – bsimpson

1

jQuery có thể gửi các sự kiện từ các đối tượng thông thường. Here's a fiddle.

function MyClass() { 
    $(this).on("MyEvent", function(event) { 
     console.log(event); 
    }); 

    $(this).trigger("MyEvent"); 
} 

var instance = new MyClass(); 
Các vấn đề liên quan