如何在JavaScript中向我自己的类的对象添加事件侦听器和调度事件?
在ActionScript 3中,我可以简单地从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。
答案 0 :(得分:5)
我尝试将方法添加到我的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);
}
}
答案 1 :(得分:1)
你可以制作自己的,这个是通用的,非常简单。我实际上自己使用它:D
这是您将获得的功能。
这个函数将向对象添加所需的方法,同时返回一个可以调度事件的函数。
// 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)};
}
// Simplified example of usage =========================================
function App(){
// Add functionality
var dispatchEvent = createEventDispatcher(this); // Call snippet
// Use functionality
var count = 0;
setInterval(function(){
dispatchEvent("something",{msg:"hello",count:count++});
},100);
}();
// Somewhere outside your App
function onSomething(event){
console.log(event.msg + "["+event.count+"]");
if(event.count >= 10){
// Remove eventlistener
myApp.removeEventListener("something",onSomething);
}
}
var myApp = new App();
myApp.addEventListener("something",onSomething);
// Easy
https://jsfiddle.net/squadjot/0n2nby7k/
如果要从对象中删除所有侦听器,可以执行类似的操作。
myApp.__listeners = {};
答案 2 :(得分:0)
您可以在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)
答案 3 :(得分:0)
这是某种“功能”方法,我不喜欢在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)