ADDED_TO_STAGE解雇问题

时间:2016-03-09 07:53:47

标签: actionscript-3 events stage

已解决 - 底部有示例处理程序的解决方案。

有没有办法停止多次触发ADDED_TO_STAGE事件。

我注意到通过加载一个加载我的主文件的外部preLoader,任何后续的Movieclips都会多次添加到舞台或嵌套的火焰中,具体取决于深度。

预加载 主要 - (添加到舞台)UINav 在UINav类中(添加任何按钮或MovieClip)

如果我从Main测试MovieClip, 结果主要发射一次,UINav发射一次,但是UINav内或之外的任何物体发射两次或三次,具体取决于它们的深度。

如果我从preLoader测试MovieClip, 结果主要发射一次,UINav发射一次,但UINav或其他物体内的任何物体根据其深度发射三到四次。

预加载器类:

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

主要类别:

package 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:

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

网站标题类:

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

来自preLoader的跟踪结果:

preLoader Results

来自Main的跟踪结果:

main Results

正如你所看到的,预加载器为UINav触发两次,为Header触发三次,在主体中它会触发一次UINav和两次头部。

任何线索,因为这是开车精神!?

我理解为什么会这样,但如果我在另一个对象中添加一个对象,为什么它会在每个级别放置在舞台上。如果我添加一个切换到添加的最高对象,在删除它之后,当它将对象重新添加到舞台时它只会触发一次!?

首先,这是正常的吗?我已经看到有关ADDED_TO_STAGE两次触发的类似示例的问题,并尝试了所有但没有什么有所作为,我已经清除并在初始化后删除所有eventListener但没有任何区别。

有没有办法阻止这种情况发生,或者有人可以了解使用嵌套Movieclips的最佳程序!?另外,如果这是常规的,那么使用外部预加载器肯定是一个主要的缺点吗?

提前致谢。

已解决:(感谢@ ices_2)

对于其他任何受苦的人,请参阅修改后的代码,将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_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 ));
    }

再次感谢,网上有很多关于遭受ADDED_TO_STAGE重复实例的人的例子,没有关于如何正确使用它们的真实解释。

每天都是上学日!

1 个答案:

答案 0 :(得分:1)

您没有清除事件侦听器,因为它们绑定到此而不是舞台。 你可以像这样从类中删除事件监听器:

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");
    }
}

此代码将跟踪"添加"在控制台中只有一次。