如今的web開(kāi)發(fā)也需要越來(lái)越接近MVC框架模式,web的前端可視為由結(jié)構(gòu)+表現(xiàn)+行為組成,根據(jù)W3C的標(biāo)準(zhǔn),使用xhtml+css已經(jīng)使得結(jié)構(gòu)和表現(xiàn)成功分離。在網(wǎng)上看到越來(lái)越多被重構(gòu)過(guò)的網(wǎng)站是件非常令人欣喜的事情,如果現(xiàn)在要讓我再做一個(gè)表格布局的網(wǎng)頁(yè),當(dāng)我看到那一堆可以被一句CSS代替的表格代碼時(shí),我甚至?xí)盒牡较胪拢?biāo)準(zhǔn)給掙扎在混沌的淤泥里的我們帶來(lái)了清新空氣,良好重構(gòu)過(guò)的頁(yè)面也像出淤泥而不染的清蓮,香馨沁人心脾!那么下一步就應(yīng)該是結(jié)構(gòu)和行為的分離了,因?yàn)楸憩F(xiàn)和行為本來(lái)是不相關(guān)的,就算微軟的瀏覽器標(biāo)準(zhǔn)支持一個(gè)我當(dāng)時(shí)非常喜歡的css里的behavior,但現(xiàn)在看來(lái)表現(xiàn)依然不能包括行為,不應(yīng)該去代替行為行事。在這個(gè)三角形里,結(jié)構(gòu)可以說(shuō)是重點(diǎn),表現(xiàn)依賴于結(jié)構(gòu),行為也依賴于結(jié)構(gòu),表現(xiàn)和行為的聯(lián)系相對(duì)較少(除了一些特效操作),表現(xiàn)是被結(jié)構(gòu)導(dǎo)入的,于是開(kāi)始思考,行為是否也可以完全由外部導(dǎo)入,在結(jié)構(gòu)即html頁(yè)面里完全看不到一句javascript代碼?
經(jīng)過(guò)本人一番研究,至少一半左右簡(jiǎn)單應(yīng)用的行為是可以分離開(kāi)的。為什么說(shuō)是一半呢,由于通過(guò)對(duì)對(duì)象定義的事件函數(shù)還存在參數(shù)傳遞的一些問(wèn)題,但繞過(guò)這個(gè)障礙實(shí)施全部應(yīng)用的可行性正在研究中,而且態(tài)勢(shì)也在逐漸明朗,將在下文提及。所以答案是肯定的——結(jié)構(gòu)(html)與行為(javascript)可以實(shí)現(xiàn)分離!
下面來(lái)看分離面臨的核心問(wèn)題,一個(gè)我的實(shí)例(為方便調(diào)試,js代碼仍寫(xiě)在script標(biāo)簽里,但其他任何body里的對(duì)象都不再添加js代碼):
運(yùn)行代碼框
[Ctrl+A 全部選擇 提示:你可先修改部分代碼,再按運(yùn)行]
函數(shù)initBehavior()的作用就是建立一個(gè)操作序列,為每個(gè)html文檔結(jié)構(gòu)中需要使用行為的對(duì)象進(jìn)行事件觸發(fā)與相應(yīng)操作處理函數(shù)的連接,即生成行為。如例子中對(duì)id為holder的div元素添加的onclick事件函數(shù),同理也可以添加onmouseover,onmouseout……等事件。于是我們分離的第一步完成了,這一步要做的就是重復(fù)initBehavior函數(shù)里面的內(nèi)容,添加其他觸發(fā)事件。
接下來(lái)要做的就是具體實(shí)現(xiàn)每個(gè)觸發(fā)函數(shù)了,如上例showNode()函數(shù),問(wèn)題的核心也就在這里,因?yàn)槎x的是事件處理入口,函數(shù)中沒(méi)辦法在定義事件的時(shí)候就確定參數(shù),于是參數(shù)表就隱式被傳遞了。為什么說(shuō)有參數(shù)表,這也是在查閱了網(wǎng)上一些資料才知道的,每個(gè)函數(shù)也是一個(gè)對(duì)象,函數(shù)對(duì)象就有一個(gè)屬性是arguments:Array(),而當(dāng)函數(shù)被調(diào)用時(shí),參數(shù)都是arguments里的元素,這個(gè)大家可以另外做測(cè)試。要說(shuō)的是,不同的瀏覽器在這里有一點(diǎn)小小的區(qū)別,對(duì)于IE,每當(dāng)一個(gè)事件被觸發(fā)時(shí)他的一個(gè)全局對(duì)象window.event就會(huì)接收到信息,在處理函數(shù)的參數(shù)表里并沒(méi)有體現(xiàn)。而FF則不同,一個(gè)事件觸發(fā)時(shí),則與這個(gè)事件連接的處理函數(shù)會(huì)帶有一個(gè)默認(rèn)的事件參數(shù),作為參數(shù)表里的第一個(gè)參數(shù)傳遞給處理函數(shù),這里參數(shù)表就派上用場(chǎng)了,看上面的程序,由于函數(shù)沒(méi)有定義形參,IE解析的參數(shù)表里面是空的,所以函數(shù)里定義的evt得到的是event的引用,F(xiàn)F則因?yàn)槭录鳛榈谝粋(gè)參數(shù)表里的元素也得到一個(gè)事件對(duì)象。下一句也就容易理解了,對(duì)于不同瀏覽器,F(xiàn)F的事件來(lái)源屬性是target,IE的是srcElement,那么到這里就通過(guò)解析得到事件來(lái)源對(duì)象,也就可以對(duì)這個(gè)對(duì)象進(jìn)行相關(guān)操作了,那么本來(lái)需要從函數(shù)傳遞過(guò)來(lái)的對(duì)象參數(shù)也就不必要了。這里說(shuō)到上面提到的一個(gè)不允許傳遞參數(shù)的機(jī)制,這個(gè)是在flash的ActionScript里也碰到的,仔細(xì)思考了一下,似乎明白了設(shè)置這個(gè)機(jī)制的道理,因?yàn)楫?dāng)一個(gè)事件觸發(fā)函數(shù)時(shí),其實(shí)需要傳遞的參數(shù)都是在外部暫時(shí)靜態(tài)存在的,那么直接在函數(shù)里調(diào)用外部的對(duì)象或其他數(shù)據(jù),也就完成了需求。
說(shuō)是完成了,但心里總是隱隱約約覺(jué)得不妥,好象還是不完美,不過(guò)到這已經(jīng)足夠了,我們的目的是結(jié)構(gòu)與行為的分離,那么已經(jīng)實(shí)現(xiàn)了,收工大吉!
經(jīng)典論壇討論: http://bbs.blueidea.com/thread-2701872-1-3.html
出處:藍(lán)色理想
責(zé)任編輯:moby
◎進(jìn)入論壇網(wǎng)頁(yè)制作、網(wǎng)站綜合版塊參加討論
|