首先看我从网上转载了一篇文章:
<!------------
在flex中我们可以很方便的在mxml标签中使用事件名="函数名()"来给对象添加侦听..
像click="goUrl()"
可是当我们不需要该侦听的时候..
如果想使用
id.removeEventListener("click",goUrl)来删除侦听.
却发现怎么也remove不成功..
原来使用该方法给对象添加侦听时..
flex并不是直接使用我们指定的函数(goUrl),
而是先动态生成一个函数.
然后再使用该函数调用我们指定的函数..
所以我们使用id.removeEventListener("click",goUrl)当然就失败了...
正当ym的时候..记得之前使用过状态(state)来移除过这样的侦听..
马上试了下一下..
<mx:states>
<mx:State name="statename">
<mx:SetEventHandler target="{obj}" name="click"/>
</mx:State>
</mx:states>
运行了一下..果然成功了..
无耐之前只好把swf反编译一下...终于在代码里看到了
一个叫"__obj_click"的函数..
猜想这个应该就是由flex动态添加的函数..于是试了一下...
obj.removeEventListener("click",this["__obj_click"]);
//这里需要注意..为什么不直接使用__obj_click
而使用this["__obj_click"],
因为当flex编译时..__obj_click 这个函数还不存在,直接调用会出错..所以取巧一下..
保存运行..侦听成功删除...猜想正确...
分析一下该函数的规律..
第一部份是"__"
第二部份是对象ID
第三部份是"_"
第四部份是事件名
相应的
mouseOver事件就是__obj_mouseOver
mouseDown事件就是__obj_mouseDown
-------------!>
在实际运用中,我们可能为某个组件或容器添加监听
xx(Id).addEventListener(xxxEvent,fun)
又要在AS代码中用获取组件或容器的ID来移除监听
xx(Id).removeEventListener(xxxEvent,fun);此时不能移除该监听改怎么办呢?
今天在开发的时候用到了一种比较简单和实用的办法就是,在上面的监听事件执行方法fun中用判断
一个变量的值来控制代码执行,比如加一个flg:Boolean的开关,将要监听的代码放到if(flg){}里面,用
不到监听时,但现在又不能移除监听,这时就可以将flg设置为false不然监听事件的方法执行任何逻辑
代码。这样虽然没有根本移除监听,但对要经常在一个容器或组件上反复使用和取消监听的菜鸟是个很
不错的解决方法!!!
我们继续用代码来实例为在mxml中的组件不能用xx(Id).removeEventListener(xxxEvent,fun)移除
和哪些情况可以移除,请阅读下面实例:(自定义监听事件参数,和移除监听)
我们知道FLEX添加监听事件,会经常使用到,但是常见的方法,并不能自定义参数。我收集到一个非常好的方法。可以在监听的时候,添加自己喜欢的参数。好吧,我们开始第一个
- <?xml version="1.0" encoding="utf-8"?>
- <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
- xmlns:s="library://ns.adobe.com/flex/spark"
- xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
-
- <fx:Script>
- <![CDATA[
- import mx.controls.Alert;
- public var count:int=0;
- protected function button1_clickHandler(event:MouseEvent):void
- {
- bt2.addEventListener(MouseEvent.CLICK,function(event:MouseEvent):void
- {
- clickPar(event,20,30);
- });
- }
- protected function clickPar(event:MouseEvent,x:int,y:int):void
- {
-
- count++;
- ta.text+="被调用了"+count+"次"+"x:"+x+"y:"+y+"\n";
- }
-
-
-
-
- ]]>
- </fx:Script>
-
- <fx:Declarations>
-
-
- </fx:Declarations>
- <s:Button x="64" y="40" label="按钮1" click="button1_clickHandler(event)"/>
- <s:Button x="63" y="97" label="按钮2" id="bt2"/>
- <s:TextArea x="217" y="32" id="ta"/>
-
- </s:Application>
点击按钮1,为按钮2,添加相应的监听事件,点击一次按钮一,将会增加一次对按钮2的监听。这样我们就可以实现监听事件的时候,传递相关参数。问题来了,我们现在需要移除监听。好吧,我们继续,按照我们常规的做法,就是把这个函数再写一遍就是了。
- <?xml version="1.0" encoding="utf-8"?>
- <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
- xmlns:s="library://ns.adobe.com/flex/spark"
- xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
-
- <fx:Script>
- <![CDATA[
- import mx.controls.Alert;
- public var count:int=0;
- protected function button1_clickHandler(event:MouseEvent):void
- {
- bt2.addEventListener(MouseEvent.CLICK,function(event:MouseEvent):void
- {
- clickPar(event,20,30);
- });
- }
- protected function clickPar(event:MouseEvent,x:int,y:int):void
- {
-
- count++;
- ta.text+="被调用了"+count+"次"+"x:"+x+"y:"+y+"\n";
- }
- protected function button3_clickHandler(event:MouseEvent):void
- {
- bt2.removeEventListener(MouseEvent.CLICK,function(event:MouseEvent):void
- {
- clickPar(event,20,30);
- });
- }
-
-
-
- ]]>
- </fx:Script>
-
- <fx:Declarations>
-
-
- </fx:Declarations>
- <s:Button x="64" y="40" label="按钮1" click="button1_clickHandler(event)"/>
- <s:Button x="63" y="97" label="按钮2" id="bt2"/>
- <s:TextArea x="217" y="32" id="ta"/>
- <s:Button x="63" y="155" label="按钮3" click="button3_clickHandler(event)"/>
- </s:Application>
我们点击按钮三的时候,事实并非所想,难道这是一个bug,还是怎么回事?开始骂Adobe,设计的什么玩意。
其实function(event:MouseEvent):void
{
clickPar(event,20,30);
}
这是一个匿名函数,虽然写的是一模一样,但是函数地址是不一样的,所以说,移除的不是你添加的,这句话你明白了吗?我似乎听见,都在说,small case。
解铃还须系铃人,我们把那个监听的函数给记住,然后不就可以了吗!对。这个匿名函数,怎么能得到他呢。当然我们可以查一下帮助文档,arguments 出现在我们面前,为什么我会知道这个东西呢?当然,我写这篇文章之前,我都从网络上搜索好了,实现方法是什么,所以知道该查什么。
public var callee:Function
Language Version: |
ActionScript 3.0 |
Runtime Versions: |
AIR 1.0, Flash Player 8, Flash Lite 4 |
A reference to the currently executing function.
这是他的原话,意思是一个对当前函数的引用。秀一下英语,比较难的时候,我都在google翻译过来,然后再去理解。
下面稍微修改一下,就可以移除了。
- <?xml version="1.0" encoding="utf-8"?>
- <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
- xmlns:s="library://ns.adobe.com/flex/spark"
- xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
-
- <fx:Script>
- <![CDATA[
- import mx.controls.Alert;
- public var count:int=0;
- public var ft:Function;
- protected function button1_clickHandler(event:MouseEvent):void
- {
-
- bt2.addEventListener(MouseEvent.CLICK,function(event:MouseEvent):void
- {
- clickPar(event,20,30,arguments.callee);
- });
- }
- protected function clickPar(event:MouseEvent,x:int,y:int,fn:Function):void
- {
- ft=fn;
- count++;
- ta.text+="被调用了"+count;
- }
-
-
- protected function button3_clickHandler(event:MouseEvent):void
- {
-
- bt2.removeEventListener(MouseEvent.CLICK,ft);
- }
-
- ]]>
- </fx:Script>
-
- <fx:Declarations>
-
-
- </fx:Declarations>
- <s:Button x="64" y="40" label="按钮1" click="button1_clickHandler(event)"/>
- <s:Button x="63" y="97" label="按钮2" id="bt2"/>
- <s:TextArea x="217" y="32" id="ta"/>
- <s:Button x="63" y="155" label="按钮3" click="button3_clickHandler(event)"/>
-
- </s:Application>
我总感觉,Flex与JS有太多的相似性,当我不熟悉Flex的时候,我就向JS想,看看能不能有什么突破点没。