2010-09-30 96 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其中僅在如此你怎麼稱呼它,你可以肯定的值將是你送什麼,每次函數自身的範圍內分配;)滿意

總之,謝謝指着我在正確的方向,我得到了我的頭現在纏這一點,我可以找到一些其他的似乎不合邏輯的問題來拉我的頭髮了:)

和平