通過(guò)上節(jié)對(duì)FlahsMX組件的衍生過(guò)程的熟悉,相信我們對(duì)于創(chuàng)建屬于自己的用戶組件會(huì)有一定的前期認(rèn)識(shí)。當(dāng)然,上節(jié)的內(nèi)容只是奠定組件編寫(xiě)的總體思維方式,而真正的組件創(chuàng)作過(guò)程并沒(méi)展開(kāi)。在本章內(nèi)我們將帶領(lǐng)大家一起探索用戶組件創(chuàng)建的神秘歷程。
1 創(chuàng)建組件相關(guān)的重要指令
組件的創(chuàng)建絕不同于構(gòu)建一個(gè)簡(jiǎn)單的功能函數(shù),也不同于制作一個(gè)相似功能的Smart Clip,由于FlashMX Components的創(chuàng)建引入了許許多多新的全新概念,因而也隨之引入了一些全新的賦予新的作用與含義的函數(shù)與方法等操作指令,如自定義組件的函數(shù)#initclip #endinitclip和方法Object.registerClass()、addProperty()。由此,我們?cè)谡窖?qǐng)大家編寫(xiě)用戶組件之前想請(qǐng)大家再一起來(lái)了解與熟悉一下這些關(guān)鍵的指令。
#initclip
適用版本:Flash Player 6.
語(yǔ)法:#initclip order
參數(shù):order 整數(shù),指定#initclip代碼塊的執(zhí)行次序,可選。
說(shuō)明:
該指令表示一組Component初始化動(dòng)作的開(kāi)始。在同時(shí)初始化多個(gè)MC時(shí),可以使用參數(shù)order來(lái)指定初始化優(yōu)先次序。Component初始化動(dòng)作在相應(yīng)MC組件已定義時(shí)才執(zhí)行。若該MC屬于輸出影片類型,Component初始化動(dòng)作就在該SWF文件第一楨上的動(dòng)作之前執(zhí)行。否則,Component初始化動(dòng)作就在包含相關(guān)MC組件第一個(gè)實(shí)例的那一楨上的動(dòng)作執(zhí)行之前執(zhí)行。
影片播放中component初始化動(dòng)作僅僅執(zhí)行一次,用于一次性初始化,比如類的定義與注冊(cè)。
#endinitclip
適用版本:Flash Player 6.
語(yǔ)法:#endinitclip
參數(shù):無(wú)
說(shuō)明:
與#initclip一起配對(duì)使用,組件的初始化過(guò)程以#initclip開(kāi)始以#endinitclips出現(xiàn)為結(jié)束。
Object.registerClass
適用版本:Flash Player 6
用法:
Object.registerClass(symbolID, theClass)
參數(shù):
symbolID:影片剪輯元件的鏈接標(biāo)識(shí)符,或動(dòng)作腳本類的字符串標(biāo)識(shí)符。
theClass:指向動(dòng)作腳本類的構(gòu)造函數(shù)的引用,或?yàn)?null,則不注冊(cè)元件。
返回值:
如果類注冊(cè)成功,則返回值為 true;否則,返回 false。
說(shuō)明:
方法:將影片剪輯元件與動(dòng)作腳本對(duì)象類相關(guān)聯(lián)。如果元件不存在,則Flash在字符串標(biāo)識(shí)符和對(duì)象類之間創(chuàng)建關(guān)聯(lián)關(guān)系。
時(shí)間軸放置指定影片剪輯元件的實(shí)例時(shí),該實(shí)例注冊(cè)到由theClass參數(shù)指定的類,而不是注冊(cè)到MovieClip類。
使用attachMovie或duplicateMovieClip方法創(chuàng)建指定影片剪輯元件的實(shí)例時(shí),該實(shí)例注冊(cè)到由stheClass參數(shù)指定的類,而不是注冊(cè)到MovieClip類。
如果theClass為null,則sObject.registerClass 刪除任何與指定影片剪輯元件或類標(biāo)識(shí)符相關(guān)聯(lián)的動(dòng)作腳本類定義。對(duì)于影片剪輯元件,該影片剪輯的任何現(xiàn)有實(shí)例保持不變,但此元件的新實(shí)例將與默認(rèn)類MovieClip 相關(guān)聯(lián)。
如果元件已經(jīng)注冊(cè)到某類,則Object.registerClass方法將使用新的注冊(cè)替換現(xiàn)有的注冊(cè)。
影片剪輯實(shí)例被時(shí)間軸放置或通過(guò)attachMovie或duplicateMovieClip創(chuàng)建時(shí),動(dòng)作腳本使用指向此對(duì)象的關(guān)鍵字this調(diào)用適當(dāng)類的構(gòu)造函數(shù)。此構(gòu)造函數(shù)在調(diào)用時(shí)不帶有參數(shù)。
如果使用Object.registerClass方法將影片剪輯注冊(cè)到動(dòng)作腳本類而不是MovieClip類,則該影片剪輯元件不繼承內(nèi)置MovieClip類的方法、屬性和事件,除非將MovieClip類包括在新類的原型鏈中。下面的代碼新建一個(gè)名為theClass的ActionScript類,它繼承了MovieClip類的屬性:
theClass.prototype = new MovieClip();
Object.addProperty
適用版本:Flash Player 6.
使用方法:myObject.addProperty( prop, getFunc, setFunc )
參數(shù):prop
創(chuàng)建的屬性名稱
getFunc
此參數(shù)是一個(gè)函數(shù)對(duì)象,而此函數(shù)起調(diào)用獲取屬性值的功能
setFunc
此參數(shù)也是一個(gè)函數(shù)對(duì)象,而與getFunc的參數(shù)函數(shù)相對(duì),此處的函數(shù)功能是設(shè)置屬性的功能。假若此參數(shù)設(shè)置為null,那么屬性將被設(shè)置為只讀。
返回值:
返回一個(gè)布爾值,如果一個(gè)屬性被創(chuàng)建則返回True,反之則為False。
說(shuō)明:
方法:創(chuàng)建一個(gè)獲得/設(shè)置的屬性。當(dāng)Flash讀取獲得/設(shè)置屬性,它將調(diào)用相應(yīng)的獲取函數(shù)并且將返回值傳遞為一個(gè)屬性值,而當(dāng)Flash在寫(xiě)一個(gè)獲得/設(shè)置屬值的時(shí)候,它將調(diào)用相應(yīng)的設(shè)置函數(shù),并且將它的新值作為一個(gè)參數(shù)來(lái)應(yīng)用。如果一個(gè)被命名的屬性已經(jīng)存在,那么新的屬性將覆蓋原來(lái)舊的屬性。
獲取函數(shù)是一個(gè)無(wú)參數(shù)的函數(shù),它所返回的值可以是任何的類型,它返回的值將作為屬性的當(dāng)前值來(lái)對(duì)待。
設(shè)置函數(shù)只附帶了一個(gè)參數(shù),而次參數(shù)是將作為新的屬性值的。舉個(gè)實(shí)例來(lái)說(shuō)明,如果一個(gè)屬性值x已經(jīng)被x=1所聲明,那么設(shè)置函數(shù)將認(rèn)識(shí)此參數(shù)并將它作為一個(gè)數(shù)字類型對(duì)待,而設(shè)置函數(shù)返回的值將被忽略。
你能增加一個(gè)獲取/設(shè)置屬性到原型對(duì)象中。如果你添加了一個(gè)獲取/設(shè)置屬性到一個(gè)原型對(duì)象,那么場(chǎng)景中所有繼承于該原型對(duì)象的對(duì)象將繼承這個(gè)獲取/設(shè)置的屬性。因而,這就造就了一種可能,相信我們能夠添加獲取/設(shè)置屬到到一個(gè)特定的區(qū)域中,即該原型函數(shù),而它將會(huì)傳播于場(chǎng)景中該實(shí)化的所有的類(就像添加事件到該原型對(duì)象一樣)。如果一個(gè)獲取/設(shè)置函數(shù)中一個(gè)繼承的原型對(duì)象中調(diào)用獲取/設(shè)置屬性,那么參數(shù)傳遞給獲取/設(shè)置函數(shù)的將是最先的對(duì)象參數(shù),而不是繼承的原型對(duì)象的。如果調(diào)用錯(cuò)誤,addProperty對(duì)象將會(huì)導(dǎo)致一個(gè)錯(cuò)誤。
setInterval
適用版本:
Flash Player 6.
使用方法:
setInterval( function,interval[,arg1, arg2, ...,argn] )
setInterval(object, methodName,interval[,arg1,arg2, ..., argn] )
參數(shù):
function
命名或指向一個(gè)匿名函數(shù)的函數(shù)
object
來(lái)源于Object對(duì)象的對(duì)象
methodName
調(diào)用對(duì)象參數(shù)的事件名稱
interval
調(diào)用函數(shù)或事件名稱的參數(shù)之間相隔的毫秒數(shù)。
arg1, arg2, ..., argn
可選參數(shù)用以傳遞函數(shù)或事件的參數(shù)。
返回值:
一個(gè)時(shí)間間隔標(biāo)識(shí)標(biāo),你能通過(guò)clearInterval命令用以清除該時(shí)間間隔。
說(shuō)明:
命令:
調(diào)用一個(gè)函數(shù)或事件或?qū)ο?,?dāng)影片運(yùn)行時(shí)定時(shí)的觸發(fā)。你能運(yùn)用時(shí)間間隔函數(shù)從數(shù)據(jù)庫(kù)中來(lái)保存該變量或是更新時(shí)間顯示。
如果interval小于影片幀的播放率(如:10幀每秒(fps)等于100毫秒),那么interval函數(shù)就很有可能將interval關(guān)閉。你必須用updateAfterEvent函數(shù)確定該屏幕播放有足夠充分時(shí)間。如果interval大于影片幀的播放率,那么interval函數(shù)只是在每個(gè)幀的前面影片部分調(diào)用以使得每次屏幕刷新之時(shí)保持最小的影響。
上述第一種setInterval函數(shù)的語(yǔ)法示例在Action面板中是以正常模式為默認(rèn)值的,而第二種語(yǔ)法示例,你必須運(yùn)用專家Action面板進(jìn)行操作。
clearInterval
適用版本:
Flash Player 6.
使用方法:
clearInterval( intervalID )
參數(shù):
intervalID
通過(guò)setInterval函數(shù)返回的一個(gè)標(biāo)識(shí)標(biāo)。
返回值:無(wú)
說(shuō)明:
清除一個(gè)setInterval函數(shù)調(diào)用。
Key.addListener
適用版本:Flash Player 6.
使用方法:Key.addListener (newListener)
參數(shù):newListener
當(dāng)按下釋放鍵盤(pán)控制后返回的一個(gè)對(duì)象事件上。
返回值:無(wú)
說(shuō)明:
事件:注冊(cè)一個(gè)對(duì)象用以接受鍵盤(pán)按下釋放后的反應(yīng)。當(dāng)一個(gè)鍵盤(pán)按鈕按下或是釋放,不管是否有輸入焦點(diǎn),所有用addListener注冊(cè)過(guò)的onKeyDown事件或是onKeyUp事件都將會(huì)被觸發(fā)。多個(gè)對(duì)象也能監(jiān)聽(tīng)鍵盤(pán)控制。如果監(jiān)聽(tīng)者newListener早被注冊(cè)過(guò),那么將不會(huì)產(chǎn)生任何反映。
instanceof
應(yīng)用版本:Flash Player 6.
使用方法:object instanceof class
參數(shù):object
一個(gè)ActionScript對(duì)象
class
ActionScript構(gòu)造器函數(shù)類型,如String或是Date等類型。
返回值:
如果一個(gè)對(duì)象是指定的某種場(chǎng)景類,instanceof返回值為true,否則返回值為false。
說(shuō)明:
操作:確定一個(gè)對(duì)象是否屬于一種特殊的類,測(cè)試該對(duì)象為某種類型。
Instanceof操作不能將原始類型轉(zhuǎn)化為封裝類型,例如,下面的代碼將返回true值:
new String("Hello") instanceof String
而下面的代碼將返回false值:
"Hello" instanceof String
現(xiàn)在我們?cè)賹?duì)上述的這些指令作以簡(jiǎn)單綜述:
#initclip與#endinitclip是一對(duì)成對(duì)出現(xiàn)的指令,主要功能是在影片關(guān)鍵幀等內(nèi)容未曾載入調(diào)用前對(duì)組件進(jìn)行一定的初始化定義描述及操作;
Object.addProperty是添加一個(gè)對(duì)象的屬性,這有便于我們?yōu)橛脩艚M件創(chuàng)建一些屬于自己的對(duì)象屬性。
SetInterval與clearInterval基本也是成對(duì)出現(xiàn)的指令,如果對(duì)于這兩個(gè)指令在剛開(kāi)始階段比較難以理解,或許大家可以把它們與VB或是Delphi中的timer控件的作用作以類比,其它說(shuō)到底,它們起到了一個(gè)“定時(shí)觸發(fā)”的時(shí)間控制作用而已。
addListener對(duì)象監(jiān)聽(tīng)的指令,我們不僅可以監(jiān)聽(tīng)鍵盤(pán)對(duì)象,還可以監(jiān)聽(tīng)鼠標(biāo)、場(chǎng)景、文本框等等對(duì)象的內(nèi)容,由此我們?cè)谟脩艚M件的創(chuàng)作過(guò)程中此指令就可以大大改善用戶體驗(yàn),增加組件與用戶之間的溝通。
Instanceof判斷一個(gè)對(duì)象是否屬于某一種特定的類型。
2 構(gòu)建自己第一個(gè)用戶組件
相信各位對(duì)前面利用“功能函數(shù)”創(chuàng)建的一個(gè)MovieClip的提示信息實(shí)例仍記憶猶新,而到了現(xiàn)在我們對(duì)組件的編程基本原理已經(jīng)有了一定的認(rèn)識(shí)的基礎(chǔ)上,那么對(duì)于類似的問(wèn)題,我們?nèi)缬肍lashMX組件的方式又該作以如何思考呢?那就請(qǐng)諸位跟隨我們?cè)俅芜M(jìn)行一次提煉精華的操作過(guò)程吧。
類似于我們已經(jīng)作以詳細(xì)介紹的FlashMX內(nèi)置組件及擴(kuò)展使用一般,我們欲求此次制作的組件也能從Library中直接拖放至場(chǎng)景中,并且要求該組件能夠自動(dòng)粘附到相應(yīng)的場(chǎng)景對(duì)象上,如果場(chǎng)景對(duì)象是MovieClip,那么我們可以通過(guò)Parameters面板進(jìn)行樣式選擇,并通過(guò)輸入相應(yīng)的提示信息以后進(jìn)行影片測(cè)試時(shí)便可達(dá)到我們欲求的理想效果。
從上述的制作要求中我們大概歸納了幾點(diǎn)精華:
其一,具有組件的外觀樣式;
其二,粘附場(chǎng)景對(duì)象,并判斷是否為MovieClip類型的場(chǎng)景對(duì)象內(nèi)容;
其三,樣式的選擇,可以按照所需選擇指定的不同的樣式,從而讓提示信息在不同的情況要求下顯示不同的樣式外觀;
其四,提示信息顯示,當(dāng)然,這些提示信息的樣式得根據(jù)第三部分內(nèi)容的更改而改變。
整理完畢上述內(nèi)容,我們就可以著手開(kāi)始落實(shí)我們第一個(gè)簡(jiǎn)單的自定義用戶組件ToolTip了。
如同制作Smart Clip一般,我們?cè)诘谝徊蕉x了一個(gè)MovieClip(如圖64所示),當(dāng)然還會(huì)為它添置一些參數(shù)以備后用(如圖65所示)。
圖64 ToolTip的MovieClip
圖65 ToolTip(MovieClip)的Component Definition參數(shù)設(shè)置
根據(jù)需求分析所得,我們可根據(jù)圖65所示進(jìn)行參數(shù)設(shè)置,在此我們?cè)O(shè)置了三個(gè)Style,三個(gè)Style Text及一個(gè)Target Name,它們分別針對(duì)的內(nèi)容是三種不同的樣式格式,針對(duì)不同樣式格式的提示內(nèi)容及將ToolTip鎖定的場(chǎng)景對(duì)象范圍。
當(dāng)我們?cè)O(shè)置完參數(shù)定義后,返回Library查看類庫(kù)內(nèi)容,原本ToolTip的MovieClip圖標(biāo)樣式就已被更換成的組件圖標(biāo)顯示樣式了,這主要是為了更容易區(qū)別普通MovieClip與組件內(nèi)容。
然后我們?cè)贚ibrary中建立一個(gè)文件包,并在該文件包內(nèi)創(chuàng)建三個(gè)MovieClip(提示信息外觀樣式MovieClip),它們分別為styleToolTip_1、styleToolTip_2、styleToolTip_3,如下圖66所示。
圖66 StyleToolTip(MovieClip)樣式
其實(shí)三種樣式的制作過(guò)程都基本雷同,我們?cè)诖酥粚?duì)styleToolTip_1的場(chǎng)景內(nèi)容稍作分析。如下圖67所示,在樣式一中我們建立了三個(gè)層次的內(nèi)容,TxtField層包括了一個(gè)文本框(以后將在此文本框內(nèi)顯示提示信息),TipBox層是樣式外框顯示樣式,而shdw層是樣式外框顯示樣式的陰影效果。其實(shí)場(chǎng)景中物件并不煩多,而樣式二與樣式三與樣式一的制作過(guò)程也是一致,只是在TxtField顯示的提示信息量及樣式外框顯示樣式的樣式上略有區(qū)別而已。
圖67 StyleToolTip_1場(chǎng)景內(nèi)容
圖68 樣式二及樣式三的場(chǎng)景內(nèi)容
在這里我們需要進(jìn)行屬性設(shè)置的是txtField層中的文本內(nèi)容,它的設(shè)置如下圖69所示,我們將它設(shè)置為Dynamic Text類型,而將其變量Var定義為style(注意:前面已經(jīng)有所敘述,樣式二與樣式三的內(nèi)容只是文本提示信息量上的區(qū)別,而Var定義的值三個(gè)樣式中的文本框需均為style)。
圖69 提示信息文本框?qū)傩远x
做好了前期準(zhǔn)備工作我們?cè)賮?lái)查看一下主角的內(nèi)容情況,如下圖70所示,我們的ToolTip(MovieClip)的場(chǎng)景內(nèi)容包括了二層內(nèi)容,一層為ActionSctip,而另一層則是Icon(注:其實(shí)該層內(nèi)容的存在主要是為了對(duì)該ToolTip組件有一個(gè)外觀樣式顯示而已,在該組件中假若去除此層Icon的內(nèi)容并不會(huì)對(duì)最終的影片測(cè)試效果產(chǎn)生任何影響,最多只是在設(shè)計(jì)階段組件的樣式顯示會(huì)有所不同而已)。
圖70 ToolTip場(chǎng)景內(nèi)容
到此我們已經(jīng)基本完成了該組件實(shí)例的制作過(guò)程,我們只運(yùn)用了與“功能函數(shù)”差不多的代碼行就解決雷同的問(wèn)題,而一個(gè)則是面向開(kāi)發(fā)人員用戶,另一個(gè)則將會(huì)面對(duì)普通設(shè)計(jì)級(jí)用戶群。
“實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn)”,為了驗(yàn)證該組件是否能夠正常運(yùn)行,我們將用剛才編寫(xiě)完畢的組件制作一實(shí)例,查看它的運(yùn)行效果以便作最終判斷。
由于我們?cè)诖a中已用this.myTarget instanceof MovieClip作以判斷所需的提示信息對(duì)象應(yīng)該是MovieClip類型,因而我們創(chuàng)建了一個(gè)內(nèi)容為正圓的MovieClip(myTextMovieClip)。
我們拖動(dòng)myTestMovieClip 到場(chǎng)景中,并復(fù)制2個(gè)該對(duì)象(由于我們制作了三種提示信息樣式,因而我們將制作三種不同的提示信息樣式顯示),如下圖73所示:
圖73 制作自定義組件ToolTip實(shí)例的MovieClip準(zhǔn)備
我們先點(diǎn)擊選中Tools工具欄中的磁性工具,然后從Library中拖動(dòng)ToolTip組件到場(chǎng)景中的TestMovieClip之上,如圖74所示:
圖74 拖動(dòng)ToolTip組件到myTestMovieClip上
由于我們選中了磁性工具,因而我們?cè)诜胖肨oolTip組件到myTestMovieClip影片上時(shí)會(huì)有粘縛的功效哦。
在此我們可能會(huì)回想起前面ToolTip場(chǎng)景的內(nèi)容,圖74中ToolTip已顯示為一提示信息樣式的圖標(biāo),而我們?cè)?jīng)提及,如果將ToolTip場(chǎng)景中的那層圖標(biāo)樣式刪除,對(duì)于ToolTip運(yùn)后最終的效果并不會(huì)產(chǎn)生什么不良影響,只會(huì)在設(shè)計(jì)階段產(chǎn)生稍許不同而已,比較圖74與圖75查看結(jié)果。
圖75 刪除ToolTip中Icon以后ToolTip在實(shí)例運(yùn)用中樣式
比較結(jié)果十分明顯,就直觀性來(lái)說(shuō)圖74所示樣式要比圖75直觀的多,我們一眼即可辨別那些場(chǎng)景對(duì)象是ToolTip,而至于刪除Icon層內(nèi)容以后的ToolTip在運(yùn)用過(guò)程中我們甚至?xí)鎰e不清楚那到底是否是ToolTip組件,因而我們前面在ToolTip組件中加入了Icon層并非多余而是十分關(guān)鍵與必要的,這極大的增加了用戶體驗(yàn)。
組件自動(dòng)粘縛場(chǎng)景中的MovieClip對(duì)象以后,組件的Target Name屬性將在原先this.myTarget = this._parent[this._targetInstanceName]; 代碼地操作下會(huì)自動(dòng)獲取該對(duì)象的實(shí)體名稱。當(dāng)然,如果我們直接將myTestMovieClip拖放至場(chǎng)景而未對(duì)場(chǎng)景中的實(shí)體進(jìn)行實(shí)體名定義,則系統(tǒng)會(huì)自動(dòng)按順序給對(duì)象添加上InstanceName_0、InstanceName_1等等,如下圖76所示:
圖76 ToolTip組件Target Name的自動(dòng)獲取
我們選擇場(chǎng)景中某一ToolTip組件后再調(diào)出對(duì)象屬性設(shè)置面板可查看到Parameters參數(shù)面板中除了Target Name外還有Style 1 row、Style 2 row、Style 3 row等參數(shù)設(shè)置項(xiàng)(Style參數(shù)設(shè)置項(xiàng)的功能主要是確定提示信息顯示的樣式類型)。我們可以設(shè)定某一樣式為True來(lái)使該組件運(yùn)用此樣式進(jìn)行提示信息顯示(選擇Style 1 row將選擇styleToolTip_1類型的提示信息樣式,以此類推),不過(guò)需注意,我們只能設(shè)置這些樣式參數(shù)中的一項(xiàng)內(nèi)容為True,不可進(jìn)行多選(具體原因詳見(jiàn)對(duì)handleSelected函數(shù)相關(guān)解釋)。
圖77 ToolTip組件Style樣式設(shè)置
與Style 1 row等相對(duì)應(yīng)的當(dāng)然是提示文本內(nèi)容了,因而我們?cè)赑arameters參數(shù)面板中還可以查看到Style 1 Text、Style 2 Text、Style 3 Text等參數(shù)設(shè)置,如下圖78所示。
圖78 ToolTip組件Text內(nèi)容設(shè)置
我們需要注意的是,Text與row應(yīng)該是成對(duì)選擇的,由于我們?cè)趆andleSelected函數(shù)中利用遍歷的方法進(jìn)行控制并設(shè)置相應(yīng)的變量,因而在那時(shí)我們已經(jīng)將row與Text構(gòu)成了成對(duì)使用的參數(shù)對(duì),由于前面我們已經(jīng)將Style 1 row參數(shù)項(xiàng)設(shè)置為True,因而在Text參數(shù)設(shè)置中我們只能對(duì)Style 1 Text參數(shù)項(xiàng)進(jìn)行提示信息文本輸入設(shè)置,倘若我們嘗試將文本設(shè)置到其它的文本參數(shù)框內(nèi),那么最組件的測(cè)試效果并不會(huì)是我們預(yù)期所想的。
當(dāng)我們將上述實(shí)例中組件對(duì)象的參數(shù)設(shè)置完畢以后按下Ctrl+Enter進(jìn)行影片測(cè)試,我們就可以查看此番辛苦的杰作了,如下圖79及圖80所示。
圖79 鼠標(biāo)未移至ToolTip組件提示信息對(duì)象
圖80 鼠標(biāo)移至ToolTip組件提示信息對(duì)象上的顯示