我刚刚发现 FileReader 调度事件就像它是一个 DOM 元素一样。是吗?我想知道是否可以创建一个类似于 FileReader 的对象,它在 HTML/XML 结构中没有表示,但可以调度事件?
4 回答
FileReader
有类似的方法,addEventHandler
因为它被定义为实现EventTarget
接口。EventTarget
由DOM 事件规范定义,但您无需成为 DOM 对象即可实现它。window
,XMLHttpRequest
并且FileReader
是其他实现EventTarget
.
不幸的是,没有简单的方法来搭载浏览器的事件目标的本机实现......您可以尝试通过使用一个作为prototype
属性从浏览器对象继承,但这通常是非常不可靠的。然而,用纯 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;
};
注意:上面的代码不在我的脑海中,未经测试,但可能有效。但是,它有一些限制,例如仅在对象支持 DOM Level 3属性时才支持dispatchEvent
返回值,并且不支持 DOM Level 3 (除非您依赖自己的为其公开属性的 Event 对象,否则这是不可能实现的)。也没有层次结构或捕获/冒泡的实现。Event
defaultPrevented
stopImmediatePropagation()
所以 IMO:尝试编写参与 DOM 事件模型的代码并不会获得太多收益。对于纯 JS 回调工作,我将使用您自己的侦听器列表的临时实现。
bobince 有正确的想法,但他的代码只是一个例子。对于实际经过实战测试的实现,Doob 先生在 three.js 中使用了一个。
jQuery 可以从常规对象调度事件。这是一个小提琴。
function MyClass() {
$(this).on("MyEvent", function(event) {
console.log(event);
});
$(this).trigger("MyEvent");
}
var instance = new MyClass();
我假设它是 javascript ;通常,任何可以获得对 DOM 元素的引用的对象都应该能够使用 element.dispatchEvent 函数调度事件;看 :