DHTML應(yīng)用開(kāi)發(fā)

          本文介紹了IE和Navigator兩種瀏覽器對(duì)DHTML標(biāo)準(zhǔn)實(shí)現(xiàn)的差異,特別是如何編寫(xiě)Navigator中運(yùn)行的DHTML程序。


            DHTML(Dynamic HTML)是W3C組織提出的一種新的規(guī)范,它對(duì)原有的HTML做了許多擴(kuò)充,并結(jié)合Javascript,使得靜態(tài)的HTML頁(yè)面產(chǎn)生了許多動(dòng)態(tài)效果, 例如菜單的展開(kāi)和收起,頁(yè)面元素的外觀動(dòng)態(tài)改變等。IE 4.0以上,Navigator 4.0以上的版本都支持這個(gè)標(biāo)準(zhǔn)。但是,不同的瀏覽器廠家對(duì)它都做了不同程度的擴(kuò)充。以最流行IE的和NS為例,IE的實(shí)現(xiàn)更接近于W3C的方案,而 NS,說(shuō)實(shí)話,與W3C的方案差異很大,而且并沒(méi)有完全實(shí)現(xiàn),甚至可以說(shuō)是另一套方案。筆者在初識(shí)DHTML時(shí),按照書(shū)上講的編寫(xiě)了幾個(gè)小程序,在IE上 一試就通,而在NS上可以說(shuō)費(fèi)盡了周折才逐漸找到解決方案。由于市面上很少有講述NS的DHTML實(shí)現(xiàn)方案的書(shū)(大概NS由于的實(shí)現(xiàn)不符合標(biāo)準(zhǔn)),而真正 的商業(yè)網(wǎng)站至少應(yīng)同時(shí)支持IE和NS這兩種主要的瀏覽器,我愿意把我的一些心得寫(xiě)出來(lái)與大家共享,使大家不必再走我走過(guò)的彎路。對(duì)于二者的實(shí)現(xiàn)相同的部 分,本文作一簡(jiǎn)略介紹,您若有興趣可參考有關(guān)書(shū)籍或網(wǎng)上資源。


            DHTML實(shí)際上由三兩部分組成:CSS(Cascade Style Sheet,級(jí)聯(lián)樣式表),層(Layer)和Javascript。


            所謂CSS,概念上類(lèi)似于C++中的類(lèi),在類(lèi)定義中指明元素的外觀樣式,如字體,顏色,大小等等,頁(yè)面中的任何一個(gè)HTML元素如被指定屬于 這個(gè)類(lèi),就自動(dòng)擁有該類(lèi)的特性;還可以為某種HTML元素定義樣式,這樣頁(yè)面中的所有這種元素都有了同樣的外觀。如果將這樣的樣式定義存在一個(gè)單獨(dú)的. css文件中(就象C++那樣將類(lèi)定義存在 .h文件中),再在頁(yè)面中將其包含進(jìn)來(lái),則一個(gè)網(wǎng)站的所有頁(yè)面就有了同樣的外觀。IE和NS對(duì)CSS的實(shí)現(xiàn)基本相同,在此就不再詳細(xì)介紹了。


            兩者的差異主要體現(xiàn)在層的實(shí)現(xiàn)上。所謂層,就是頁(yè)面上的一塊區(qū)域,其中可以包含任何的HTML元素,通過(guò)改變層的屬性,其間的元素可以跟著出 現(xiàn),消失,更改,移動(dòng)等。 在IE中,層依靠<DIV></DIV>和<SPAN></SPAN>來(lái)實(shí)現(xiàn),兩者基本相同,通常 <DIV>用于較大的層,<SPAN>用于較小的層,并且<DIV>在實(shí)現(xiàn)的層后面加上一個(gè)回車(chē)換行,而< SPAN>不加。它的語(yǔ)法如下(二者相同):


            <div id=layername style="style definition">Layer content</div> 或


            <div id=layername class="classname">Layer content</div>


            其中style definition是一組有分號(hào)隔開(kāi)的樣式定義,常用的有以下幾種:


            position:其值可以為absolute和relative,所謂absolute(絕對(duì)定位),就是層的內(nèi)容不必按照出現(xiàn)的先后次序 在瀏覽器上依次排列,而是可以像素為單位定位到瀏覽器用戶(hù)區(qū)域的任意位置;而relative(相對(duì)定位)則是層按照相鄰的內(nèi)容依次排列。


            left,top,width,height:指層的左上角坐標(biāo)以及它的寬度和高度。


            z-index:由于層可以被放置在頁(yè)面的任何位置,當(dāng)它與其它內(nèi)容重合時(shí),z-index值大的顯示在上面,所有層的z-index值為 1。但是在NS中,所有的表單元素(文本框,列表框,按鈕等),只要是可見(jiàn)的就無(wú)法被遮住,而無(wú)論z-index值是多少。因此在設(shè)計(jì)頁(yè)面時(shí),要注意不要 使動(dòng)態(tài)出現(xiàn)或隱藏的元素(例如彈出式菜單)的位置上放置表單元素。


            Visibility:指明層是否可見(jiàn),通過(guò)在程序中動(dòng)態(tài)改變這個(gè)值,可以實(shí)現(xiàn)層的出現(xiàn)和消失,比如下拉菜單就要依靠它來(lái)實(shí)現(xiàn)。它的三個(gè)候選 值為:inherit,可見(jiàn)性與父元素的可見(jiàn)性相同;visible,可見(jiàn)(在NS中是show);hidden,不可見(jiàn)(在NS中是hide)。


            NS同樣支持這兩個(gè)標(biāo)記,但是支持得很不好,經(jīng)常出現(xiàn)一些莫名其妙的錯(cuò)誤,我想這可能是出于策略上的考慮,而不見(jiàn)得是NS的產(chǎn)品質(zhì)量不好。 NS引入了另兩個(gè)標(biāo)記,<layer>和<ilayer>,<layer>用于絕對(duì)定位,< ilayer>用于相對(duì)定位,因此在這兩個(gè)標(biāo)記的樣式定義中沒(méi)有position屬性。


            兩個(gè)瀏覽器對(duì)層的不同實(shí)現(xiàn)體現(xiàn)在以下幾點(diǎn):


            1. 層的引用。在IE中,頁(yè)面上的每個(gè)可編程元素(不僅是層,還包括其它任何指明了ID值的元素,詳見(jiàn)下文)都是document.all集合的一項(xiàng);而在 NS中,頁(yè)面中每個(gè)層,無(wú)論是用上面四個(gè)標(biāo)記中的哪個(gè)定義的,也無(wú)論是絕對(duì)或是相對(duì)定位,都是document.layers集合的一項(xiàng)。因此,若想引用 名為layer1的層,應(yīng)以如下語(yǔ)法:


            IE:document.all["layer1"]或document.all.layer1


            NS:document.layers["layer1"]或document.layers.layer1


            2. 層的坐標(biāo)和大小。在IE中,每個(gè)涉及層的外觀的屬性,如位置,大小,顏色等,都是層的style屬性集合的以一項(xiàng),如層的左上角x坐標(biāo)為 document.all.layer1.style.pixelLeft,y坐標(biāo)為 document.all.layer1.style.pixelTop,寬度為 document.all.layer1.style.pixelWidth,高度為 document.all.layer1.style.pixelHeight。還有幾組屬性如scrollxxx,offsetxxx, clientxxx,其中xxx為L(zhǎng)eft,Top,Width,Height ,分別描述層的滾動(dòng),位移,客戶(hù)區(qū)等屬性,詳見(jiàn)MSDN中關(guān)于坐標(biāo)的描述。而在NS中,每個(gè)層都有一個(gè)clip屬性集,x,y,width,height 是這個(gè)集的集合元素。


            另外,IE中所有元素?fù)碛型粋€(gè)坐標(biāo)系,無(wú)論它位于層外或?qū)觾?nèi);在NS中,每個(gè)層都有一個(gè)獨(dú)立的坐標(biāo)系。


            3. 層的內(nèi)容。IE中的層包含innerHTML和outerHTML屬性(由于并非描述層的外觀,所以它們不是style屬性集的元素,而是層的屬性),其含義如下:


            innerHTML:層中的HTML代碼,但是不包括層的定義。


            outerHTML:層中的HTML代碼,且包括層的定義。


            改變這些屬性值就可以改變層的內(nèi)容,如下語(yǔ)句改變層layer1的內(nèi)容為加粗的字符串"layer1": document.all.layer1.innerHTML=”<b>layer1</b>” ,而在NS中,每一個(gè)document.layers集合中的元素,即一個(gè)層,都NS被視為一個(gè)獨(dú)立的窗口,有獨(dú)立document屬性,就象 Javascript中的document屬性一樣,通過(guò)調(diào)用document.write函數(shù),可以動(dòng)態(tài)改變層的內(nèi)容。上例在NS中應(yīng)修改為:


            document.layers.layer1.document.open();


            doucment.layers.layer1.write("<div><b>layer1</b></div>");


            document.layers.layer1.document.close;


            同樣,對(duì)于層中的其它可編程元素,例如圖象,其引用語(yǔ)法如下: document.layers.layer1.document.images[imgname],而如果該圖象位于層的外面,其語(yǔ)法應(yīng)為 document.images[imgname],而在IE中,無(wú)論圖象位于層內(nèi)或?qū)油?,其語(yǔ)法都是后者。


            Javascript是Netscape公司首先提出的一種客戶(hù)端編程的腳本語(yǔ)言,隨后有擴(kuò)展到服務(wù)器端。它的語(yǔ)法和概念都類(lèi)似于C++,但 是沒(méi)有C++那樣嚴(yán)格。IE同樣支持客戶(hù)端Javascript(微軟還推出了類(lèi)似的,功能更強(qiáng)大的Vbscript,但是NS卻不支持)。兩種瀏覽器對(duì) Javascript的基本實(shí)現(xiàn)是一樣的,但是又都對(duì)它做了許多不同的擴(kuò)展,而在DHTML編程中,很多情況下都需要用到這些擴(kuò)展。由于此時(shí)已經(jīng)沒(méi)有標(biāo)準(zhǔn) 可遵循,二者已經(jīng)看不出有相同之處。例如,瀏覽器的客戶(hù)區(qū)的寬度,在IE中是document.body.clientWidth,在NS中是 window.innerWidth;再比如你想知道用戶(hù)按瀏覽器的滾動(dòng)條滾動(dòng)了多少像素,在IE中是document.body.scrollTop, 在NS中是window.pageYOffset。在這種情況下,你只能查閱二者的文檔。IE的Javascript文檔包含在MSDN中,也可以到微軟 的站點(diǎn)上單獨(dú)下載。NS的Javascript文檔可以到 http://developer.netscape.com上下載,那里也能得到NS的DHTML文檔。


            NS沒(méi)有實(shí)現(xiàn)的功能。


            1.IE中,頁(yè)面中的任何元素都是可編程的,只要賦予它ID屬性,其語(yǔ)法如下:


            <div id=itemid>content</div>或<span id=itemid>content</span>


            而在NS中,除非元素位于層中,否則無(wú)法對(duì)它編程。


            2.IE中增添了元素的漸變(Transition)和濾鏡(Filter)效果,NS中沒(méi)有。


            3.IE中支持客戶(hù)端的數(shù)據(jù)綁定(Data bind),即頁(yè)面中的某個(gè)元素(例如表格中的一個(gè)格)可以與服務(wù)器端的數(shù)據(jù)庫(kù)的某個(gè)字段綁定,在數(shù)據(jù)內(nèi)容不變的情況下,可以不必再次訪問(wèn)數(shù)據(jù)庫(kù)而改變頁(yè)面的形式(例如按某個(gè)字段重新排序)。NS同樣沒(méi)有實(shí)現(xiàn)這種特性。


            以上列舉了二者的如此之多的差別,那我們?nèi)绾尉帉?xiě)跨瀏覽器的DHTML頁(yè)面呢?一種方法是編寫(xiě)兩個(gè)獨(dú)立的頁(yè)面,而在入口文件中根據(jù)瀏覽器的不同而重定向到不同的頁(yè)面,如:


            <HTML><BODY>


            <Script Language="Javascript">


            isNS=(navigator.appName=="Netscape");


            if (isNS)


             window.location="ns.html";


            else


             window.location="ie.html";


            </Script>


            </BODY></HTML>


            這種方法簡(jiǎn)單,頁(yè)面整潔,缺點(diǎn)是有很大冗余,畢竟一個(gè)頁(yè)面中程序是少量的,大部分靜態(tài)內(nèi)容在兩個(gè)瀏覽器中并沒(méi)有區(qū)別,一旦靜態(tài)的內(nèi)容發(fā)生改變必須在兩個(gè)頁(yè)面中一起更改,而且當(dāng)包含DHTML的頁(yè)面增多時(shí),每一個(gè)頁(yè)面都需要三個(gè)頁(yè)面來(lái)實(shí)現(xiàn),增大了維護(hù)的負(fù)擔(dān)。


            另一種方法是在同一個(gè)頁(yè)面中集成兩個(gè)瀏覽器的代碼。在每一個(gè)實(shí)現(xiàn)特定功能的函數(shù)中都根據(jù)瀏覽器的不同分別寫(xiě)代碼,如:


            <HTML><BODY>


            <Script Language="Javascript">


            isNS=(navigator.appName=="Netscape");


            function fun1(){


            if (isNS)


             //NS codes here


            else


             //IE codes here


            }

            </Script>

            </BODY></HTML>

            對(duì)于HTML代碼也不同的部分,可以利用Javascript函數(shù) document.writeln()來(lái)實(shí)現(xiàn),例如對(duì)于層的定義,可以如下實(shí)現(xiàn):

            <Script Language="Javascript">

             if(isNS)

             document.writeln("<layer id=\"layer1\" left=20 top=30 width=40 height=50 z-index=2>");

             else

             document.writeln("<div id=\"layer1\" style=\"position:absolute;left:20;top:30;width:40;height:50;z-index:2\">");

            </Script>

            Layer content here

            <Script Language="Javascript">

             if(isNS)

             document.writeln("</layer>");

             else

             document.writeln("</div>");


            </Script>

            這種實(shí)現(xiàn)方法維護(hù)簡(jiǎn)單,缺點(diǎn)是失去了頁(yè)面編輯器所見(jiàn)即所得的特性(因?yàn)橹挥械竭\(yùn)行時(shí)才能將層的定義寫(xiě)入瀏覽器,在編輯階段它們只是些 Javascript程序),調(diào)整層的坐標(biāo)和大小都比較困難。在實(shí)際編程中可以先按一種瀏覽器的定義寫(xiě),待調(diào)整完畢后再將它轉(zhuǎn)成另一種定義。但總的來(lái)說(shuō), 這種辦法適合對(duì)HTML標(biāo)準(zhǔn)比較熟悉的開(kāi)發(fā)人員。

          posted on 2007-07-03 12:38 chenguo 閱讀(184) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): AJAX Dev

          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導(dǎo)航

          統(tǒng)計(jì)

          留言簿

          隨筆分類(lèi)(1)

          文章分類(lèi)(52)

          好友 小山的博客

          最新隨筆

          最新評(píng)論

          主站蜘蛛池模板: 琼结县| 宁德市| 永德县| 镇康县| 滨州市| 安康市| 包头市| 樟树市| 巴南区| 双桥区| 洪湖市| 成都市| 始兴县| 鄱阳县| 宝清县| 曲周县| 思茅市| 钟祥市| 卢龙县| 汉阴县| 厦门市| 锡林郭勒盟| 永吉县| 华宁县| 卢氏县| 江达县| 孟津县| 裕民县| 古田县| 景洪市| 游戏| 竹山县| 县级市| 宜城市| 博罗县| 合江县| 永兴县| 翁源县| 宜都市| 定远县| 卓资县|