我刚刚遇到一个奇怪的场景,我想在一个没有名字的函数中使用removeEventListener()
。我的意思是,我在addEventListener()
中创建了函数,而不是引用一个函数:
addEventListener(
Event.ENTER_FRAME,
function(e:Event):void
{
if(getTimer() > 8000)
{
// removeEventListener(Event.ENTER_FRAME, <<this function>>);
// Other stuff
}
}
);
是否可以引用当前函数(即我正在使用的函数)?或者我只需要以标准方式构建上述内容?
请注意,我完全清楚您可以使用许多可用的标准化方法来实现上述目标,它纯粹是一个示例代码段。
答案 0 :(得分:15)
有两个选项,您可以为其命名(有三种方法可以执行此操作),也可以使用arguments.callee。
对于前者,在AS3中命名函数的三种方法是:
class Foo
{
// class (static or member) level
public function bar():void
{
// use a variable (technically, this function is anonymous, but we can
// still use the variable to reference the function itself.
var inVariable:Function = function():void
{
// declare it in a local scope
function local():void
{
}
}
}
}
使用命名函数:
function callback(e:Event):void {
trace("tick");
removeEventListener(Event.ENTER_FRAME, callback);
}
addEventListener(Event.ENTER_FRAME, callback);
使用arguments.callee:
addEventListener(
Event.ENTER_FRAME,
function(e:Event):void
{
if(getTimer() > 8000)
{
// I get superstitious and I use a local variable.
var callee:Function = arguments.callee
removeEventListener(event.type, callee);
// Other stuff
}
}
);
答案 1 :(得分:2)
你只需要给它一个名字,例如:
addEventListener(Event.ENTER_FRAME, function callback(e:Event):void {
trace("tick");
removeEventListener(Event.ENTER_FRAME, callback);
});
在这个例子中,“tick”只会被追踪一次。
答案 2 :(得分:2)
在actionscript中使用匿名函数是一个糟糕的选择,因为它非常慢。他们几乎不能被垃圾收集。还可以提一下,这只有在调用监听器时才会起作用(是的,如果是enter_frame的话),所以在匿名函数之外其他函数无法删除监听器。除此之外,is还是一个使用单独函数的actionscript约定,这使得您的代码更具可读性,并且只需要几个额外的字符(仅为其命名)。
addEventListener(Event.ENTER_FRAME, onEnterFrame);
function onEnterFrame(e:Event):void
{
if(getTimer() > 8000)
{
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}
}
如果您想要一种更简单的方法来删除事件监听器;您可以从目标对象中检测侦听器的类型和函数被调用者。但是我认为这也会使代码的可读性降低。
e.target.removeEventListener(e.type, arguments.callee);
<强>来源强>
http://jacksondunstan.com/articles/413
http://gskinner.com/blog/archives/2006/07/as3_weakly_refe.html