FileReader
has methods like addEventHandler
because it is defined to implement the EventTarget interface. EventTarget
is defined by the DOM Events spec but you don't need to be a DOM object to implement it. window
, XMLHttpRequest
and FileReader
are other Browser Object Model objects that implement EventTarget
.
Unfortunately there's no easy way to piggyback on the browser's native implementation of event targets... you could try inheriting from a browser object by using one as a prototype
property, but that's very unreliable in general. However it is not too difficult to write code to implement all the methods yourself in plain JavaScript:
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;
};
Caution: the above code is off the top of my head and untested, but may work. However it has limitations like only supporting the dispatchEvent
return value if the Event
object supports the DOM Level 3 defaultPrevented
property, and no support for DOM Level 3 stopImmediatePropagation()
(which is impossible to implement unless you rely on your own Event object that exposes a property for it). Also there's no implementation of hierarchy or capture/bubbling.
So IMO: you don't gain much by trying to write code that participates in the DOM Events model. For plain-JS callback work I'd just go with your own ad hoc implementation of listener-lists.