简体   繁体   English

ADDED_TO_STAGE次触发问题

[英]ADDED_TO_STAGE firing issues

Resolved - Solution with example handlers at the bottom. 已解决 -解决方案的底部带有示例处理程序。

Is there a way to stop the ADDED_TO_STAGE event firing multiple times. 有没有一种方法可以停止ADDED_TO_STAGE事件多次触发。

I've noticed that by loading an external preLoader which loads my Main file, any subsequent Movieclips added to the stage or nested fire multiple times depending upon the depth. 我注意到,通过加载外部preLoader来加载我的Main文件,随后的任何Movieclips都会根据深度而多次添加到舞台或嵌套射击。

preLoader Main - (Add to stage) UINav In UINav class (add any button or MovieClip) preLoader Main-(添加到舞台)UINav在UINav类中(添加任何按钮或MovieClip)

If I test the MovieClip from the Main, Result Main fires once, UINav fires once, but any objects within UINav or beyond fire twice, or three times depending upon their depth. 如果从主界面测试MovieClip,则“结果主界面”会触发一次,UINav会触发一次,但是UINav内或以外的任何对象都会触发两次,或三次,具体取决于它们的深度。

If I test the MovieClip from the preLoader, Result Main fires once, UINav fires once,but any objects within UINav or beyond fire three or four times depending upon their depth. 如果我从preLoader中测试MovieClip,则Result Main会触发一次,UINav会触发一次,但是UINav内或以外的任何对象都会触发三到四次,具体取决于它们的深度。

preloader Class : 预载器类别:

package
{   

public class preLoader extends MovieClip
{

    public function preLoader()
    {
        if( stage ) added( null );
            else
            addEventListener( Event.ADDED_TO_STAGE, added );
    }
    private function added( event:Event ):void
    {
        stage.removeEventListener( Event.ADDED_TO_STAGE, added );
        stage.removeEventListener( Event.ADDED_TO_STAGE, init );
        trace( "preSite : "+ getQualifiedClassName( this ), "Initiated" );

        stage.scaleMode = StageScaleMode.NO_SCALE;
        stage.align = StageAlign.TOP_LEFT;
        stage.stageFocusRect = false;

        //loadStatusTxt on stage
        //preLoadText on stage

        var loader : Loader = new Loader();
        _targetLoaderInfo = loader.contentLoaderInfo;
        _targetLoaderInfo.addEventListener( ProgressEvent.PROGRESS, onProgress );
        _targetLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, errorIOHandler);
        _targetLoaderInfo.addEventListener( Event.COMPLETE , onLoaded );

        if( Capabilities.playerType != "External" )
        {
            loader.load( new URLRequest("Main.swf?id=" + myIdentifier) );
        } else {
            loader.load( new URLRequest("Main.swf") );
        }
    }

    private function errorIOHandler( event:IOErrorEvent ):void
    {
        trace( event.text );
    }

    private function onProgress( event:ProgressEvent ):void
    {

        var loaded : uint = event.bytesLoaded;
        var total : uint = event.bytesTotal;

        var percentLoaded:Number = Math.round( (loaded/total) * 100 );

        preLoadText.text = "Loading " + percentLoaded + "%";
        addChild( preLoadText );

        pLoader.x = stage.stageWidth / 2;
        pLoader.y = stage.stageHeight - 50;
        addChild( pLoader );

        _loadPercent = _targetLoaderInfo.bytesLoaded / _targetLoaderInfo.bytesTotal;
        updateLoader( _targetLoaderInfo.bytesLoaded /  _targetLoaderInfo.bytesTotal );

        if ( _loadPercent >= 100 )
        {
            onLoaded( event );
        }
    }

    private function updateLoader( num:Number ) : void {
        //num is a number between 0 and 1
        pLoader.mcPreloaderBar.width = num * 476;
    }

    private function onLoaded( e:Event ):void
    {
        _targetLoaderInfo.removeEventListener( ProgressEvent.PROGRESS, onProgress );
        _targetLoaderInfo.removeEventListener( IOErrorEvent.IO_ERROR, errorIOHandler );
        _targetLoaderInfo.removeEventListener( Event.COMPLETE , onLoaded );

        // TODO hide loader
        removeChild( pLoader );
        while ( this.numChildren > 0 )
        {
            this.removeChildAt( 0 );
        }           
        this.addChild( DisplayObject(LoaderInfo(e.target).content) );
        trace( "Class "+ getQualifiedClassName( this ), " - COMPLETE" );
    }

}//End Class
}// End Package

Main Class : 主类:

package com.misoLepto { 软件包com.misoLepto {

public class Main extends MovieClip
{

    public static var test_Main : Boolean = true;// true = Live / false = TraceEvents

    public var site_Background : Site_Background = new Site_Background();
    public var site_UINav : Site_UINav = new Site_UINav();

    public function Main()
    {
        if ( stage ) init();
        else    addEventListener( Event.ADDED_TO_STAGE, init );
    }
    public function init( event : Event = null):void
    {
        if( hasEventListener( Event.ADDED_TO_STAGE ))
        {
            stage.removeEventListener( Event.ADDED_TO_STAGE, init );
            trace( "YES Listener Main" );
        }
        else
        {
            trace( "NO Listener Main" );
        }
        GlobalVariable.stage = stage;

        //stage.removeEventListener(Event.ADDED_TO_STAGE, init);
        stage.addEventListener( Event.RESIZE, resizeMain );

        stage.scaleMode = StageScaleMode.NO_SCALE;
        stage.align = StageAlign.TOP_LEFT;

        setupMain();
    }
    private function toggleUINav( e:Event ):void {
        if( site_UINav.stage )
        {
            removeChild( site_UINav );
        }
        else
        {
            addChild( site_UINav );
        }
    }
    private function setupMain():void
    {
        addChild( site_UINav );
        stage.addEventListener( MouseEvent.CLICK, toggleUINav );
    }
    private function resizeMain( event : Event ) : void
    {
        trace("Resized Stage");
    }

}//End Class
}//End Package

UINav CLass : UINav CLass:

package com.misoLepto {

public class Site_UINav extends MovieClip {

    public var site_Header : Site_Header = new Site_Header()

    public function Site_UINav()
    {
        if ( stage ) initUINav();
        else    addEventListener( Event.ADDED_TO_STAGE, initUINav, false, 0, true );
                addEventListener( Event.REMOVED_FROM_STAGE, removedUINav );
    }
    public function initUINav( event : Event = null ):void
    {

        stage.removeEventListener( Event.ADDED_TO_STAGE, initUINav );
        stage.addEventListener( Event.RESIZE, resizeUINav );
        setupUINav();
    }
    private function setupUINav():void {
        trace("UINav : Initiated");
        addChild( site_Header );
    }
    private function resizeUINav( event : Event ) : void
    {
        trace("Resized Stage");
    }
    private function removedUINav ( event : Event ):void
    {           
        stage.removeEventListener( Event.RESIZE, resizeUINav );
        stage.removeEventListener( Event.REMOVED_FROM_STAGE, removedUINav );
        removeChild( site_Header );
    }

}//End Class
}//End Package

Site Header Class : 网站标题类别:

package com.misoLepto {


public class Site_Header extends Sprite {

    public var headPanel : Sprite = new Sprite();
    public var lineColour : uint = new uint( 0x999999 );
    public var lineWidth : Number = new Number( 1 );
    public var headerColour : uint = new uint( 0xFFFFFF );

    public function Site_Header ()
    {
        if ( stage ) initHeader();
         else
         addEventListener( Event.ADDED_TO_STAGE, initHeader, false, 0, true );
         addEventListener( Event.REMOVED_FROM_STAGE, removedHeader );
    }
    public function initHeader ( e : Event = null ):void
    {
        stage.removeEventListener( Event.ADDED_TO_STAGE, initHeader );
        stage.addEventListener( Event.RESIZE, resizeHeader );

        headPanel.graphics.lineStyle( lineWidth, lineColour );
        headPanel.graphics.beginFill( headerColour, 1 );  
        headPanel.graphics.drawRoundRect( stage.stageWidth / 2, 2, stage.stageWidth / 2 - 3, 25, 10 );
        headPanel.graphics.endFill();
        trace( "HeaderPanel : Initialised" );
        addChild(headPanel);

        setupHeader();
    }
    public function resizeHeader( event : Event ) : void
    {
        if ( headPanel.stage )
        {
            headPanel.graphics.clear();
            headPanel.graphics.lineStyle( lineWidth, lineColour );
            headPanel.graphics.beginFill( headerColour, 1 );  
            headPanel.graphics.drawRoundRect( stage.stageWidth / 2, 2, stage.stageWidth / 2 - 3, 25, 10 );
            headPanel.graphics.endFill();
        }
        else
        {
            trace("headPanel not on screen");
        }
    public function removedHeader ( e : Event ):void {          
        stage.removeEventListener( Event.RESIZE, resizeHeader );
        stage.removeEventListener( Event.REMOVED_FROM_STAGE, removedHeader );
        headPanel.graphics.clear();
        removeChild( headPanel );
    }

}//End Class
}//End Package

Trace results from preLoader : 跟踪来自preLoader的结果:

preLoader结果

Trace results from Main : 跟踪来自Main的结果:

主要结果

As you can see, the preloader fires twice for the UINav, and three times for the Header, and in the main it fires the UINav once and the header twice. 如您所见,预加载器会为UINav触发两次,并为Header触发三次,而在主菜单中,它会触发UINav一次,并触发两次Header。

Any clues please as this is driving mental!? 请提供任何线索,因为这令人担忧!

I understand the essence of why this would be but if I'm adding an object within another object why does it account for if being placed on stage at each level. 我理解为什么会这样,但如果我要在另一个对象中添加一个对象,为什么要放在每个级别的舞台上,这也要解释为什么。 If I add a toggle to the highest object added, after its been removed, when it re-adds the object to the stage it only fires the once!? 如果我将切换开关添加到添加的最高对象,则将其删除后,将对象重新添加到舞台时,它只会触发一次!

Firstly, is this normal? 首先,这正常吗? I've seen issues raised about similar examples of ADDED_TO_STAGE firing twice and tried all but nothing makes a difference, I've cleared and removed all eventListeners after they are initialised but nothing makes a difference. 我已经看到了有关ADDED_TO_STAGE两次触发的类似示例的问题,并尝试了所有措施,但没有任何效果。初始化后,我清除并删除了所有eventListener,但没有任何效果。

Is there a way to stop this from happenening or can someone please shed some light on the best procedure to work with nested Movieclips!? 有什么方法可以阻止这种情况的发生,或者有人可以说明与嵌套Movieclips一起使用的最佳过程吗? Also, if this is regular, surely this is a major drawback from using an external preloader too? 另外,如果这是常规操作,那么这肯定也是使用外部预加载器的主要缺点吗?

Thanks in advance. 提前致谢。

Resolved : (thanks to @ices_2) 解决:(感谢@ ices_2)

For any others suffering, here's the ammended code to use ADDED_TO_STAGE with trace handlers to see the event being added and removed. 对于其他受苦的人,下面是经过修改的代码,可将ADDED_TO_STAGE与跟踪处理程序配合使用,以查看事件的添加和删除。

public function Site_UINav()
{
        if ( this.stage ) initUINav();
        else
            this.addEventListener( Event.ADDED_TO_STAGE, initUINav );
            this.addEventListener( Event.REMOVED_FROM_STAGE, removedUINav );
    }
    public function initUINav( event : Event = null ):void
    {
        trace( "UINav listerner present (a): " + this.hasEventListener( Event.ADDED_TO_STAGE ));
        if(this.hasEventListener( Event.ADDED_TO_STAGE ))
        {
            //remove listener if it was added
            this.removeEventListener( Event.ADDED_TO_STAGE, initUINav );
        }
        trace( "UINav listerner present (b): " + this.hasEventListener( Event.ADDED_TO_STAGE ));
    }

Remove the REMOVE_FROM_STAGE event : 删除REMOVE_FROM_STAGE事件:

    private function removedUINav ( event : Event ):void
    {           
        stage.removeEventListener( Event.RESIZE, resizeUINav );
        trace( "UINav listerner present (c): " + this.hasEventListener( Event.REMOVED_FROM_STAGE ));
        if(hasEventListener( Event.REMOVED_FROM_STAGE ))
        {
            //remove listener if it was ever added
            this.removeEventListener( Event.REMOVED_FROM_STAGE, removedUINav );
        }
        trace( "UINav listerner present (d): " + this.hasEventListener( Event.REMOVED_FROM_STAGE ));
    }

Thanks again, so many examples online of people suffering ADDED_TO_STAGE duplicates instances and no real explanation as to how to use them correctly. 再次感谢您,在线上有许多关于遭受ADDED_TO_STAGE折磨的人们的例子都是重复的实例,而对于如何正确使用它们并没有真正的解释。

Everyday's a school day! 每天都是上学日!

You are not clearing event listeners because they bind to this, and not the stage. 您不会清除事件侦听器,因为它们绑定到此侦听器,而不是绑定到阶段。 You shold remove event listener from class like this: 您可以像这样从类中删除事件侦听器:

public class Preloader extends MovieClip
{
    public function Preloader()
    {
        if (stage)
            this.init();
        else
            this.addEventListener(Event.ADDED_TO_STAGE, init);
    }

    private function added(event:Event):void
    {
        this.removeEventListener(Event.ADDED_TO_STAGE, init);
        trace("added");
    }
}

This code will trace "added" in console only one time. 此代码将仅在控制台中跟踪“添加”一次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM