从外部加载 swf 时 removechild 不工作

removechild not working when the swf is loaded externally

我的问题是 放在 swf 中的关闭按钮(removechild) 单独使用时效果很好,但是 当从另一个 swf 加载时 按钮 不再有效。

这是外部 swf 代码:

eti_scroll.scrollTarget = box_eti ;
hab_scroll.scrollTarget = box_hab ;
com_scroll.scrollTarget = box_com ;
descr_scroll.scrollTarget = box_descr ;



       exit.addEventListener(MouseEvent.CLICK, exitBtn_clickHandler);  

    function exitBtn_clickHandler(event:MouseEvent):void {  
    if(this.parent) this.parent.removeChild(this);
}  

这是主 swf 中的按钮代码:

menu_button_2.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler2);

function fl_MouseClickHandler2(event:MouseEvent):void
{
    var myLoader:Loader = new Loader();                     
    var url:URLRequest = new URLRequest("pages/page_template.swf");  
    myLoader.load(url);                                  
    addChild(myLoader);
}

在主 swf 中没有导入包或 loaderclass

这里是 link 到 fla 版本和示例版本: http://www.mediafire.com/file/5dzqnq3kth6n6dt/examples.rar

当我使用@organis 的跟踪代码并从外部 SWF 文件加载时抛出错误: 抛出的错误:

 I am here! Exit Button: [object SimpleButton] object Event Handler: function
 Function() {} function Exit.addEventListener: function Function() {} function 
MouseEvent.CLICK This: [object MainTimeline] object Parent: [object Loader] 
object Parent.removeChild: function Function() {} function Error: Error #2069:
 La clase Loader no implementa este método(The Loader Class doesn't implement 
this method). at Error$/throwError() at flash.display::Loader/removeChild() at 
page_template_fla::MainTimeline/onClick()[page_template_fla.‌​MainTimeline::frame1‌​
:65] –

让我解释一下如何处理这种问题。一旦应该工作的东西不工作,首先要做的是查明问题的确切位置,这样你就可以诊断出问题是什么,而不是模糊地知道某处有问题。

所以你从独立 运行 读取所有痕迹,然后从加载 运行 读取所有痕迹,这肯定有区别。找到它后,您就根据差异采取行动。

// If this does not work, that means scripts do not work in the loaded SWF at all.
trace("I am here!");

// If this doesn't work the same as standalone, that means
// something breaks while constructing the loaded content.
trace("Exit Button:", exit, typeof(exit));

// Lets check id the event handler is doing fine.
trace("Event Handler:", onClick, typeof(onClick));

// If the method is not present on the object,
// something is deeply wrong with the whole thing.
trace("Exit.addEventListener:", exit.addEventListener, typeof(exit.addEventListener));

exit.addEventListener(MouseEvent.CLICK, onClick);  

function onClick(event:MouseEvent):void
{
    // If it doesn't work that means there's no mouse event.
    trace("MouseEvent.CLICK");

    // Just to check things out.
    trace("This:", this, typeof(this));
    trace("Parent:", this.parent, typeof(this.parent));
    trace("Parent.removeChild:", this.parent.removeChild, typeof(this.parent.removeChild));

    if(this.parent) this.parent.removeChild(this);
}

UPD: 现在,你得到了错误(实际上你应该首先在你的问题中提到它)

错误:错误 #2069:加载器没有实现方法(_加载器 Class 没有实现方法_)。在 Error$/throwError() 在 flash.display::Loader/removeChild() 在 page_template_fla::MainTimeline/onClick()[page_template_fla.‌ MainTimeline::frame1‌ :65]

现在看看这里(我喜欢这个 link 因为它解释了很多):https://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e26.html

你的剧本在主时间线上。因此,当您 运行 它处于独立模式时, this.parent 指向 stage 可以添加和删除子项,没问题。

然后,当您 运行 它处于 loaded 模式时,层次结构进入 main SWF stage -> main SWF root -> ... -> Loader -> loaded SWF root。如您所见,当您寻址 this.parent 时,您会得到 Loader 实例,这正是您在主 SWF 中用于加载另外一个。 Loader 是一个 DisplayObjectContainer 但不适用于 adding/removing 儿童,因此它抛出 exception 上面提到了

综上所述,我建议使用另一种方法来删除看不见的内容:

exit.addEventListener(MouseEvent.CLICK, onClick);  

function onClick(event:MouseEvent):void
{
    // Unsubscribe to help Garbage Collector do its job.
    exit.removeEventListener(MouseEvent.CLICK, onClick);  

    // Hide the content.
    visible = false;

    // Remove all of its children.
    removeChildren();
}

或者您可以判断您的脚本 运行 正在执行的情况并采取相应行动:

exit.addEventListener(MouseEvent.CLICK, onClick);  

function onClick(event:MouseEvent):void
{
    // Unsubscribe to help Garbage Collector do its job.
    exit.removeEventListener(MouseEvent.CLICK, onClick);  

    // Checking for
    // if (parent == null)
    // is unnecessary here because if that was the case
    // there won't be a mouse event in the first place.

    var aParent:DisplayObjectContainer = parent;

    if (aParent is Loader)
    {
        // Loaded case.
        aParent.parent.removeChild(aParent);
    }
    else
    {
        // Standalone case.
        parent.removeChild(this);
    }
}

但是,计算 仅适用于简单情况,不适用于更复杂的设置(跨域内容、安全沙箱等)。