10

我刚刚发现 FileReader 调度事件就像它是一个 DOM 元素一样。是吗?我想知道是否可以创建一个类似于 FileReader 的对象,它在 HTML/XML 结构中没有表示,但可以调度事件?

4

4 回答 4

13

FileReader有类似的方法,addEventHandler因为它被定义为实现EventTarget接口。EventTargetDOM 事件规范定义,但您无需成为 DOM 对象即可实现它。windowXMLHttpRequest并且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 对象,否则这是不可能实现的)。也没有层次结构或捕获/冒泡的实现。EventdefaultPreventedstopImmediatePropagation()

所以 IMO:尝试编写参与 DOM 事件模型的代码并不会获得太多收益。对于纯 JS 回调工作,我将使用您自己的侦听器列表的临时实现。

于 2011-07-09T15:56:44.140 回答
4

bobince 有正确的想法,但他的代码只是一个例子。对于实际经过实战测试的实现,Doob 先生在 three.js 中使用了一个

于 2013-03-28T04:50:49.860 回答
1

jQuery 可以从常规对象调度事件。这是一个小提琴

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

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

var instance = new MyClass();
于 2016-10-26T01:14:47.240 回答
0

我假设它是 javascript ;通常,任何可以获得对 DOM 元素的引用的对象都应该能够使用 element.dispatchEvent 函数调度事件;看 :

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

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

于 2011-07-09T13:57:23.243 回答