用JavaScript编写自定义事件调度程序?

用JavaScript编写自定义事件调度程序?,javascript,events,dom-events,Javascript,Events,Dom Events,如何向JavaScript中我自己类的对象添加事件侦听器并从中分派事件? 在ActionScript3中,我可以简单地从Sprite/DisplayObject继承并使用那里可用的方法。像这样: // ActionScript-3: // I can add event listeners to all kinds of events var mySprite: Sprite = new MySprite(); mySprite.addEventListener("my_menu_it

如何向JavaScript中我自己类的对象添加事件侦听器并从中分派事件?

在ActionScript3中,我可以简单地从Sprite/DisplayObject继承并使用那里可用的方法。像这样:

// ActionScript-3:
// I can add event listeners to all kinds of events
var mySprite: Sprite = new MySprite();
mySprite.addEventListener("my_menu_item_click", onMenuItemClick);

// later I can dispatch an event from one of my objects
mySprite.dispatchEvent(new Event("my_menu_item_click", ...));
我希望有同样的JavaScript。到现在为止,我知道了
window.addEventListener(…)
document.addEventListener(…)
。到目前为止,我有自己的JavaScript Sprite类,我想用它来调度我自己的事件

// JavaScipt:
function Sprite()
{
    this.x = 0;
    this.y = 0;
    // ...
}
既然这两种语言在事件上看起来如此“相似”,我想我需要从某个类继承吗?或者我必须使用一些全局变量,比如窗口和/或文档


我在这里使用HTML5。我只有1个画布和一堆精灵,它们被绘制到画布上并对用户输入做出反应。我希望一个精灵A订阅另一个精灵B的事件。但不订阅第三个精灵C。

您可以在JS中对事件和CustomEvent对象执行大致相同的操作:

var event = new Event('build');

// Listen for the event.
elem.addEventListener('build', function (e) { ... }, false);

// Dispatch the event.
elem.dispatchEvent(event);

来源:MDN()

我试图将这些方法添加到我的Sprite类中,但成功了。
当然还没有完成,但至少它能工作。
这就是我要找的

function Sprite()
{
    // ...
    this.eventListeners = new Array();

    this.addEventListener = function(type, eventHandler)
    {
        var listener = new Object();
        listener.type = type;
        listener.eventHandler = eventHandler;
        this.eventListeners.push(listener);
    }

    this.dispatchEvent = function(event)
    {
        for (var i = 0; i < this.eventListeners.length; i++)
            if (event.type == this.eventListeners[i].type)
                this.eventListeners[i].eventHandler(event);
    }
}
函数Sprite()
{
// ...
this.eventListeners=新数组();
this.addEventListener=函数(类型,eventHandler)
{
var listener=新对象();
listener.type=type;
listener.eventHandler=eventHandler;
this.eventListeners.push(listener);
}
this.dispatchEvent=函数(事件)
{
for(var i=0;i
这是一种“功能性”方法,我不喜欢在javascript中使用“new”和“This”。我喜欢普通的、对等的或扩展的对象

//应从其他文件导入某些帮助器函数
const partial=fn=>(…pargs)=>(…args)=>fn.apply(null,[…pargs,…args]);
const partinarke=fn=>(…pargs)=>(…args)=>fn.apply(null,[…args,…pargs.reverse());
//模块从这里开始
const on=(侦听器,类型,侦听器,一次)=>{
如果(!侦听器[类型]){
侦听器[类型]=[];
}
if(侦听器[type].indexOf(侦听器)<0){
listener.one=一次;
侦听器[类型]。推送(侦听器);
}
};
const once=on(开)(真);
const off=(侦听器、类型、侦听器)=>{
const listenerType=侦听器[type];
if(listenerType&&listenerType.length){
const index=listenerType.indexOf(侦听器);
如果(索引!=-1){
listenerType.拼接(索引1);
}
}
if((listenerType&!listenerType.length)| |!listener){
删除侦听器[类型];
}
};
常量emit=(侦听器,类型,…数据)=>{
if(侦听器[类型]){
侦听器[type].forEach(侦听器=>{
apply(null,数据);
if(listener.one){
关闭(侦听器、类型、侦听器);
}
});
}
};
//您可以使用“export default()=>{}”使其成为可导入的模块
常量eventEmitter=()=>{
常量侦听器={};
返回{
on:partial(on)(听众),
一次:部分(一次)(侦听器),
关闭:部分(关闭)(侦听器),
发射:部分(发射)(侦听器),
};
};
const myObj=Object.create(Object.assign({},eventEmitter());
myObj.on('hello',name=>console.log(name));
设置超时(()=>{
emit('hello','Csaba')

},2000)
您可以自己制作,这是一款通用且非常简单的产品。实际上我自己也用过:D

这就是您将获得的功能

  • addEventListener()
  • removeEventlistener()
  • dispatchEvent()
这个函数将向对象添加所需的方法,同时返回一个可以分派事件的函数

// Snippet  =========================================
function createEventDispatcher(o) {
  var L = o.__listeners = {};
  o.addEventListener = function(n, fn) { L[n] = L[n] || []; L[n].push(fn); };
  o.removeEventListener = function(n, fn) { var a = L[n]; for (var i = 0; i < a.length; i++) if (a[i] === fn) a.splice(i, 1);};
  return function() { var a = Array.prototype.slice.call(arguments); var l = L[a.shift()]; if (l)  for (var i = 0; i < l.length; i++) l[i].apply(l[i], a)};
}

如果要从对象中删除所有侦听器,只需执行以下操作

myApp.__listeners = {};

相关:好的。但这里的埃伦是什么?Html元素?我只有一张画布和一堆精灵。elem是任何js对象。你不需要自己实现addEventListener和dispatchEvent,它们将由js引擎自己添加。我承认我不是JavaScript专家,但我不知道这会发生什么。除此之外,此测试还会抛出一个错误:
try{new Object().addEventListener(“click”,onClick);}catch(error){alert(error.message);}
My bad,它集成在所有DOM对象中,而不是所有js对象中AS3,EventDispatcher实现独立于DisplayObject类的事件调度。DisplayObjects在其继承链中都有EventDispatcher,但由于EventDispatcher是一个单独的类,您也可以直接从中继承,因此您可以从非DisplayObjects的对象中分派事件。在JavaScript中,EventDispatcher的等价物是什么?或者功能只是被错误地混入DOM对象中,而没有像AS3这样干净、独立的实现?JavaScript远远落后于AS3,令人恶心。真是太棒了!谢谢,帮了大忙。
myApp.__listeners = {};