(转)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 发现的一个典型问题, 希望对大家有帮助 :-)