(转)关于Flex及AS3的百多条小小知识(2)


关于Flex及AS3的百多条小小知识

                           脚本之家(www.jb51.net)

【当文本字段受到选取或取消选取时给予响应】
获得焦点时: FocusEvent.FOCUS_IN
失去焦点时: FocusEvent.FOCUS_OUT
通过键盘(Tab键)把焦点移除时: FocusEvent.KEY_FOCUS_CHANGE
通过鼠标把焦点移除时: FocusEvent.MOUSE_FOCUS_CHANGE
FocusEvent类有一个relatedObject属性.就FOCUS_IN事件而言,relatedObject属性是刚才拥有焦点的对象的引用 地址;对于FOCUS_OUT,KEY_FOCUS_CHANGE以及MOUSE_FOCUS_CHANGE事件,relatedObject属性是刚接 收到焦点的对象的引用地址.
FOCUS_IN和FOCUS_OUT事件都是在焦点改变后发生的,所以两者都是不可取消的事件.对于KEY_FOCUS_CHANGE和MOUSE_FOCUS_CHANGE事件,可以使用FocusEvent.preventDefault()方法取消默认行为:
field.addEventListener(FocusEvent.KEY_FOCUS_CHANGE, onKeyFocus);
private function onKeyFocus(event:FocusEvent):void {
    if(field.text == "") {
        event.preventDefault(); //当field没有任何文字前,不允许使用Tab键把焦点移除
    }
    //event.relatedObject就是刚才拥有焦点的对象的引用地址,即下一个获得焦点的对象的引用地址
}
【响应用户的输入行为】
field.addEventListener(TextEvent.TEXT_INPUT, onTextInput);
private function onTextInput(event:TextEvent):void {
    if(event.text == "a" && field.length == 0) {
        event.preventDefault(); //TEXT_INPUT是可以取消的事件.TextEvent有一个text属性,内含用户所输入的的字符.此例子确保用户输入的第一个字母不是"a"
    }
}
【把超链接加入文字】
打开网页:
例子1:
var css:StyleSheet = new StyleSheet();
css.parseCSS("a{color:#0000FF;} a:hover{text-decoration:underline;}");
field.styleSheet = css;
field.htmlText = "<a href='http://www.riahome.cn' target='_blank'>Link text</a>";
例子2:
field.text = "Link text";
var formatter:TextFormat = new TextFormat();
formatter.url = "http://www.riahome.cn";
formatter.target = "_blank";
field.setTextFormat(formatter);
打开Email:
field.text = "Link text";
var formatter:TextFormat = new TextFormat();
formatter.url = "mailto:y_boy@126.com";
field.setTextFormat(formatter);
使用event协议,打开ActionScript方法:
field.htmlText = "<a href='event:http://www.riahome.cn'>www.RIAHome.cn</a>";
field.addEventListener(TextEvent.LINK, onClickHyperlink);
private function onClickHyperlink(event:TextEvent):void {
    trace(event.text); //输出: http://www.riahome.cn
}
【精确获取某字符的索引值】
在 x 和 y 参数指定的位置返回从零开始的字符索引值
TextField.getCharIndexAtPoint(x:Number, y:Number):int
例子:
field.getCharIndexAtPoint(mouseX, mouseY); //返回鼠标位置上的该字符的索引值
【精确获取某字符的边框区域】
TextField.getCharBoundaries(charIndex:int):Rectangle
通过读取Rectangle的x,y,width以及height等属性来确定该字符的边框区域范围.
【精确获取某行的索引值】
在 x 和 y 参数指定的位置返回从零开始的行索引值
TextField.getLineIndexAtPoint(x:Number, y:Number):int
field.getLineIndexAtPoint(mouseX, mouseY); //返回鼠标位置上的该行的索引值
【获取指定索引值处的字符所在行的行索引值】
TextField.getLineIndexOfChar(charIndex:int):int
【获取指定行的字符数】
TextField.getLineLength(lineIndex:int):int
【获取指定索引值处的行所包含的字符】
TextField.getLineText(lineIndex:int):String
【获取指定行索引所在行的第一个字符的索引值】
TextField.getLineOffset(lineIndex:int):int
【获取指定文本行的度量信息】
TextField.getLineMetrics(lineIndex:int):TextLineMetrics
TextLineMetrics类包含文本字段中某行文本的文本位置和度量值的相关信息,帮助文档里有深入的图解.
【获取指定索引处的字符所在段落内的第一个字符索引值】
如果给定一个字符索引,则返回同一段落中第一个字符的索引
TextField.getFirstCharInParagraph(charIndex:int):int
【获取指定索引处的字符所在段落内的字符数】
TextField.getParagraphLength(charIndex:int):int
【替换所选文字】
TextField.replaceSelectedText(value:String):void
可以使用此方法插入和删除文本而不破坏其余文本的字符和段落格式.
【替换指定范围的文本】
TextField.replaceText(beginIndex:int, endIndex:int, newText:String):void
注意: 如果对文本字段应用了样式表,则该方法不起作用
【Timer计时器的使用】
var timer:Timer = new Timer(delay:Number, repeatCount:int = 0);
timer.addEventListener(TimerEvent.TIMER, onTimer);
timer.start();
private function onTimer(event:TimerEvent):void {
    //code
}
【以指定方向和速度移动元件】
speed: 目标速度
radians: speed与x轴的夹角,弧度
vx = Math.cos(radians) * speed;
vy = Math.sin(radians) * speed;
【缓动动画算法】
targetX,targetY: 目标坐标;
easingSpeed: 每次移动分数,范围0到1;
var vx:Number = (targetX - sprite.x) * easingSpeed;
var vy:Number = (targetY - sprite.y) * easingSpeed;
sprite.x += vx;
sprite.y += vy;
注意: 在非常逼近目标点时,往往找出通往目标点的距离,如果其值少于特定值,就应该停止该缓动.
【模拟弹簧往复运动算法】
五个变量: targetX(目标点的x坐标),sprite.X(物体的x坐标),vx(水平速度),ax(水平加速度),k(弹簧强度)
已知: targetX(目标点的x坐标),k(弹簧强度)
var ax:Number = (targetX - sprite.x) * k;
vx += ax;
sprite.x += vx;
注意: 这里只是水平方向的情形,也可以推广到垂直方向以及水平垂直一起来的情形
【模拟单摆运动】
四个变量: sprite.x(物体的x坐标),centerX(中心位置的x坐标),angle(弧度),radius(摆动的振幅,也就是摆动的范围)
sprite.x = centerX + Math.sin(angle) * radius;
angle += 0.05;
【模拟阻尼运动】
六个变量: targetX(目标点的x坐标),sprite.X(物体的x坐标),vx(水平速度),ax(水平加速度),k(弹簧强度),damp(阻尼系数)
已知: targetX(目标点的x坐标),k(弹簧强度)
var ax:Number = (targetX - sprite.x) * k;
vx += ax;
sprite.x += vx;
vx *= damp; //无阻力情况下的弹簧往复运动只缺少此句
注意: 这里只是水平方向的情形,也可以推广到垂直方向以及水平垂直一起来的情形.
这种原理可以推广到其它属性,如scaleX:
scaleVel += (targetScale - sprite.scaleX) * k;
sprite.scaleX += scaleVel;
scaleVel *= damp;
【计算两点间的角度】
Math.atan2(y:Number, x:Number):Number
y: 两点间的垂直距离
x: 两点间的水平距离
返回一个以弧度为单位的角度,返回值介于正PI和负PI之间.
【让物体指着鼠标(跟随眼睛)】
var dx:Number = mouseX - sprite.x;
var dy:Number = mouseY - sprite.y;
var radians:Number = Math.atan2(dy, dx);
sprite.rotation = radians * 180 / Math.PI;
【联结字符串时需要注意的地方】
var result:String = 2 + 6 + "a";
trace(result); //输出: 8a
var result:String = "a" + 2 + 6;
trace(result); //输出: a26
var result:String = "a" + (2 + 6);
trace(result); //输出: a8
【查找匹配的字符串】
使用String.indexOf(val:String, startIndex:Number = 0):int
返回指定子字符串的第一个匹配项的索引,没有匹配就返回-1
查找所有匹配的字符串:
var index:int = -1;
while((index = myString.indexOf("val", index + 1)) != -1) {
    trace("结果:" + index);
}
使用String.lastIndexOf(val:String, startIndex:Number = 0x7FFFFFFF):int
返回指定子字符串的最后一个匹配项的位置,没有匹配就返回-1
var index:int = myString.length;
while((index = myString.lastIndexOf("val", index - 1)) != -1) {
    trace("结果:" + index);
}
注意: indexOf()和lastIndexOf()方法都是区分大小写的.想把大小写都查找出来的话,可以结合String.toLowerCase()和String.toUpperCase()方法先把字符串一起转为小写或大写再进行查找.
【提取子字符串】
String.substr(startIndex:Number = 0, len:Number = 0x7fffffff):String
String.substring(startIndex:Number = 0, endIndex:Number = 0x7fffffff):String
String.slice(startIndex:Number = 0, endIndex:Number = 0x7fffffff):String
substr()第一个参数可以是负值,表示索引值是从字符串尾端算过来,-1是最后一个字符;
substring()和slice()差别在于substring()只接受正索引值,而把负值作为0处理.另外,如果endIndex小于startIndex,substring()方法在执行前,会自动将其调换过来,总是使用两个参数中较小的值作为起始索引.
slice()方法可接受startIndex和endIndex为负值,而把负值表示为从字符串的尾端算回来,如果endIndex小于startIndex,slice()方法会返回空字符串.
【以指定模式拆分字符串】
String.split(delimiter:*, limit:Number = 0x7fffffff):Array
【替换指定的字符串】
使用String.replace(pattern:*, repl:Object):String
可以这样来替换所有指定的字符串: myString.split("a").join("b");
【按单词或单个字母逆转字符串】
1. 把字符串切割使用String.split()方法成一个数组:对单词而言,以空格作为分界符,对字母而言,以空字符("")作为分界符;
2. 使用Array.reverse()方法对数组进行逆转;
3. 使用Array.join()方法重新组合为字符串:对单词而言,以空格(" ")作为联结符,对字母而言,以空字符("")作为联结符;
【使用SharedObject及捕获异常】
var so:SharedObject = SharedObject.getLocal("so");
so.data.userName = "Youthoy";
try {
    var flushResult:String = so.flush(500 * 1024); //请求500KB容量
    //如果flush()没成功执行,就替netStatus加个事件处理函数以确认用户是同意还是拒绝,否则只检验结果.
    if(flushResult == SharedObjectFlushStatus.PENDING) {
        //替netStatus加个事件处理函数,使得我们可以检验用户是否同意以足够磁盘容量储存共享对象.当netStatus事件发生时,执行onStatus函数.
        so.addEventListener(NetStatusEvent.NET_STATUS, onStatus);
    }else if(flushResult == SharedObjectFlushStatus.FLUSHED) {
        //成功储存.把数据成功储存后你想执行的程序放在这里.
    }
}catch(e:Error) {
    //这里表示用户把本地储存设置为"拒绝".如果储存数据很重要,你会想在此警告用户.
    //此外,如果你想让用户可修改其设定值,可以用下面语句打开Player的"设置"对话框的本地储存页面.
    Security.showSettings(SecurityPanel.LOCAL_STORAGE);
}
//定义onStatus函数以处理共享对象的状态事件.flush()返回"pending"时,引发提示,而用户做了选择后所引发的事件.
function onStatus(event:NetStatusEvent):void {
    if(event.info.code == "SharedObject.Flush.Success"){
        //如果event.info.code内容是"SharedObject.Flush.Success",表示用户同意.把用户同意后你想执行的程序放在这里.
    }else if(event.info.code == "SharedObject.Flush.Failed"){
        //如果event.info.code内容是"SharedObject.Flush.Failed",表示用户同意.把用户拒绝后你想执行的程序放在这里.
    }
    //现在,移除事件监听器,因为我们只需监听一次.
    so.removeEventListener(NetStatusEvent.NET_STATUS, onStatus);
}
【向LSO储存对象时需要注意】
LSO使用二进制的AMF(Action Message Format)对一个对象进行编码.当你在LSO储存类对象时,该对象会编码成包含内容属性的普通对象.于是,当你试着从共享对象里读取该对象时,无法被 读成某类的对象,因为没有类型数据.要克服这个限制,使用flash.net.registerClassAlias()方法.
任何影片中,只要从共享对象读取出自定义对象数据,自定义类就必须注册别名,而且调用registerClassAlias()方法时必须在SharedObject.getLocal()方法被调用之前.
【要相同域名内的两个影片可以存取相同LSO】
首先LSO是储存在以下目录下:
C:\Documents and Settings\[user name]\Application Data\Macromedia\Flash Player\#SharedObjects
例如,如果来自于http://www.riahome.cn/youthoy的影片movie.swf写入名为example的LSO,则数据会储存在以下位置:
C:\Documents and Settings\[user name]\Application Data\Macromedia\Flash Player\#SharedObjects\[random directory name]\riahome.cn\youthoy\movie.swf\example.sol
如果在这个movie.swf里的代码是这样的: var example:SharedObject = SharedObject.getLocal("example", "/"); 也就是使用了选用的本地路径参数,则LSO会储存在以下路径,注意到与以上路径少了"youthoy\movie.swf":
C:\Documents and Settings\[user name]\Application Data\Macromedia\Flash Player\#SharedObjects\[random directory name]\riahome.cn\example.sol
以此方法建立的LSO,可以由相同域的其它Flash影片用以下程序来读取:
var example:SharedObject = SharedObject.getLocal("example", "/");
再看一个例子:
有两个Flash影片movieOne.swf和movieTwo.swf都位于同一域(http://www.riahome.cn)内,但是, movieOne.swf位于http://www.riahome.cn/youthoy/firstGroup,而movieTwo.swf位于 http://www.riahome.cn/youthoy/secondGroup.在这情况里,movieOne.swf可以用下列任何本地路径建 立和读取LSO:
/
/youthoy
/youthoy/firstGroup
而movieTwo.swf可以用下列任何本地路径建立和读取LSO:
/
/youthoy
/youthoy/secondGroup
因此,如果你想要两个影片都可以读取相同LSO,当你调用getLocal()方法时,必须指定影片共享的两个本地路径之一(/或/youthoy).
【URLLoader.dataFormat的三种类型】
URLLoader.dataFormat的可选值是:
flash.net.URLLoaderDataFormat.BINARY
flash.net.URLLoaderDataFormat.TEXT
flash.net.URLLoaderDataFormat.VARIABLES
当dataFormat是BINARY时,URLLoader.data属性就是flash.utils.ByteArray类型;
当dataFormat是TEXT时,URLLoader.data属性就是String类型;
当dataFormat是VARIABLES时,uRLLoader.data属性就是Object类型.
【在XML内使用动态数据】
把变量放在大括号({和})内:
var userName:String = "Youthoy";
var myXML:XML = <person><userName>{userName}</userName></person>;
【新增一个节点元素】
//例子一:
var example:XML = <person/>;
example.father = <father/>; //内容属性和元素名称不一定要相同,也可以: example.abc = <father/>,但会以元素名称为准,即会建立一个<father/>元素
trace(example);
/*
输出:
<person>
<father/>
</person>
*/
//例子二:
var example:XML = <person/>;
example.father = ""; //建立一个<father/>元素
trace(example.toString());
/*
输出:
<person>
<father/>
</person>
*/
//例子三:
var example:XML = <person/>;
var id:int = 10;
example["user" + id] = "";
trace(example);
/*
输出:
<person>
<user10/>
</person>
注意: 有些情况必须使用第三种情况.例如,元素节点名称内含连字符("-")是完全合法的,但在ActionScript里会得到编译器错误:
example.some-element = ""; //产生编译器错误
正确的写法是:
example["some-element"] = "";
*/
【新增属性】
var example:XML = <person/>;
example.element = "";
example.element.@name = "Youthoy";
example.element.@["bad-variable-name"] = "yes";
example.element.@other = ["riahome.cn", undefined, true, 44, null];
var id:int = 44;
example.element.@["user" + id] = "love";
trace(example);
/*
输出:
<person>
<element name="Youthoy" bad-variable-name="yes" other="riahome.cn,,true,44," user44="love"/>
</person>
*/
【向XML插入文字元素和节点元素】
//在指定元素前和后插入,在最前端和尾端插入
var example:XML = <person/>;
example.two = "";
example.insertChildBefore(example.two, <one/>); //在two节点前插入one节点
example.insertChildBefore(example.two, "在two节点前插入文字");
example.insertChildAfter(example.two, <three/>); //在two节点后插入three节点
example.prependChild(<start/>); //在最顶端插入start节点
example.appendChild(<end/>); //在尾端插入end节点
example.start = "start内容"; //向节点增加内容
trace(example);
/*
输出:
<person>
<start>start内容</start>
<one/>
在two节点前插入文字
<two/>
<three/>
<end/>
</person>
*/
【把XML实例的内容属性转换为任何可以转换成字符串的内容】
//先把等号右边转为可以转换的字符串
var example:XML = <person/>;
example.one = "one";
example.two = new URLLoader();
example.three = new Sprite();
example.four = new Boolean; //Boolean对象的值初始化为false
example.five = new Number();
example.six = new String();
example.seven = {a:"Youthoy", b:true, c:undefined};
example.eight = ["three", undefined, true, 44, null];
/*
输出:
<person>
<one>one</one>
<two>[object URLLoader]</two>
<three>[object Sprite]</three>
<four>false</four>
<five>0</five>
<six/>
<seven>[object Object]</seven>
<eight>three,,true,44,</eight>
</person>
*/
【对XML属性层层递归的算法】
var example:XML = <menu>
                    <menuitem label="File">
                      <menuitem label="New"/>
                      <menuitem label="Save"/>
                    </menuitem>
                    <menuitem label="Help">
                      <menuitem label="About"/>
                    </menuitem>
                  </menu>;
walk(example);
function walk(node:XML):void {
for each(var element:XML in node.elements()) {
    trace(element.@label);
    walk(element);
}
【读取文字节点及其值】
var example:XML = <menu>
                    My name is Youthoy.
                    <myName>Youthoy</myName>
                  </menu>;
example.text(); //输出: My name is Youthoy.
example.myName.toXMLString(); //输出: <myName>Youthoy</myName>
//以下三行都输出: Youthoy
example.myName.toString();
example.myName.text();
example.myName;
【递归元素属性时读取属性名与其值】
var example:XML = <person name="Youthoy" age="21"/>;
    for each(var i:XML in example.attributes()) {
    trace(i.name() + "=" + i);
}
/*
输出:
name=Youthoy
age=21
*/
另类方法:
var example:XML = <person name="Youthoy" age="21"/>;
trace(example.@*[1]); //输出: 21
【不论层级地访问整个XML中指定的节点或属性】
使用后代存取器运算符..
例子1(对于节点元素):
var example:XML = <a>
                    <z>I am z.</z>
                    <b>
                     <c></c>
                     <z>I am z.</z>
                   </b>
                 </a>;
trace(example..z.text()); //输出: I am z.I am z.
例子2(对于属性):
var example:XML = <person>
                    <a>
                      <item name="Youthoy" age="21"/>
                    </a>
                    <item name="Jimpa" age="21"/>
                  </person>
trace(example..@name); //输出: YouthoyJimpa
【删除节点元素,文字节点以及属性】
使用delete对单一项进行删除,要删除整个XMLList可以使用for循环以倒序形式进行删除,以避免迭代时需要改变数组索引问题.
【搜索XML的高级应用】
使用术语过滤.(condition),可结合正则表达式来使用.
例子:
var example:XML = <foodgroup>
<fruits>
<fruit color="red">Apple</fruit>
    <fruit color="orange">Orange</fruit>
    <fruit color="green">Pear</fruit>
    <fruit color="red">Watermelon</fruit>
</fruits>
<vegetables>
    <vegetable color="red">Tomato</vegetable>
    <vegetable color="brown">Potato</vegetable>
    <vegetable color="green">Broccoli</vegetable>
</vegetables>
</foodgroup>;
trace(example..*.(hasOwnProperty("@color") && @color == "red"));
/*
hasOwnProperty所做的检测是确保元素具有color属性,然后,有的话,就测试color属性之值是否为red.只有当条件的计算结果为true时,该元素才会加入EX4运算式所返回的XMLList.
输出
<fruit color="red">Apple</fruit>
<fruit color="red">Watermelon</fruit>
<vegetable color="red">Tomato</vegetable>
*/
【CDATA(Character Data)标签】
<![CDATA[]]>,必须大写.如果<![CDATA[[]]]>这样的话,它会告诉你语法错误的.
【一些名词】
RPC:
全称: Remote Procedure Call,台湾的朋友称其为: 远端程序呼叫
SOAP:
全称: Simple Object Access Protocol,台湾的朋友称其为: 简单物体存取协定
WSDL:
全称: Web Service Description Language,台湾的朋友称其为: web service描述语言

posted @ 2008-03-29 13:41  有容乃大  阅读(1803)  评论(0编辑  收藏  举报