2010-09-30 64 views
0

好了,这里就是我想要做的事:怪异AS3变量行为

我有上有3个按钮的登陆页面,和我有3个对应的外部SWF文件,每一个按钮...所以用户点击一个按钮并将相应的swf文件加载到舞台上的空白MC中。现在,每个外部swf文件还包含多个按钮,单击这些按钮时每个按钮都会触发单击事件,每个swf中的每个按钮事件均基于按钮名称和swf文件名称进行唯一命名(例如:swf1_button1_click)So在单击按钮后的主SWF文件中,循环显示3个主按钮,并为每个按钮添加侦听器,以便侦听“swf1_button1_click”,“swf1_button2_click”,“swf2_button1_click”等各个按钮的内容。 。 等等等等。

现在,这一切工作,剪辑正确加载,事件触发,并听取赞许意思是空剪辑确实收到“swf1_btn1_click”事件,它正确地触发与该事件相关的代码,但问题是与该函数所谓的,这是有问题的代码...

用于加载外部SWF文件的功能:

function loadCommunity(e:MouseEvent) { 
var mLoader:Loader = new Loader(); 
var community:String = MovieClip(e.currentTarget).name; 
trace("Loading " + community); 
var mRequest:URLRequest = new URLRequest(DevSite+"/flash/" + community + ".swf?community=" + community); 
mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, displayCommunity); 
mLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, function(e:ProgressEvent) { 
    var percent:Number = e.bytesLoaded/e.bytesTotal; 
    percent = Math.round(percent * 100); 
    trace(percent + "% loaded"); 
}); 
mLoader.load(mRequest); 
} 

分配事件侦听器的代码:

function displayCommunity(e:Event) { 
for (var i = 0; i < mcCommunityHolder.numChildren; i++) { 
    mcCommunityHolder.removeChild(mcCommunityHolder.getChildAt(i)); 
} 
mcCommunityHolder.alpha = 0; 
mcCommunityHolder.visible = true; 
mcCommunityHolder.addChild(e.currentTarget.content); 
TweenLite.to(mcCommunityHolder, 1, {alpha:1, easing:Elastic.easeOut}); 
var newClip:MovieClip = MovieClip(mcCommunityHolder.getChildAt(mcCommunityHolder.numChildren - 1)); 

for each (var mc:MovieClip in mcCommunities) { 
    var commName:String = mc.name.toLowerCase(); 
    trace(" ... " + commName + " ... "); 
    newClip.addEventListener(commName + "_btnMap", function(e:Event) { trace("clicked: " + commName); viewLotmap(commName); }); 
    newClip.addEventListener(commName + "_btnLocation", function(e:Event) { trace("clicked: " + commName); viewLocationmap(commName); }); 
    newClip.addEventListener(commName + "_btnAriel", function(e:Event) { trace("clicked: " + commName); arielPhotos(commName); }); 
    newClip.addEventListener(commName + "_btnRegister", function(e:Event) { trace("clicked: " + commName); communityRegister(commName); }); 
} 
} 

所以我得到的是:无论外部swf的按钮,我点击了其中的按钮的事件,就好像我在哪里点击从外部swf 3内的按钮...有道理?我点击按钮1,外部swf 1加载并显示,在外部swf 1中点击按钮1,它触发其事件“swf1_btn1_click”并且主要swf看到它,但是当此功能(“ communityRegister(commName);“)在侦听器事件中被调用,”commName“始终是相同的值(主swf的btn3应具有的值)。

所以我的主要闪存块是对待每一个外部swfs事件,就好像它们来自外部swf 3一样。我可以解释它的最好方法是:它处理“commName:String”就好像它在哪里引用变量和何时我在循环的每一次迭代中都提交它,它以前的用法也会更改为新的值,所以每次使用它时总是将其设置为上次分配的值的值...

Gahh !!,什么是脑残,哈哈......我以前曾经有过这个问题很多次,但从未真正弄明白过。我一直设法重新编写代码,直到修复它的自我,但我厌倦了这样做,我想知道为什么会发生这种情况。我对其他编码方式不感兴趣,我需要知道是怎么回事,导致这种行为,所以不要害羞得到技术;)

在此先感谢。

回答

0

我想你已经发现了这个问题。所有事件侦听器最后都会引用在循环的最后一次迭代中创建的commName

有一些解决方法。关闭我的头顶:

for each (var mc:MovieClip in mcCommunities) { 
    var commName:String = mc.name.toLowerCase(); 
    trace(" ... " + commName + " ... "); 
    newClip.commName = commName; 
    newClip.addEventListener(commName + "_btnMap", function(e:Event) { trace("clicked: " + e.target.commName); viewLotmap(e.target.commName); }); 
    newClip.addEventListener(commName + "_btnLocation", function(e:Event) { trace("clicked: " + commName); viewLocationmap(e.target.commName); }); 
    newClip.addEventListener(commName + "_btnAriel", function(e:Event) { trace("clicked: " + e.target.commName); arielPhotos(e.target.commName); }); 
    newClip.addEventListener(commName + "_btnRegister", function(e:Event) { trace("clicked: " + e.target.commName); communityRegister(e.target.commName); }); 
} 

这里的想法是,既然影片剪辑是动态的,你可以添加commName作为一个属性。然后,在事件处理程序中,您可以从mc实例中访问该值。

其他选项可能是这样的:

for each (var mc:MovieClip in mcCommunities) { 
    var commName:String = mc.name.toLowerCase(); 
    trace(" ... " + commName + " ... "); 
    setEvents(newClip,commName); 
} 

function setEvents(mc:MovieClip,commName:String):void { 
    mc.addEventListener(commName + "_btnMap", function(e:Event) { trace("clicked: " + commName); viewLotmap(commName); }); 
    mc.addEventListener(commName + "_btnLocation", function(e:Event) { trace("clicked: " + commName); viewLocationmap(commName); }); 
    mc.addEventListener(commName + "_btnAriel", function(e:Event) { trace("clicked: " + commName); arielPhotos(commName); }); 
    mc.addEventListener(commName + "_btnRegister", function(e:Event) { trace("clicked: " + commName); communityRegister(commName); }); 
} 

传递commName作为参数,应该防止的是,MCS共享相同的值。

+0

外观极好!我现在明白了,不知道为什么我没有看到过,但现在我知道了,感谢您的帮助:) – gbinflames 2010-10-01 17:52:47

0

编辑:卫生署,哈哈我只是重新阅读上面的注释,这种方法实际上是他做了第二个建议,我是有点跃跃欲试了他的第一建议和失败......哦,好了,我米会留下这个原始评论这里虽然因为它解释了为什么第一个建议将无法正常工作,第二个...

好的,所以你的解释是合理的,但你的解决方案不起作用...这里是为什么:

你说要添加一个属性到movieclip,它包含“commName”的值以消除引用变量问题,这是需要的(虽然“commName”刚刚分配的“mc.name”所以你可以只使用“mc.name”来代替),但引用问题的价值仍然存在,因为我们正处在一个for循环...

for each (var mc:MovieClip in mcCommunities)... 

因此,“三菱商事”依然看作是一个参考变量,我们仍然得到同样意外的结果是这样(每个对象的事件充当虽然它被点击的行中的最后一个对象,其中...)

我们如何解决它......那么,我落得这样做改变“为每个”到“为(VAR我:INT ...),并抢得‘’通过使用‘getObjectAt(I)’起初我还以为会工作MC,但事实证明,我们仍然有的演技像一个参考变量,这一次是“我:INT”的迭代...所以这个:

for (var i:int = 0; i < mcCommunities.numChildren; i++) { 
MovieClip(mcCommunities.getChildAt(i)).name); ... 

其中mcCommunities.numChildren为3(0,1,2)引起i到等于3(不是一个有效索引)当环路退出和到处我已成立“的MovieClip(mcCommunities.getChildAt(i))的。名称);”前手现在有3个为我的值,以及... fustration

所以最终的工作液如下:

function displayCommunity(e:Event) { 
    for (var i = 0; i < mcCommunityHolder.numChildren; i++) { 
     mcCommunityHolder.removeChild(mcCommunityHolder.getChildAt(i)); 
    } 
    mcCommunityHolder.alpha = 0; 
    mcCommunityHolder.visible = true; 
    mcCommunityHolder.addChild(e.currentTarget.content); 
    TweenLite.to(mcCommunityHolder, 1, {alpha:1, easing:Elastic.easeOut}); 

    for (var j:int = 0; j < mcCommunities.numChildren; j++) { 
     assignListeners(MovieClip(mcCommunityHolder.getChildAt(mcCommunityHolder.numChildren - 1)), MovieClip(mcCommunities.getChildAt(j)).name); 
    } 
} 

function assignListeners(newClip:MovieClip, commName:String) { 
    newClip.addEventListener(commName + "_btnMap", function(e:Event) { trace("clicked: " + commName); viewLotmap(commName); }); 
    newClip.addEventListener(commName + "_btnLocation", function(e:Event) { trace("clicked: " + commName); viewLocationmap(commName); }); 
    newClip.addEventListener(commName + "_btnAriel", function(e:Event) { trace("clicked: " + commName); arielPhotos(commName); }); 
    newClip.addEventListener(commName + "_btnRegister", function(e:Event) { trace("clicked: " + commName); communityRegister(commName); }); 
} 

我所做的就是把分配的eventListeners出来并将它放在一个函数中,所以现在无处不在导致引用ENCE变量之前,现在正在通过功能PARAMATERS其中仅在如此你怎么称呼它,你可以肯定的值将是你送什么,每次函数自身的范围内分配;)满意

总之,谢谢指着我在正确的方向,我得到了我的头现在缠这一点,我可以找到一些其他的似乎不合逻辑的问题来拉我的头发了:)

和平