(转)AS3中的stage,this,root的区别

要了解这个问题就要先对flash中的显示对象结构有一个大概的了解:

 

第一级:舞台;

 

第二级:当前SWF;

 

第三级:各种容器及可视对象(如:文本框,位图……);

 

以此类推…………

 

stage:

 

其中舞台(Stage)是最根本的容器,包含当前SWF的所有显示对象,每个flash程序只能有一个舞台容器。

 

所有显示对象的stage属性指向舞台。

 

root:

 

在舞台下面的也是一个容器,被称作当前SWF主类的实例(注:AS3.0中所有容器直接或间接继承自DisplayObjectContainer类),在AS3.0中,每一个SWF都和一个类相关联,这个类就称为SWF的主类,如果没有设定文档类,则MainTimeline类(注:MainTimeLine是MovieClip的子类)就是主类。而root就指向当前SWF主类的实例(注:在AS2.0中,_root.指代绝对路径)。

 

this:

 

this关键字持有对当前对象的引用,编译器将this关键字加在类中每一个调用实例属性和实例方法的地方。

 

this关键字常见使用情况:

 

(1)向第三方提供对象自身的引用。

 

(2)与return结合,在类方法中返回自身的引用。

 

(3)和局部变量,方法参数,静态属性同名时,加上this关键字明确指定使用实例属性。

 

1.STAGE是根,是最顶层的容器!可以通过STAGE的任何子容器或显示

 

对象以DisplayObjectContainer.stage(需注意的是stage是小写,如果在时间轴上trace(stage.width)是正确的,如果写成trace(Stage.width则会报错))或DisplayObject.stage访问到Stage类的

 

唯一实例stage.就连主时间轴也是stage容器的子容器。

例如。你在主时间轴上写上代码:trace(this);输出的是什么呢?因为你是在主

 

时间轴上写的。所以返回的是一个对象:MainTimeLine,也就是主时间轴了。同

 

志们可以试试在主时间轴上写:trace(this.stage);当然输出的是Stage对象了

 

。也可以省略不写this,直接写:trace(stage);输出的还是Stage对象。为了更清

 

楚,在主时间轴上写上代码:trace(stage.getChildAt(0));看看输出的是什么

 

呢?如果是MainTimeLine的话,就更能说明问题了,主时间轴是stage容器的第

 

一个子容器,在索引位置0上。

 

2.stage.width 与stage.stageWidth

 

我记得width相当于sprite的width,是stage上所有child构成的范围的宽(

 

没东西width就是0),stageWidth就是舞台的宽

其实这个问题很简单,但是你为什么不自己用个两个文本框在各种不同的情况下

 

显示一下这两个的值呢。

 

Java代码

1.stage.addEventListener(MouseEvent.CLICK,update);  

2. 

3.function update(e)  

4.{  

5.   txt.text = String(stage.stageWidth);  

6. 

7.   txt1.text = String(stage.width);  

8.} 

stage.addEventListener(MouseEvent.CLICK,update);

 

function update(e)

{

   txt.text = String(stage.stageWidth);

 

   txt1.text = String(stage.width);

}

 

 

 

自己看看吧,改变一下舞台的大小,场景上的东西,还有环境,缩放,

 

自己试出来的结果永远比别人讲的来的清晰

 

 

 

3.这两天看AS3 cookbook和AS3的帮助文档,里面很多代码执行后都会出现“TypeError: Error #1009: 无法访问空对象引用的属性或方法。”这个错误。几经周折,才知道解决办法:使用addEventListener( Event.ADDED_TO_STAGE, enterDLHandle ),把要用的stage代码放到enterDLHandle里面,就没问题了。不知道有没有其他解决方法,知道的说声啊~

 

在经典论坛上提问这个问题,终于有人做出全面回答了,在此感谢zjs35

 

首先要明白stage是什么意思,stage是显示对象的一个引用舞台的属性,如果显示对象不在显示列表中,即没有用addChild()添加,stage等于null,你的问题就在这里。

使用stage有下面几种方法:

1、文档类的构造函数中可以直接使用stage属性

2、非文档类可以通过参数传递到类里面。

class Test extends Shape

{

function Test(stage:Stage)

{

}

}

3、不想传递参数时,要注意代码的顺序。

class Test extends Shape

{

function Test()

{

}

functon useStage()

{

trace(stage)

}

}

这样使用

var test=new Test()

test.useStage()//null,你的问题出在这里

addChild(test)//添加到显示列表后,就可以使用stage属性。

test.useStage()//[object Stage]

总之,理解stage是显示对象的属性,位于显示列表中的显示对象的stage才引用舞台

 

AS3.0 中root和parent的用法

一、首先看一下在单个swf中的用法:

在主舞台上的帧上写下如下代码:

var xxx="this is root";

新建一个MC,给它一个实例名称test_mc1,在test_mc1中的帧上写下如下代码:

trace(parent["xxx"]);

trace(root["xxx"]);

trace(root["test_mc1"].alpha)

最终的输出为:

this is root this is root

1

如果在test_mc1中在建立一个实例名称为test_mc2的movieclip,如何trace它的alpha呢:

trace(root["test_mc1"].test_mc2.alpha);

最终输出“1”。

 

二、如果是两个swf,他们之间是怎样操作的呢:

新建两个flash文件,命名为a1和a2,

在a1.fla中的帧上写下如下代码:

var xxx="this is root";

var myloader=new Loader();

myloader.load(new URLRequest("a2.swf"));

addChild(myloader);

在a2.fla中建立一个动态文本框,实例名称为txt;

在帧中写下如下代码:

txt.text=parent.root["xxx"];

分别发布两个flash文件,然后运行a1.swf,看到其显示结果为"this is root";

在发布a2.swf是你会看到:

ReferenceError: Error #1069: 在 flash.display.Stage 上找不到属性 xxx,且没有默认值。

at a2_fla::MainTimeline/a2_fla::frame1()

不用去理它,因为他不是通过a1.swf load到场景,所以找不到xxx这个参数。

这里的第一个parent是a1.swf中的myloader,myloader的再上一级才能找到xxx这个参数,这里也可以写成parent.parent["xxx"]。

我想通过这两个例子应该比较清楚如何在AS3中使用root和parent了。

 

但as3的root在类型转换上出现的问题具有普遍性

as3的文档类通常使用Sprite或MovieClip,但实际上继承DisplayObject的类,在理论上均可做文档类

故adobe在设计root时,

设计为root:DisplayObject

 

很多时候需要使用root as MovieClip来使用gotoAndStop一类脚本 这在前一篇文章中(AS2中的_root,在AS3的用法)已经说过了

 

我通过这段时间对 AS 3.0 的研究, 发现下面这个很有价值的问题, 所以今天写下来, 给大家分享.

 

 

Action Script 2.0 中 this 的用法:

在 Flash 里拖一个 Button 组件到舞台, 给这个 Button 实例取个名字叫 b1, 在 b1 身上添加代码:

 

[复制到剪贴板]CODE:on (click) {

this.label = "你点了这个按钮一下";

}

 

这里的 this 指的就是 Button 对象 b1, 点击 b1 之后, b1的标签马上变为"你点了这个按钮一下". 也就是说, 在 AS 2.0 中 this 指的是使用该方法的当前对象.

 

 

Action Script 3.0 中 this 的用法:

在 Flex Builder 的 Design 模式下拖一个 Button 到舞台, 给这个实例取名, 也就是设置 id 的值, 还是取名 b1, 然后回到 Source 模式下, 添加代码:

 

[复制到剪贴板]CODE:<mx:Button id="b1" click="this.label="你点了这个按钮一下";"/>

 

当你运行之后就会发现, 点了 b1 之后, b1 的标签并没有任何改变, 这是因为, this 关键字并不是指的 b1 这个按钮, 而是指的 Application 的实例, 所以, 点了按钮之后, 实际上企图修改的是 Application 的标签, 而不是 b1 这个按钮的标签.

 

因此正确的代码应该是:

 

[复制到剪贴板]CODE:<mx:Button id="b1" click="b1.label="你点了这个按钮一下";"/>

 

原因是这样的: 每个 MXML Application 在保存以后, 实际上都被编译成了一个 AS 3.0 的类(类名跟 MXML 文件名相同), this 指的是这个类本身的实例, 所以 this 的用法跟 AS 2.0 大相径庭, 完全两码事.

 

 

总之, 在 AS 3.0 中, this 永远是指当前顶级类的一个实例(对象), 细分下面几种情况:

 

1. 在 MXML Applcation 文件中, this 永远指的是 Application 的实例;

 

2. 在 MXML Component 文件中, this 永远指的是 Componet 的实例, 也就是这个文件中根元素的实例;

 

3. 在 Action Script Class 文件中, this 永远指的是这个 Class 的实例;

 

4. 如果 MXML Component 和 Action Script Class 都被导入到 MXML Applcation 中, 在这个 MXML Applcation 里 this 关键字依然还是指 Application 的实例, 而不是其中任何子元素的实例.

 

好了, 这就是我最近研究 AS 3.0 发现的一个典型问题, 希望对大家有帮助 :-)

 

posted @ 2012-05-14 10:00  ☆A希亿  阅读(4609)  评论(0编辑  收藏  举报