首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在JavaScript中编写自定义事件分派器?

在JavaScript中编写自定义事件分派器?
EN

Stack Overflow用户
提问于 2015-06-29 16:07:38
回答 4查看 9.1K关注 0票数 2

如何在JavaScript中向我自己的类的对象添加事件侦听器,以及如何从这些对象中分派事件?

在Sprite 3中,我可以简单地继承ActionScript /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;
    // ...
}

既然这两种语言与事件看起来如此“相似”,我想我需要继承一些类?或者我必须使用一些全局变量,比如window和/或document?

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

EN

回答 4

Stack Overflow用户

发布于 2015-06-29 17:28:02

我尝试将这些方法添加到我的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);
    }
}
票数 5
EN

Stack Overflow用户

发布于 2016-09-09 01:25:07

这是某种“函数式”方法,我不喜欢在javascript中使用"new“和" This”。我喜欢普通的、对等的或扩展的对象。

// Some helper functions, should be imported from a different file
const partial = fn => (...pargs) => (...args) => fn.apply(null, [...pargs, ...args]);
const partialRight = fn => (...pargs) => (...args) => fn.apply(null, [...args, ...pargs.reverse()]);

// Module starts here
const on = (listeners, type, listener, once) => {
  if (!listeners[type]) {
    listeners[type] = [];
  }
  if (listeners[type].indexOf(listener) < 0) {
    listener.once = once;
    listeners[type].push(listener);
  }
};

const once = partialRight(on)(true);

const off = (listeners, type, listener) => {
  const listenerType = listeners[type];
  if (listenerType && listenerType.length) {
    const index = listenerType.indexOf(listener);
    if (index !== -1) {
      listenerType.splice(index, 1);
    }
  }
  if ((listenerType && !listenerType.length) || !listener) {
    delete listeners[type];
  }
};

const emit = (listeners, type, ...data) => {
  if (listeners[type]) {
    listeners[type].forEach(listener => {
      listener.apply(null, data);
      if (listener.once) {
        off(listeners, type, listener);
      }
    });
  }
};

// you could use "export default () => {}" to make it an importable module
const eventEmitter = () => {
  const listeners = {};
  return {
    on: partial(on)(listeners),
    once: partial(once)(listeners),
    off: partial(off)(listeners),
    emit: partial(emit)(listeners),
  };
};

const myObj = Object.create(Object.assign({}, eventEmitter()));

myObj.on('hello', name => console.log(name));

setTimeout(() => {
  myObj.emit('hello', 'Csaba')
}, 2000)

票数 1
EN

Stack Overflow用户

发布于 2015-06-29 16:13:16

您可以在JS中使用Event和CustomEvent对象执行几乎相同的操作:

var event = new Event('build');

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

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

来源: MDN (https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31110706

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档