【发布时间】:2011-10-01 21:13:32
【问题描述】:
我刚刚发现 FileReader 调度事件就像它是一个 DOM 元素一样。是吗?我想知道是否可以创建一个类似于 FileReader 的对象,它在 HTML/XML 结构中没有表示,但可以调度事件?
【问题讨论】:
标签: javascript events dom filereader dispatch
我刚刚发现 FileReader 调度事件就像它是一个 DOM 元素一样。是吗?我想知道是否可以创建一个类似于 FileReader 的对象,它在 HTML/XML 结构中没有表示,但可以调度事件?
【问题讨论】:
标签: javascript events dom filereader dispatch
FileReader 有类似addEventHandler 的方法,因为它是defined 来实现EventTarget 接口。 EventTarget 由 DOM Events 规范定义,但您无需成为 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;
};
注意:上面的代码在我脑海中浮现,未经测试,但可能有效。但是,它有一些限制,例如如果 Event 对象支持 DOM Level 3 defaultPrevented 属性,则仅支持 dispatchEvent 返回值,并且不支持 DOM Level 3 stopImmediatePropagation()(除非您依赖于您的为它公开属性的自己的事件对象)。也没有层次结构或捕获/冒泡的实现。
因此,IMO:尝试编写参与 DOM 事件模型的代码不会有太多收获。对于纯 JS 回调工作,我将使用您自己的侦听器列表的临时实现。
【讨论】:
preventDefault/@ 987654342@/stopImmediatePropagation 已被调用。所以唯一的好处是熟悉 DOM 事件接口......但可以说它是一个相当笨重的接口。
detail 属性,这在Java 等更严格的语言中很方便,但在JS 中用途有限,你可以在你的对象上放置任意属性。
bobince has the right idea,但他的代码只是一个例子。对于实际经过实战测试的实现,Mr. Doob has one that he uses in three.js。
jQuery 可以从常规对象调度事件。 Here's a fiddle.
function MyClass() {
$(this).on("MyEvent", function(event) {
console.log(event);
});
$(this).trigger("MyEvent");
}
var instance = new MyClass();
【讨论】:
我假设它是 javascript ;通常,任何可以获得对 DOM 元素的引用的对象都应该能够使用 element.dispatchEvent 函数调度事件;见:
【讨论】: