我的问题看起来像:我有五个按钮,其中四个正在将四个不同的swf画廊加载到主SWF中,最后一个卸载所有画廊。它们中的每一个都具有完全相同的代码,唯一的区别是jpg文件和swf文件的位置。另外,每个人都有听众ADDTOSTAGE
和REMOVEFROMSTAGE
,因为我使用了gallery / swfs中的stage
。
因此,当我进入菜单并加载第一个swf时,我没有收到任何输出错误,当我点击btn_back
时,他正确地卸载了swf而没有任何错误。等等,但只有当我加载一个画廊时。
但是当我在加载第一个图库后,想要点击另一个按钮并加载第二个图库然后我在输出中出现了这个错误,因此在加载的swf / gallery中加载了很多图片:
TypeError: Error #1009: Nie można uzyskać dostępu do właściwości lub metody dla odniesienia do obiektu null.
at DocObject/resizeMyDoc()
at DocObject/onResizeDoc()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.display::Stage/dispatchEvent()
at Miniaturka/onAddedToStage()
at flash.display::DisplayObjectContainer/addChild()
at Miniaturki/callback()
at Function/http://adobe.com/AS3/2006/builtin::apply()
at Miniaturka/onLoadComplete()
所以我的结论是问题不在加载的swf中,而是在加载和卸载我的swf代码的代码中。我能找到的唯一解决方案是:当我单击第二个按钮时,代码应首先卸载当前的swf,当卸载完成后,立即加载另一个。但我不知道如何写它。有人可以帮忙吗?所以这是代码。
import flash.events.MouseEvent;
import fl.transitions.Tween;
import fl.transitions.easing.*;
import fl.transitions.TweenEvent;
import flash.display.Loader;
var _mainLoader:Loader;
var _currentContent:DisplayObject;
var url:URLRequest;
var loaded:Boolean = false;
var a:Array = new Array(s1_1_arch, s1_2_arch, s1_3_arch, s1_4_arch);
var swfList:Array = ["A0101.swf", "A0102.swf", "A0103.swf"];
//Initiate Loader, do it only once
function initiateLoader():void {
_mainLoader = new Loader();
_mainLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
}
function loadGallery(path:String):void {
//Check if content previously loaded, unload it
if (_currentContent != null) {
removeChild(_currentContent);
_currentContent = null;
_mainLoader.unloadAndStop();
}
//Now load another one
_mainLoader.load(new URLRequest[1]);
}
function onComplete(e:Event):void {
_currentContent = _mainLoader.content;
//Add root DisplayObject of the loaded content to the display list
stage.addChild(_currentContent);
}
function samClick(e:MouseEvent):void
{
switch (e.target)
{
case s1_1_arch :
break;
case s1_2_arch :
break;
case s1_3_arch :
break;
case s1_4_arch :
break;
}
}
function samOver(e:MouseEvent):void{
switch (e.target)
{
case s1_1_arch : var sam1Ou:Tween = new Tween(s1_1_arch, "alpha", Strong.easeOut, 1, 0.2, 0.5, true);
break;
case s1_2_arch : var sam2Ou:Tween = new Tween(s1_2_arch, "alpha", Strong.easeOut, 1, 0.2, 0.5, true);
break;
case s1_3_arch : var sam3Ou:Tween = new Tween(s1_3_arch, "alpha", Strong.easeOut, 1, 0.2, 0.5, true);
break;
case s1_4_arch : var sam4Ou:Tween = new Tween(s1_4_arch, "alpha", Strong.easeOut, 1, 0.2, 0.5, true);
break;
}
}
function samOut(e:MouseEvent):void{
switch (e.target)
{
case s1_1_arch : var sam1Ou:Tween = new Tween(s1_1_arch, "alpha", Strong.easeOut, 0.2, 1, 0.5, true);
break;
case s1_2_arch : var sam2Ou:Tween = new Tween(s1_2_arch, "alpha", Strong.easeOut, 0.2, 1, 0.5, true);
break;
case s1_3_arch : var sam3Ou:Tween = new Tween(s1_3_arch, "alpha", Strong.easeOut, 0.2, 1, 0.5, true);
break;
case s1_4_arch : var sam4Ou:Tween = new Tween(s1_4_arch, "alpha", Strong.easeOut, 0.2, 1, 0.5, true);
break;
}
}
for (var i:Number = 0; i < 4; i++)
{
a[i].addEventListener(MouseEvent.CLICK, samClick);
a[i].addEventListener(MouseEvent.MOUSE_OVER, samOver);
a[i].addEventListener(MouseEvent.MOUSE_OUT, samOut);
}
答案 0 :(得分:0)
你是正确的方式。但是您的代码中存在许多问题,大多数交换机都是冗余的。默认情况下,您加载的所有图库都将加载到子ApplicationDomains
中,因此它们适合垃圾回收。
如果您使用单Loader
,您将更容易管理它,并及时加载一个部分。
//Pseudo code
Create main loader (with onComplete event handler);
Create a function for loading content, and call it.
Check if previous load operation was successful (use your flag `loaded`), if Yes - unload previous content, remove previous content from the display list;
Load new content;
After loading is completed, add content to the main display list holder, designed to show gallery content.
另外,我建议使用TweenLite,它也更适合开发者。
这里有几个可以帮助您完成任务的实用功能:
private var _mainLoader:Loader;
private var _currentContent:DisplayObject;
//Initiate Loader, do it only once
private function initiateLoader():void {
_mainLoader = new Loader();
_mainLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
}
private function loadGallery(path:String):void {
//Check if content previously loaded, unload it
if (_currentContent != null) {
removeChild(_currentContent);
_currentContent = null;
_mainLoader.unloadAndStop();
}
//Now load another one
_mainLoader.load(new URLRequest(path));
}
private function onComplete(e:Event):void {
_currentContent = _mainLoader.content;
//Add root DisplayObject of the loaded content to the display list
addChild(_currentContent);
}
更具体的实现,你可以在你的框架中使用它,但不要忘记进行所有导入,并在场景中创建所有必要的显示对象:
//Self explanatory
var currentContent:DisplayObject;
//Initiate Loader
var mainLoader:Loader = new Loader();
mainLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
//Create some MovieClip and give it a name, you will place loaded content there, ex: contentHolder
//Add buttons in one container (MovieClip) and give it name, ex: buttonHolder
//Give buttons some names, ex: s1Arch, s2Arch, s3Arch
//Map our buttons to external links and prepare for mouse events
var links:Object = {"s1Arch": "A0101.swf", "s2Arch": "A0102.swf", "s3Arch": "A0103.swf"};
//Register listeners, you could do it in cycle
s1Arch.addEventListener(MouseEvent.CLICK, onClickButton);
s2Arch.addEventListener(MouseEvent.CLICK, onClickButton);
s3Arch.addEventListener(MouseEvent.CLICK, onClickButton);
//Mouse events, using events bubbling
buttonHolder.addEventListener(MouseEvent.CLICK, onClickButton);
function loadGallery(path:String):void {
//Check if content previously loaded, unload it
if (currentContent != null) {
contentHolder.removeChild(currentContent);
currentContent = null;
mainLoader.unloadAndStop();
}
//Now load another one
mainLoader.load(new URLRequest(path));
}
function onClickButton(e:MouseEvent):void {
//Explanation step-by-step
//Clicked button
var button: DisplayObject = DisplayObject(e.currentTarget);
//Path to the external file
var path: String = links[button.name];
//Utility function will handle another stuff
loadGallery(path);
}
function onComplete(e:Event):void {
currentContent = mainLoader.content;
//Add root DisplayObject of the loaded content to the display list
contentHolder.addChild(currentContent);
}
答案 1 :(得分:0)
只是添加......
对于这样的事情,你最好将所有代码放在一个地方。如果您还是新手,类文件将在以后为您节省其他挫折。只需控制一个地方的所有元素。还要考虑Nicolas Siver在答案中所说的话。
关于如何设置类文件的快速指南。如果您保存为Main.as并附加到FLA,那么您可以在此处粘贴时间轴代码。
package
{
//IMPORTS go here
//Declare your Class (name of .as file)
public class Main extends MovieClip
{
//VARS go here
//Declare main function of your Class (must have same name as Class (.as file)
public function Main()
{
// Your main program code go here
//Something(); //example: run a function called Something
}
public function Something();
{
// Do something code
}
} //End of Class
} //End of Package