是否可以在常规对象(而不是DOM对象)上调度事件?

时间:2011-07-09 13:50:08

标签: javascript events dom filereader dispatch

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

4 个答案:

答案 0 :(得分:12)

FileReader包含addEventHandler等方法,因为它是defined来实现EventTarget接口。 EventTargetDOM Events规范定义,但您不需要是DOM对象来实现它。 windowXMLHttpRequestFileReader是实施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;
};

警告:上面的代码不在我的头顶,未经测试,但可能有效。但是,如果dispatchEvent对象支持DOM Level 3 Event属性,并且不支持DOM Level 3 defaultPrevented(这是支持stopImmediatePropagation()返回值,则它有一些限制。除非你依赖自己的Event对象为它公开一个属性,否则无法实现。此外,没有层次结构或捕获/冒泡的实现。

所以IMO:通过尝试编写参与DOM Events模型的代码,你获得的收益并不高。对于普通的JS回调工作,我只是使用你自己的临时实现的监听器列表。

答案 1 :(得分:4)

bobince has the right idea,但他的代码只是一个例子。对于经过实战考验的实施,Mr. Doob has one that he uses in three.js

答案 2 :(得分:1)

jQuery可以从常规对象中分派事件。 Here's a fiddle

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

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

var instance = new MyClass();

答案 3 :(得分:0)

我认为这是javascript;通常,任何可以获取DOM元素引用的对象都应该能够使用element.dispatchEvent函数调度事件。见:

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

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