是否可以在常规对象(而不是DOM对象)上分派事件? [英] Is it possible to dispatch events on regular objects (not DOM ones)?
问题描述
FileReader
具有诸如 addEventHandler
的方法,因为它是定义来实现 EventTarget
界面。 EventTarget
由 DOM事件 spec,但是你不需要是一个DOM对象来实现它。 窗口
, XMLHttpRequest
和 FileReader
是其他浏览器对象模型对象实现 EventTarget
。
不幸的是,没有简单的方法来搭载浏览器的本机实现事件目标...您可以尝试通过使用一个作为原型
属性的浏览器对象继承,但这一般非常不可靠。但是,编写代码并不是很容易,而是通过纯JavaScript实现所有的方法。
function CustomEventTarget(){this。 _在里面(); }
CustomEventTarget.prototype._init = function(){
this._registrations = {};
};
CustomEventTarget.prototype._getListeners = function(type,useCapture){
var captype =(useCapture?'1':'0')+ type;
if(!(this._registrations中的captype))
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 <$ c $,则它只能支持 dispatchEvent
返回值c> defaultPrevented 属性,不支持DOM Level 3 stopImmediatePropagation()
(这是不可能实现的,除非你依靠自己的Event对象公开其财产)。而且没有实现层次结构或捕获/冒泡。
所以IMO:尝试编写参与DOM事件模型的代码不会有太大的收获。对于简单的JS回调工作,我只是随着你自己的专案执行听众列表。
I just found out that FileReader dispatches events just as if it was a DOM element. Is it? I wonder if it's possible to create an object similar to FileReader, which doesn't have a representation in HTML/XML structure, but can dispatch events?
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.
这篇关于是否可以在常规对象(而不是DOM对象)上分派事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!