ActionScript 3 EventDispatcher 的 Javascript 实现
我正在将 ActionScript 应用程序移植到 JavaScript,并且正在尝试完善我的 EventDispatcher 实现。
我最近遇到的一个问题是,我附加的回调没有使用正确的 this
值进行调用。我临时修复它的方法是向 addEventListener
添加第三个参数,并将上下文发送回,但这并不理想,因为它与等效的动作脚本不匹配相同的原型。
我尝试的另一件事是 this.callback 风格的函数,但这有更多问题,尤其是使用 removeEventListener
时。
有没有办法在 Javascript 中遵循 ActionScript 的事件样式?
我当前的实现附在下面:(取决于 jQuery / jQueryMX)
var EventDispatcher = jQuery.Class.extend({
listeners: {},
init: function() {
this.listeners = {};
},
addEventListener: function(event, listener, context) {
if (this.listeners.hasOwnProperty(event)) {
this.listeners[event].push([listener,context]);
} else {
this.listeners[event] = [[listener,context]];
}
},
hasEventListener: function() {
console.error('hasEventListener unimplemented', arguments);
},
removeEventListener: function(event, listener) {
if (this.listeners.hasOwnProperty(event)) {
for (i in this.listeners[event]) {
if (this.listeners[event][i][0] == listener) {
this.listeners[event].splice(i,1);
return true;
}
}
} else {
//console.log('no listener found for',event,listener,this);
return false;
}
},
dispatchEvent: function(event) {
if (event.type && this.listeners.hasOwnProperty(event.type)) {
event.currentTarget = this;
//console.log('dispatchEvent',event,this);
for (i in this.listeners[event.type]) {
if (typeof this.listeners[event.type][i][0] == 'function') {
this.listeners[event.type][i][0].call(this.listeners[event.type][i][1],event);
}
}
}
}
});
I'm porting an ActionScript application to JavaScript, and I'm trying to perfect my EventDispatcher implementation.
A recent problem I had is that the callbacks that I had attached weren't being called with the correct this
value. The way I temporarily fixed it was to add a third parameter to addEventListener
with the context to be sent back, but this isn't ideal as it doesn't match the same prototype as the actionscript equivilant.
The other thing I tried is a this.callback -style function, but that has even more problems, especially with removeEventListener
.
Is there a way to follow ActionScript's event style in Javascript?
My current implentaton is attached below: (depends on jQuery / jQueryMX)
var EventDispatcher = jQuery.Class.extend({
listeners: {},
init: function() {
this.listeners = {};
},
addEventListener: function(event, listener, context) {
if (this.listeners.hasOwnProperty(event)) {
this.listeners[event].push([listener,context]);
} else {
this.listeners[event] = [[listener,context]];
}
},
hasEventListener: function() {
console.error('hasEventListener unimplemented', arguments);
},
removeEventListener: function(event, listener) {
if (this.listeners.hasOwnProperty(event)) {
for (i in this.listeners[event]) {
if (this.listeners[event][i][0] == listener) {
this.listeners[event].splice(i,1);
return true;
}
}
} else {
//console.log('no listener found for',event,listener,this);
return false;
}
},
dispatchEvent: function(event) {
if (event.type && this.listeners.hasOwnProperty(event.type)) {
event.currentTarget = this;
//console.log('dispatchEvent',event,this);
for (i in this.listeners[event.type]) {
if (typeof this.listeners[event.type][i][0] == 'function') {
this.listeners[event.type][i][0].call(this.listeners[event.type][i][1],event);
}
}
}
}
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Actionscript 3 和 Javascript 是根本不同的语言。您可能会在 addEventListener 函数中使用arguments.callee,并获得某种 AS3 EventDispatcher 接口的近似值,但考虑到两种语言之间的固有差异,不可能(或不需要)完全匹配它。我们通常在 AS3 中使用 EventDispatcher 的方式依赖于 绑定方法,Javascript中根本不存在这种方法。
我想说,您当前的实现不仅是正确的,而且比您一直追求的目标更强大、更安全。通过传递和存储每个事件侦听器的上下文,您可以不断提醒自己,您使用的是 Javascript,而不是 ActionScript,并且您可以避免一整类陷阱,这些陷阱会伴随着忽略 Javascript 的函数作用域和作用域之间的差异而出现。 AS3的
Actionscript 3 and Javascript are fundamentally different languages. You might play around with arguments.callee in your addEventListener function and get some sort of approximation of the AS3 EventDispatcher interface, but it is not possible (or desirable) to match it exactly given the inherent differences between the two languages. The way we typically use EventDispatcher in AS3 relies upon the concept of a Bound Method, which does not exist at all in Javascript.
I'd say your current implementation is not only correct, but more powerful and safer than what you've been shooting for. By passing along and storing the context for each event listener, you're constantly reminding yourself that you're in Javascript, not actionscript, and you're avoiding an entire class of pitfalls that goes along with neglecting the difference between Javascript's function scope and AS3's
回想一下在 AS2 中,您拥有可能派上用场的委托实用程序类。
Think back in AS2 to where you had the delegate utility class that might come in handy.