ADDED_TO_STAGE 触发问题
ADDED_TO_STAGE firing issues
已解决 - 底部有示例处理程序的解决方案。
有没有办法阻止 ADDED_TO_STAGE 事件多次触发。
我注意到,通过加载加载我的主文件的外部预加载器,任何后续 Movieclips 添加到舞台或嵌套多次,具体取决于深度。
预加载器
主要 - (添加到舞台)UINav
在 UINav class(添加任何按钮或 MovieClip)
如果我从 Main 测试 MovieClip,
结果 Main 触发一次,UINav 触发一次,但 UINav 内或超出 UINav 的任何 objects 触发两次,或三次,具体取决于它们的深度。
如果我从预加载器测试 MovieClip,
结果 Main 触发一次,UINav 触发一次,但 UINav 内或以外的任何 objects 触发三到四次,具体取决于它们的深度。
预加载器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
主要 Class :
包 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
站点 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
preLoader 的跟踪结果:
Main 的跟踪结果:
如您所见,预加载器为 UINav 触发两次,为 Header 触发三次,主要是为 UINav 触发一次,为 header 触发两次。
请提供任何线索,因为这是驾驶精神!?
我理解为什么会这样的本质,但是如果我在另一个 object 中添加一个 object,为什么它会考虑是否在每个级别的舞台上。如果我添加一个切换到最高 object 添加,在它被删除后,当它 re-adds 和 object 到舞台时它只触发一次!?
首先,这正常吗?我已经看到关于 ADDED_TO_STAGE 触发两次的类似示例提出的问题并尝试了所有但没有任何区别,我已经在初始化后清除并删除了所有 eventListeners 但没有任何区别。
有没有办法阻止这种情况发生,或者有人可以阐明使用嵌套 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 重复实例,但没有关于如何正确使用它们的真正解释。
每天都是上学日!
您没有清除事件侦听器,因为它们绑定到此,而不是舞台。
您应该像这样从 class 中删除事件侦听器:
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");
}
}
此代码将仅在控制台中跟踪 "added" 一次。
已解决 - 底部有示例处理程序的解决方案。
有没有办法阻止 ADDED_TO_STAGE 事件多次触发。
我注意到,通过加载加载我的主文件的外部预加载器,任何后续 Movieclips 添加到舞台或嵌套多次,具体取决于深度。
预加载器 主要 - (添加到舞台)UINav 在 UINav class(添加任何按钮或 MovieClip)
如果我从 Main 测试 MovieClip, 结果 Main 触发一次,UINav 触发一次,但 UINav 内或超出 UINav 的任何 objects 触发两次,或三次,具体取决于它们的深度。
如果我从预加载器测试 MovieClip, 结果 Main 触发一次,UINav 触发一次,但 UINav 内或以外的任何 objects 触发三到四次,具体取决于它们的深度。
预加载器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
主要 Class :
包 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
站点 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
preLoader 的跟踪结果:
Main 的跟踪结果:
如您所见,预加载器为 UINav 触发两次,为 Header 触发三次,主要是为 UINav 触发一次,为 header 触发两次。
请提供任何线索,因为这是驾驶精神!?
我理解为什么会这样的本质,但是如果我在另一个 object 中添加一个 object,为什么它会考虑是否在每个级别的舞台上。如果我添加一个切换到最高 object 添加,在它被删除后,当它 re-adds 和 object 到舞台时它只触发一次!?
首先,这正常吗?我已经看到关于 ADDED_TO_STAGE 触发两次的类似示例提出的问题并尝试了所有但没有任何区别,我已经在初始化后清除并删除了所有 eventListeners 但没有任何区别。
有没有办法阻止这种情况发生,或者有人可以阐明使用嵌套 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 重复实例,但没有关于如何正确使用它们的真正解释。
每天都是上学日!
您没有清除事件侦听器,因为它们绑定到此,而不是舞台。 您应该像这样从 class 中删除事件侦听器:
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");
}
}
此代码将仅在控制台中跟踪 "added" 一次。