这是我在主要类中的Flash / AS3中的代码。
addEventListener(Event.ENTER_FRAME,function(e:Event){
if(findObject == true){
// I want to remove this ENTER FRAME
}
});
答案 0 :(得分:13)
试试这个:
e.currentTarget.removeEventListener(e.type, arguments.callee)
答案 1 :(得分:5)
您不应该在上面的代码中执行操作。
如果事件的currentTarget
没有removeEventListener()
方法(可能,但非常不可能),mgraph的代码很可能无法像宣传的那样工作。从编译器的角度来看,虽然您将尝试动态解决一个易于出错的通用对象上的方法,但应小心处理。这是危险的,因为它表明程序员“不知道”她期望通过假设处理和工作的对象是什么样的。假设对于找到解决方案很有帮助,但对于实现解决方案同样不好。
如果您想要以您的方式优化某些内容,那么,仅仅是FYI这实际上会在符号表(在已编译的SWF文件中)中创建一个唯一的(冗余)名称,这会导致SWF的压缩程度更低。
如果您在实验中这样做,这很好,但您应该避免在现实生活中的代码。
还有一件事需要注意:与true
常数的比较是100%无用的。如果这样的比较完全有意义(即findObject
可能随时评估为false
),那么if (findObject) { ... }
等同于您的代码的更短版本。
最后,希望匿名函数缺少返回类型声明。除了您将收到编译器警告之外,它在您的示例中不会发生太大变化。一般来说,省略类型声明是一种不好的风格。
修改强>
public function addEventListener(type:String, listener:Function ...):void
{
this._listeners[type].push(listener);
}
public function dispatchEvent(event:Event):void
{
for each (var listener:Function in this._listeners[event.type])
listener(event);
}
public function removeEventListener(type:String, listener:Function, ...):void
{
delete this._listeners[type][listener];
}
假设您实际上想要实现IEventDispatcher(而不是使用另一个EventDispatcher - 您可能有理由这样做,原因之一是本机EventDispatcher生成大量短期对象 - 事件,您可能希望减少那个。)但是你无法在你的代码中复制event.target或event.currentTurget,因为你无法访问拥有该方法的对象,所以,你可以把它留下来。
另一个例子:
public class SomeEvent extends Event
{
private var _target:NotEventDispatcher;
public function SomeEvent(type:String, someTarget:NotEventDispatcher)
{
super(type);
this._target = someTarget;
}
public override function get target():Object
{
return this._target;
}
}
这是我在现实世界中实际看到的东西,这在Mate或类似框架中用于“匿名”将所有事件调度程序连接到某个“母舰事件调度程序”的单个静态实例。
我不一定能证明这种做法,但从技术上讲,没有什么可以阻止你做其中任何一种。我在上面的帖子中所说的是,在某些情况下,语言会向你承诺,例如,如果你这样做:
var dispatcher:IEventDispatcher;
try
{
dispatcher = IEventDispatcher(event.currentTarget);
// now you can be sure this object has removeEventListener
dispatcher.removeEventListener(event.type, arguments.callee);
}
catch (error:Error)
{
// but what are you going to do here?
}
但最常见的情况是你订阅冒泡事件,在这种情况下,你不知道你是否要取消订阅event.target或event.currentTtarget - 因为你不知道哪一个是那个你在听。
答案 2 :(得分:1)
我同意wvxvw。
解决问题的另一种方法是使用变量来控制"状态"您的ENTER_FRAME事件:
private var _state:String;
private function init(e:Event):void {
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
private function loop(e:Event):void {
switch(_state) {
case "play":
// do play stuff
// when you want to pause
// goToPause();
break;
}
}
// you can call the method below from a button or whatever you want
private function goToPause():void {
_state = "pause";
// do some stuff here
// when you are done, switch "_state" back to "play"
}
在这个例子中,你一直在监听ENTER_FRAME,但它只在_state变量设置为" play"时才会执行操作。您还可以在goToPause方法中删除事件侦听器:
private function goToPause():void {
_state = "pause";
removeEventListener(Event.ENTER_FRAME, loop);
}
然而,使用" _state"的好处是切换的事情是,你不必最终得到一堆addEventListeners和removeEventListeners(这可能会发生,这取决于你的循环得到的复杂程度),你必须跟踪。
答案 3 :(得分:0)
如果您希望稍后删除侦听器,则不应使用匿名函数调用。
public function main():void
{
//...
//some method, where you add event listener
//...
//adding enterFrame event listener
this.addEventListener(Event.ENTER_FRAME,enterFrameHandler);
//...
}
private function enterFrameHandler(e:Event)
{
if(findObject) // " == true" is not really necessary here.
{
// removing enterFrame listener:
this.removeEventlistener(Event.ENTER_FRAME,enterFrameHandler);
}
}
答案 4 :(得分:0)
为了完整性与这里提到的其他技术,你正在创建的功能是一个未绑定的闭包,所以你也可以利用这个概念来引用你的函数和调度程序。
var callback:Function;
var dispacher:IEventDispatcher = this;
addEventListener(Event.ENTER_FRAME, callback = function(e:Event){
if(findObject == true){
dispacher.removeEventListener(Event.ENTER_FRAME, callback);
}
});
适用正常的已结算变量规则。