是否可以在常规对象(而不是DOM对象)上分派事件? [英] Is it possible to dispatch events on regular objects (not DOM ones)?

查看:159
本文介绍了是否可以在常规对象(而不是DOM对象)上分派事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

解决方案

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆