舊文件

此處文件僅供參考,請自行考量時效性與適用程度,其他庫藏文件請參考文件頁面
我們亟需您的協助,進行共筆系統搬移、及文件整理工作,詳情請查閱參與我們

以萬維網標準設計您的網頁

出自 MozTW Wiki

原文

  • 翻譯:Daniel Wang、趙柏強
  • 原作:Mike Cowperthwaite, Marcio Galli, Jim Ley, Ian Oeschger, Simon Paquet, Gérard Talbot

Browser makers are no longer the problem. The problem lies with designers and developers chained to the browser-quirk-oriented markup of the 1990s-often because they don't realize it is possible to support current standards while accommodating old browsers.

現在問題已經不在瀏覽器開發商,而是許多網頁設計師的思緒還停在 90 年代、以瀏覽器怪癖為主的網頁製作方式。這通常是因為他們不知道怎麼同時支援近代標準並相容較舊的瀏覽器。 Web Standards Project

一些用於嵌入 DHTML(動態 HTML)至頁面的元素及技巧已被 W3C 的 HTML 4.01 與文件物件模型(Document Object Model,DOM)規格書所排拒在外了。舉例來說,標籤如 <LAYER> 與物件組如 document.layers[] (Netscape 4) 或 document.all (Internet Explorer 5+) 實際上並非任何萬維網標準的一份子。近來相容於 W3C 標準的瀏覽器(如 Mozilla、Firefox、與 Netscape 6/7)並不支援這些非標準的元素與專有的 DOM 串組。

本文章提供您一份將網頁升級、以求符合萬維網標準的程序概覽。各段節會舉出一些與標準相違背之技法,並建議替代方案。所有本文章所提出的標準替代方案皆也測試與檢定過,在近代瀏覽器如 MSIE 6、Netscape 7.x、Firefox 1.x、Opera 7+、Safari 1.2+、Konqueror 3.x 等的裡面完全無問題。最後的一節「更動摘要」整理本文所有替換建議。

本文件內容:

  1. 升級 Layer 元素 (Netscape 4)
    1. 棄用(Deprecated)的元素
    2. Applet
    3. Font
    4. 其它棄用的
  2. 其它排除的元素
  3. 使用 W3C DOM
    1. 與 DOM 相關未支援的屬性
    2. 以 W3C DOM 存取元素
    3. 操作文件樣式及內容
  4. 開發跨瀏覽器跨平台的網頁
    1. 瀏覽器識別(非最佳,不可靠)
    2. 物件/功能支援偵測(最佳,可靠)
  5. 更動摘要

升級 Layer 元素 (Netscape 4)

本節解釋如何用符合標準的 HTML 4.01 來取代 Netscape 4 的 <layer> 與 <ilayer> 元素。因為 <layer> 與 <ilayer> 元素不屬於任何的 W3C 網路標準, Netscape 6/7、Firefox 與 Mozilla 等合乎標準的瀏覽器皆不支援 <layer> 與 <ilayer> 元素

document.layers[] 物件集及 Netscape 4 Layer DOM 其它的特定的功能也不受支援,這些在 DOM 一節會討論。

在 Netscape 4 裡,<layer> 元素主要有兩個功用:

  • 在網頁中嵌入外部的 HTML 內容,與
  • 設定 HTML 內容特定區塊的位置;這類 HTML 內容的區塊通常在書中、在參考文件中、或在網頁作者間被稱呼為 layer﹝圖層﹞ 或 DHTML layer。

取代作為嵌入外部 HTML 內容的 <layer> 與 <ilayer>

如果你有

<LAYER SRC="foo.html" height="300" width="400"> </LAYER>

那對於 HTML 4.01 Transitional(過渡)文件你可用以下取代:

<iframe src="foo.html" height="300" width="400">
  <a href="foo.html">Foo 內容</a>
</iframe>

註:如 Netscape 4 等不支援 IFRAME 的使用代理器與非常舊的視訊瀏覽器會顯示它的內容如:「這裡,內容鏈結」。如此,內容對於較舊瀏覽器的親和力(內容退化)可以確保與最優雅化。

或著,對於 HTML 4.01 Strict(嚴格)文件你可用以下取代:

<object data="foo.html" type="text/html" height="300" width="400">
  <a href="foo.html">Foo content</a>
</object>
</code>

註:同上,不支援這物件元素的使用代理器與瀏覽器會顯示該鏈結,因此確保內容可以取得。

一般使用 <iframe> 或 <object> 的親和力策略是在 <iframe> 或 <object> 內置入最常用與支援最多的元素。如此,無法繪製 <iframe> 或 <object> 的使用代理器可以繪製這內容來代替。大多數瀏覽器遇到不明元素時的一般規則是盡所能繪製它的內容。註一

更多有關內嵌 HTML 內容:
Notes on embedded documents from W3C HTML 4.01

註一:「如果使用代理遇到它不認識的元素,它應試著繪製元素的內容。」:Notes on invalid documents

取代作為置放(positioned)區塊的 <layer> 與 <ilayer>

要升級置放的 <layer> 元素最好的 W3C 萬維網標準的取代方法是用 <div>。<div> 元素不能夠轉置(transclude),不能夠匯入網頁外的 HTML 內容,因此如果設定 src 屬性它將受符合 W3C 的瀏覽器所忽略。

如果你有

<LAYER style="position: absolute;" top="50" left="100"
width="150" height="200">
   ... 內容在這裡 ...
</LAYER>

你可以用這個代替:

<div style="position: absolute; top: 50px; left: 100px;
width: 150px; height: 200px;">
   ... 內容在這裡 ...
</div>

棄用(Deprecated)的元素

HTML 4.01 內棄用的元素一般被廣泛使用,不過它們已被其它的技巧所取代了。

W3C 的階層樣式列表(CSS)建議書中承襲了許多棄用(和一些排除的)標籤的函式,樣式表提供了威力強大的展示及組織能力,但對於 CSS 的討論則不在此文的範圍之中。

Applet

APPLET 元素的功能已在 HTML 4.01 中為 OBJECT 取代而棄用。

<p>
<applet code="HelloWorldApplet.class" height="200" width="350"></applet>
</p>

可以被轉為

<p>
<object
  classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" 
  codebase="http://java.sun.com/products/plugin/autodl/jinstall-1_4_2-windows-i586.cab#Version=1,4,2,0" 
  codetype="application/java" standby="載入 applet 中..." 
  height="200" width="350">
<param name="code" value="HelloWorldApplet.class">
<!--[if !IE]>
Mozilla 1.x、Firefox 1.x、Netscape 7.x 與其它會用內物件(巢套物件)
-->
     <object classid="java:HelloWorldApplet.class" 
     standby="載入 applet 中..." 
     height="200" width="350">
     <p>你的瀏覽器似乎沒有啟用 java 支援或沒有 Java plug-in。<br>
     <a href="http://www.java.com/zh_TW/download/manual.jsp">你可以在這裡下載
     最新的 Java plug-in。(免費下載;15 MB)</a></p>
     </object>
<!--<![endif]-->
</object>
</p>

以上的程式碼在 will work for MSIE 6、以 Mozilla 為基礎的瀏覽器、與其它以標準為基礎的瀏覽器有效。此外,它會通過 HTML 4.01 transitional 或 HTML 4.01 strict 的查驗(validation)。

程式碼的解釋:

根據 HTML 4.01 推薦,如果 <object>(例如因為其內容型別不受支援,或例如瀏覽器無法支援 <object> 所呼叫的 ActiveX 控制件)不受繪製,則瀏覽器應繪製其內容:這裡,內容是另一個(代替的)<object>。在這裡,不支援由 ActiveX 控制件觸發之 Java plug-in 的瀏覽器會顯示內 <object>。

classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93": 
這個 clsid 數值使 MSIE 6 瀏覽器用(安裝在使用者系統上)最高版本的 JRE。有時候 MSIE 6 使用者有安裝數個 JRE plug-in 版本。
codebase="http://java.sun.com/products/plugin/autodl/jinstall-1_4_2-windows-i586.cab#Version=1,4,2,0": 
codebase 定義 JRE 最低版本;在這裡是 1.4.2。如果瀏覽器沒有 java plug-in 或它有的版本在 1.4.2 之前,那將會有自動最新 1.4.2 版的下載。這選擇也許有爭議,一方面最新版的 JRE plug-in 有些安全修補與問題修正,另一方面未有使用者明確的同意而強制下載 15MB 檔不會是最好的。

其它 applet 轉換到 object 的資訊

Font

被棄用的 FONT 標籤廣泛用以指定文字的字體、色彩及尺寸,而這種功能已從 HTML 轉移至 CSS。FONT 標籤可直接以指定了相同樣式資訊的 SPAN 標籤替代:

<P><FONT color="blue" face="Helvetica">
A really <FONT size="+1">big</FONT> shoe.
</FONT></P>

可轉換為

<pre class="code">
<P><SPAN style="color:blue; font-family: Helvetica, sans-serif;">
A really <SPAN style="font-size: larger;">big</SPAN> shoe.
</SPAN></P>

或簡潔點的方式

<P style="color: blue; font-family: Helvetica, sans-serif;">
A really <SPAN style="font-size: larger;">big</SPAN> shoe.
</P>

這雖然適用於區域字體的改變,但卻不是使用樣式的最佳方式;CSS 的本意在於將文字及其他樣式以具邏輯的組合方式,來全域性地將樣式套用到所需的所有元素上。

更多有關 <FONT> 轉換:

W3C Quality Assurance tip for webmaster: Care With Font Size, Recommended Practices: Forget <font>, use CSS

其它棄用的元素

棄用元素與屬性 W3C 代換方式
CENTERalign="center" CSS1: CSS1 text-align: center; 用於同軸(inline)元素
「[text-align 特性]定義文字[或同軸內容]該如何在元素內對齊」
CENTERalign="center" CSS1: 區塊層元素的 margin-left: auto; margin-right: auto;

「if both 'margin-left' and 'margin-right' are 'auto', they will be set to equal values. This will center the element inside its parent.」
CSS1 horizontal formating
Worth mentioning is the excellent tutorial:

Centring using CSS(作者 David Dorward)
bgcolor 屬性 CSS1 background-color: ;
S
STRIKE
CSS1: text-decoration: line-through;
U CSS1: text-decoration: underline
DIR
MENU
HTML 4.01: <UL>

其它排除的元素

有一些用來作動畫與其它特效的專有元素不在任何萬維網標準內。本節舉出這些元素並建議一些用 W3C HTML 4.01 取得同樣效果的技巧:

排除的元素 W3C 代換方式
BLINK
Nav2+
CSS1: text-decoration: blink;
用戶代理有受 CSS1 規格要求要能識別 blink 關鍵字,但沒有受要求支援閃爍效果,因此符合 CSS1 的瀏覽器不一定會將文字閃爍顯示出。最好的方法是不要用閃爍內容。
MARQUEE
IE2+
HTML 4.01 DIVSPAN,內容字串用 JavaScript 藉由 DOM level 1 來定時轉換。

如閃爍文字,這類效果不受鼓勵。調查有顯示不斷移動的物件或文字會干擾閱讀與降低周邊視力。DHTML 走馬燈並在測試的瀏覽器下耗費使用者系統資源 (cpu, RAM),並會對普通的系統造成很大的負荷。如果在評估與考慮網頁後你還是想要在頁內用走馬燈效果,那你可以用以下小教學:
Cross-browser and web standard compliant Stock Ticker example by D. Rosenberg
Comprehensive web standard compliant alternative to <marquee> by D. Rosenberg

Safari, Mozilla 1.4+、NS 7.2、與 Firefox 1.x 支援這非標準的 <marquee> 元素,不過使用者可用這個 tip 來關閉這支援。

BGSOUND
IE2+
HTML 4.01 OBJECT,例如:

<OBJECT data="audiofile.wav" type="audio/wav" ...></OBJECT>
要讓聲音 OBJECT 在頁面上不顯示請見這個 DevEdge 文章
網頁背景聲音常常會把網頁載入變得很慢;如上述文字效果,伴隨頁面的音樂或聲音很少受人喜愛。根據 What we really hate on the web(我們萬維網上討厭的東西)調查,41.9% 調查受訪人會避開自動播放音樂的網站;71.1% 非常不喜歡自動播放音樂的網站。

Why Playing Music on your Web Site is a Bad Idea by A. Gulez
EMBED
Nav2+,IE3+
HTML 4.01 OBJECT。對於把 EMBED 轉換到 OBJECT 標籤的資訊請見這個 DevEdge 文章
EMBED 從未 是 W3C HTML 標準推薦的一部份,但是它還是受到 Gecko 與其它現代瀏覽器支援。支援度的品質不一;Internet Explorer 的支援與大部份 Netscape plug-in 不相容。OBJECT 也不是皆受支援,尤其是在舊的瀏覽器上。

使用 W3C DOM

在一些瀏覽器上 document 物件有屬性可用來存取元素陣列與元素類別。舉例來說, Internet Explorer 用 document.all[] 來存取文件內特定的元素。這些陣列有許多不在 W3C 的 Document Object Model 規格內,並在符合標準的瀏覽器 (如 Mozilla、Firefox、與 Netscape 6/7) 內會產生 JavaScript 錯誤。

在 W3C 的 Document Object Model 內,幾乎所有的 HTML 頁面的元素是腳本可存取物件 (scriptable object)。一般來講,W3C 的 DOM 的屬性 (attribute) 與方法 (method) 比 DHTML 編程所用的專有物件模型還強大。大致上,現代瀏覽器,如 MSIE 6、Safari 1.x、Konqueror 3.x 與基於 Mozilla 的瀏覽器 (Firefox、Mozilla、Netscape 6/7) 對 W3C DOM 的屬性 (attribute) 與方法 (method) 有很好的支援,所以依賴專有物件模型不會有更多的好處。

與 DOM 相關未支援的屬性

以下這些 document 物件特性不受 W3C Document Object Model 支援:

  1. document.layers[]
  2. id_屬性值
  3. document.all.id_屬性值
  4. document.all[id_屬性值]

以下這些(源自 Internet Explorer)的表單物件特性不受 W3C Document Object Model 支援:

  • FormName.InputName.value
  • InputName.value
  • FormCtrlName
  • document.forms(0)

用這些特性的腳本 (script) 在 Firefox、Mozilla、與 Netscape 6/7 或其它合乎標準的瀏覽器上不會執行。反之,用下一節所述的 W3C DOM 來存取屬性與 methods;因為它們在 Internet Explorer 也有支援,所以沒有必要用特定 MSIE 的屬性與 methods。

以 W3C DOM 存取元素

存取 HTML 頁面的元素的最好也最受廣泛支援的方法是用 document.getElementById(id). 所有的現代瀏覽器 (Netscape 6+、Mozilla、MSIE 5+、Firefox、Opera 6+、Safari 1.x、Konqueror 3.x 等等)支援 document.getElementById(id)。此方法傳回一個單一識別的屬性的物件參引 (this returns an object reference to the uniquely identified element),而這可用腳本處理 (script) 該元素。舉例來說,以下小範例於動態把一個 id 為 "inset" 的 div 元素的的左邊界 (left margin) 設定為半公寸:

<span class="remark">// in the HTML: <div id="inset">Sample Text</div></span>
document.getElementById("inset").style.marginLeft = ".5in";
特定 IE 的元素存取法 W3C 萬維網標準取代方案
id_attribute_value document.getElementById(id_屬性值)
document.all.id_屬性值 document.getElementById(id_屬性值)
document.all[id_屬性值] document.getElementById(id_屬性值)
表單名.欄位名.value document.forms["表單名"].欄位名.value 或
document.forms["表單名"].elements["欄位名"].value
欄位名.value document.forms["表單名"].欄位名.value 或
document.forms["表單名"].elements["欄位名"].value
表單控件名 document.forms["表單名"].表單控件名 或
document.forms["表單名"].elements["表單控件名"]
document.forms(0) document.forms[0]

其它表單與表單元素的存取的資訊:
Referencing Forms and Form Controls by comp.lang.javascript newsgroup FAQ notes
DOM 1 specification on accessing forms and form elements

對於一群元素的存取, DOM 規格書也包括了 getElementsByTagName,這傳回所有指定標籤 (tag) 名的元素,並且依文件內出現的先後順序排列:

var arrCollection_Of_Anchors = document.getElementsByTagName("a");
var objFirst_Anchor = arrCollection_Of_Anchors[0];
alert("The url of the first link is " + objFirst_Anchor.href);

除了這些存取 methods 外,W3C DOM2 規格書也允許做新元素與把它們插到文件中,建立屬性,建立新內容, 往返 (traverse) 內容樹,與處理用戶與文件互動所產生的事件。

操作文件樣式及內容

以下的表格描述基於標準,存取與更新網頁內各種 HTML 元素的樣式規則 (style rule) 的 methods。另見 W3C DOM2 推薦書 CSS2 Extended Interface

DOM level 2 提供了用 element.style 物件參引來對元素 CSS 特性設新值。你可以用 DOM 的 getElementById 或其它前面以 W3C DOM 存取元素所述之 methods 來取得那元素。

已棄用編程法 適合的 DOM 2 取代方法
Nav4: element.visibility = value; DOM level 2: element.style.visibility = value;
Nav4: element.left

IE5+: element.style.pixelLeft

DOM level 2: parseInt(element.style.left, 10)
Nav4: element.top

IE5+: element.style.pixelTop

DOM level 2: parseInt(element.style.top, 10)
Nav4: element.moveTo(x,y);

IE5+: element.style.pixelLeft = x;
element.style.pixelTop = y;

DOM level 2:

element.style.left = x + "px";
element.style.top = y + "px";

W3C DOM2 的元素 CSS 特性反映

記住根據 W3C 推薦書,一個元素的 style 特性所傳回的值只反映那元素 STYLE 的靜態 (static) 設定,而不是所有的「計算過樣式」(computed style),包括從任何母元素所承襲的樣式。因此,如果你想要用 JavaScript 透過 DOM2 來讀取與寫入這些特性,用以下這兩個方法的其一:

  • 將該元素所有的靜態 CSS 宣告放在它的 STYLE 屬性內。
  • 不要用靜態 CSS 宣告,用 JavaScript 透過 DOM2 來初始化它的 CSS 特性。

W3C DOM2 的元素 CSS 定位 (positioning) 特性反映

W3C DOM2 style.leftstyle.top 特性所傳回的值是有包括 CSS 單位 (如 "px") 的字串,反觀 Netscape 4 的 element.left 與 IE5+ 的 element.style.pixelLeft (與相對的 top 特性)傳回一個整數 (integer)。因此,如果你想要取一個元素 STYLE 裡 left 與 top 的整數值,用 parseInt() 來從字串中解出整數。反過來說,如果你想設元素 STYLE 裡的 left 與 top,確定你利用把單位字串放在整數值後來建立一個有單位的字串 (例如 "140px")。

CSS1 與 CSS 2.x 規格書要求非零的值必須要有一個長度單位;否則該 CSS 宣告會被忽略。基於 Mozilla 的瀏覽器、MSIE 6、Opera 7+ 與其它符合 W3C 標準的瀏覽器強制這錯誤處理。

CSS1 Forward-compatible parsing
CSS2.1 Rules for handling parsing errors

利用 DOM 來更改一個元素的文字

更改一個元素的實際文字内容與其它平常的動作有很大的不同。每個元素的內容被分成一組子節點 (childe node),這由純文字與子元素所組成。要改變元素的文字,腳本 (script) 要處理節點。

節點的結構與支援的 method 於 W3C DOM level 1 推薦書定義。

如果那元素沒有子元素,只有文字,那它(通常)有一個子節點,用 element.childNodes[0] 存取。在這樣的例子裡,W3C 萬維網標準中element.innerTextelement.childNodes[0].nodeValue 相等。

下面這範例說明如何改 HTML 檔中已有的 SPAN 元素的文字:

<body>
  <P>老爸的<SPAN id="dynatext">膽子</SPAN>很大!</P>

  <script type="text/javascript">
    // get reference to the SPAN element
    var span_el = document.getElementById("dynatext");

    // 實做 span_el.innerText = "全新提包"
    var new_txt = document.createTextNode("全新提包");
    span_el.replaceChild(new_txt, span_el.childNodes[0]);

    // 或著,一個比較危險的方法
    //   (如果 childNodes[0] 不是文字節點時會不能用)
    span_el.childNodes[0].nodeValue = "a brand new bag";

    // 實做 span_el.innerHTML = "全<b>新</b>提包"
    var new_el = document.createElement(span_el.nodeName);
    new_el.appendChild(document.createTextNode("全"));
    var bold_el = document.createElement("B");
    bold_el.appendChild(document.createTextNode("新"));
    new_el.appendChild(bold_el);
    new_el.appendChild(document.createTextNode("提包"));
    span_el.parentNode.replaceChild(new_el, span_el);
  </script>
</body>

第一個範例展示一個相對上簡單的方法,用替換原來的文字節點來取代 SPAN 內的文字。這裡的假設是 SPAN 有單一的文字子項;這碼甚至在假設是錯的時也能用,不過結果可以是異想不到的。

第二個範例展示一個做同樣事,較簡短但強行 (brute-force) 的技巧。如之前提到,如果第一個子節點不是個文字節點,這動作將沒效:雖然子元素節點有 nodeValue,那一欄的內容不會在文件裡顯示。

最後的範例展示一個與設 innerHTML 是一樣的技巧。首先它建立一個新元素,與原來的同類別(SPAN)。接下來它加入了三個節點:先一個文字節點,再來一個有自己文字節點的 B 元素,最後一個字文字節點。這腳本 (script) 然後取要替換的 SPAN 元素之母 (P 元素),並把母元素的節點列表內原來的 SPAN 換成新的。

這應該很清楚把腳本翻成可用來更改文件內容不是件易事。這樣的變換的好處是腳本可用在現代,符合 W3C DOM 的瀏覽器,如 Netscape 6/7 與其它基於 Gecko 的軟體。向後相容不但會延後而且會惡化處理多平台的困難度。

開發跨瀏覽器跨平台的網頁

做跨瀏覽器,跨平台的網頁與 DHTML 開發一個重要的事是判斷載入網頁的瀏覽器的功能性。可理解地,做為一個網路作者你會想要避免腳本 (script) 錯誤與頁面編排問題,並確保你的腳本能盡可能伸到廣泛的觀眾。已知達到這目標的方法有兩個:瀏覽器識別 (或 userAgent 字串偵測,另外也常稱 "browser sniffing") 與物件/功能支援偵測。瀏覽器識別方法是大家所知複雜,不可靠,與難維護。

瀏覽器識別 (或稱 "browser sniffing"):非最佳,不可靠方法

這個在目前還是很常用的方式嘗試辨識瀏覽器,使得網頁作者在設計時要決定這會代表造訪瀏覽器會有甚麼功能。這樣的方法充滿了問題與難度。它要求網頁作者知道所有目前可能會造訪網頁的瀏覽器的功能,然後為這些瀏覽器寫適當的原碼。方法要求網頁作者對未來的瀏覽器會如何做假設以對它們提供可靠的服務。這方法假設網頁作者能夠正確地識別瀏覽器與瀏覽器版本,而這不是件可靠且容易達到的事。

瀏覽器識別方法依賴檢查瀏覽器類別字串值與瀏覽器版本字串值,與搜尋 navigator.userAgent 特性字串內的某些字元或子字串的函式。當「偵測到」時,網頁作者用不同的函式 (或稱分碼) 或是把用戶轉到不同的頁面 (或稱分站) 或網頁內容。分站尤其危險,因為如果訪客可經由鏈結、書籤、搜尋器、或「錯的」瀏覽器的快取空間 (cache) 來到一個頁面。

看看一個這方法的簡單範例。

不良範例

if (navigator.appVersion.charAt(0) == "7")
{
   if (navigator.appName == "Netscape")
   {
     isNS7 = true;
     alert("這是 Netscape 7");
   };
}
else if (navigator.appVersion.indexOf("MSIE") != -1)
   {
    isIE = true;
    alert("這是 IE");
   };

雖然上面源碼這類的檢查粗略的講可用,敏銳的讀者也許會納悶,如果 IE 7 釋出,或是 Opera 7.x 用戶造訪頁面,或甚至用 appVersion 字串以 7 為開頭的非 Netscape 瀏覽器的用戶造訪頁面,那會怎樣?隨新瀏覽器的釋出,這樣試著縮小瀏覽器與瀏覽器版本範圍與做適當的轉換的源碼需要隨著更新。

這方法另一個大問題是瀏覽器身份可以「謊報」,因為在許多現代的瀏覽器內 navigator.appVersionnavigator.userAgent 字串特性為用戶可自定的。例子有,

  • Mozilla 1.x 用 "general.useragent.override" 偏好設定
  • Opera 6+ 允許用戶透過選單設定瀏覽器識別字串
  • MSIE 利用 Windows 的 registry
  • Safari 與 ICab 瀏覽器以 Internet Explorer 或 Netscape 名稱來掩飾身份

用戶與瀏覽器廠商可以在 navigator.userAgent 字串內想他們想要放的東西,這可以騙你的程式碼去執行「錯誤的」程式碼組。而且,很多情況下正確辨識出的瀏覽器沒有如名聲/預期的運作。

因此,如果 "browser sniffing" 不可靠與困難,你要如何安全地為不同瀏覽器與瀏覽器版本編程呢?

利用物件/功能支援偵測:最佳與總體上最可靠的

當你利用物件/功能支援偵測時,你只有實作你有測試與確定造訪瀏覽器有支援的功能。這方法的優點是,除了你要用的功能造訪瀏覽器有沒有支援外,它不要求你測試任何其它東西。

看看一個物件偵測的簡單範例。

優良範例

function hideElement(id_attribute_value)
{
   if (document.getElementById &&
         document.getElementById(id_attribute_value) &&
            document.getElementById(id_attribute_value).style)
   {
   document.getElementById(id_attribute_value).style.visibility="hidden";
   };
}

// 範例:
// <button type="button" onclick="hideElement('d1');">hide div</button>
// <div id="d1">一些字</div>

這些對 document.getElementById 的重複呼叫不是測試瀏覽器的 DOM 實作內有無某物件或功能的最有效方法,不過它很清楚的舉例說明物件偵測該如何地做。

最上層的 if 句檢查 document 物件內有沒有 一個叫 getElementById 的物件。如果有,程式碼檢查 getElementById(id_attribute_value) 會不會傳回一個元素,然後它檢查 style 物件。如果那元素有 style 物件,那程式碼設定它的 visibility 特性。如果你設的這個沒有實作,瀏覽器不會產生錯誤,所以你沒有必要檢查 visiblity 特定存不存在。

所以,無需要知道哪個瀏覽器與瀏覽器版本支援那個 DOM method (或 DOM 屬性或 DOM 功能),你只要確定那 method 在造訪瀏覽器內有沒有支援。用這個方法,你可以確定所有的瀏覽器,包括未來的版本與你不知道 userAgent 字串的瀏覽器,遇到你的源碼可以繼續運作。

其它物件/功能偵測的資訊

A Strategy That Works: Object/Feature Detecting by comp.lang.javascript newsgroup FAQ notes
Browser detection - No; Object detection - Yes by Peter-Paul Koch

更動摘要

本節整理本文所有元素與方法更新。這些項目的詳文請見它們的分節。

專有或棄用的功能 W3C 功能或建議的取代方案
NS 4 做為定位的 HTML 內容區塊的 LAYER HTML 4.01 DIV
NS 4 ILAYER HTML 4.01 transitional 內的 iframe
HTML 4.01 strict 內的object
NS 4 LAYER SRC=, DIV SRC= HTML 4.01 transitional 內的 iframe src=
HTML 4.01 strict 內的 object data=
IE2+ MARQUEE HTML 4.01 DIV 與 scripting
Nav2+ BLINK CSS1 text-decoration: blink;
IE2+ BGSOUND HTML 4.01 OBJECT
Nav 2+, IE3+ EMBED HTML 4.01 OBJECT
deprecated APPLET HTML 4.01 OBJECT
deprecated FONT HTML 4.01 SPAN 加上
CSS1 color: ; font-family: ; font-size: ;
deprecated CENTER or align="center" CSS1 同軸 (inline) 元素的 text-align: center;
deprecated CENTER or align="center" CSS1 區塊層元素的 margin-left: auto; margin-right: auto;
deprecated bgcolor CSS1 background-color: ;
deprecated U, S, STRIKE CSS1 text-decoration: underline, line-through;
deprecated DIR, MENU HTML 4.01 UL
專有或棄用的功能 W3C 功能或建議的取代方案
Nav4 document.layers[] DOM level 2:
document.getElementById(id)
IE5+

id_attribute_value
document.all.id_attribute_value

document.all[id_attribute_value]
DOM level 2:
document.getElementById(id_attribute_value)
IE5+ 表單名.欄位名.value DOM level 1:
document.forms["表單名"].欄位名.value
IE5+ 欄位名.value DOM level 1:
document.forms["表單名"].欄位名.value
IE5+ 表單控件名 DOM level 1:
document.forms["表單名"].表單控件名
IE5+ document.forms(0) DOM level 1:

document.forms[0]

Nav4 document.layers[id].document.write()
IE 元素.innerText
DOM Level 1 (Core) interface
Nav4 元素.visibility = value; DOM level 2:
元素.style.visibility = value;
Nav4 元素.left
IE5+ 元素.style.pixelLeft
DOM level 2: parseInt(元素.style.left, 10)
Nav4 元素.top
IE5+ 元素.style.pixelTop
DOM level 2: parseInt(元素.style.top, 10)
Nav4 元素.moveTo(x, y);
IE5+ 元素.style.pixelLeft = x;
元素.style.pixelTop = y;
DOM level 2:
元素.style.left = x + "px";
元素.style.top = y + "px";
專有或棄用的功能 W3C 功能或建議的取代方案

以下網站有更多關於網路標準的內容:

补充:[CSS2盒模型的3D示意图]

CSS2中的盒模型是关系到我们排版定位的关键,例如

就遵循盒模型规范。盒模型定义的margin,background- color,background-image,padding,content,border,初学者经常会搞不清楚它们之间的层次、关系和相互影响。这里提供一张盒模型的3D示意图,希望便于你的理解和记忆。

[[1]]

個人工具