已解决 - 底部有示例处理程序的解决方案。
有没有办法停止多次触发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的跟踪结果:
来自Main的跟踪结果:
正如你所看到的,预加载器为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重复实例的人的例子,没有关于如何正确使用它们的真实解释。
每天都是上学日!
答案 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");
}
}
此代码将跟踪"添加"在控制台中只有一次。