好的,所以这就是我要做的事情:
我有一个带有3个按钮的登陆页面,我有3个相应的外部swf文件,每个按钮一个...所以用户点击一个按钮,相应的swf文件被加载到舞台上的空MC中。现在每个外部swf文件还包含几个按钮,单击这些按钮时每个按钮都会触发一个click事件,每个swf中的每个按钮事件都是根据按钮名称和swf文件名唯一命名的(例如:swf1_button1_click)所以单击一个按钮后,在主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中点击一个按钮...有意义吗?
下面是一个例子:我点击Button1,外部swf 1加载并显示,在外部swf 1中我单击按钮1,它触发其事件“swf1_btn1_click”,主swf看到它,但是当这个函数(“communityRegister” (commName);“)在侦听器事件中被调用,”commName“始终是相同的值(主swf的btn3应具有的值)。
所以我的主要flash片段正在处理每个外部swfs事件,好像它们来自外部swf 3.我能解释它的最好方法是:它将“commName:String”视为引用变量和我何时在循环的每次迭代中重新签名,之前的使用也会更改为新值,因此每次使用它时总是设置为上次分配的值...
Gahh !!,大脑残骸是什么,哈哈......我以前曾经多次遇到这个问题而且从来没有弄明白这个问题。我总是设法重新编写代码,直到修复它自己,但我厌倦了这样做,我想知道为什么会发生这种情况。我对编写我想做的事情的其他编码方式不感兴趣,我需要知道发生了什么导致这种行为,所以不要害怕获得技术;)
提前致谢。
答案 0 :(得分: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); });
}
这里的想法是,由于MovieClip是动态的,您可以将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共享相同的值。
答案 1 :(得分:0)
编辑:Doh,哈哈,我只是重新阅读上面的评论,这个方法实际上是他提出的第二个建议,我有点急于尝试他的第一个建议而失败......哦,我我会在这里留下这个原始评论,因为它解释了为什么第一个建议不起作用而第二个建议不行......
好的,所以你的解释是合理的,但你的解决方案不起作用......原因如下:
你说要在movieclip中添加一个属性,其中包含“commName”的值,以消除引用变量问题,这是需要的(尽管“commName”只是赋值为“mc.name”,所以你可以只需使用“mc.name”,但引用问题仍然存在,因为我们处于for循环...
for each (var mc:MovieClip in mcCommunities)...
所以“mc”仍然被视为一个引用变量,我们仍然会得到相同的不良结果(每个对象事件就像它被点击的行中的最后一个对象一样......)
那么我们如何解决它......好吧,我最终做的是将“for each”更改为“for(var i:int ...)”并使用“getObjectAt”抓取“mc” i)“起初我认为会起作用,但事实证明我们仍然有一个像引用一样的变量,这次是迭代中的”i: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))。name); “之前现在有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分配出来并将其放在一个函数中,所以现在所有引起引用变量的地方现在都是通过函数参数分配的,函数参数只在函数范围内,所以每次你自己打电话给你,你可以确定价值将是你发送的内容;)满意度
无论如何,感谢你指出我正确的方向,我现在把头缠在这里,我可以找到一些看似不合逻辑的问题来拉我的头发:)
和平