Writing forward-compatible websites

  • 版本網址代稱: Web_development/Writing_forward-compatible_websites
  • 版本標題: Writing forward-compatible websites
  • 版本 ID: 232987
  • 建立日期:
  • 建立者: Sonrisa
  • Is current revision?
  • 回應 16 words added, 518 words removed

版本內容

這個頁面將解釋如何撰寫在新的瀏覽器版本發布時不會遭受毀損的網頁。

這對內部網路和其他非公共網站尤其重要,如果我們不能看到你的原始碼,我們將無法看到它是否已遭受毀損。底下所提到的原則可能無法全數做到,但盡可能遵守這些原則,對於你的網站在未來發展維護上有所幫助。

JavaScriptEdit section

使用 "window  ." 前綴修飾(Prefix) 所有存取於 onfoo 屬性的全域變數Edit section

當一個事件處理器內容屬性(例如: onclickonmouseover 等等)被使用在 HTML 的元素上時,所有對於屬性內名稱的查找首先發生在元素本身,若元素為表單控制項,再來尋找元素的表單,接著是 document,最後是 window(你定義全域變數的地方)。例如,如果你有這樣的原始碼:

<div onclick="alert(ownerDocument)">Click me</div>

在點選文字時,div 中的 ownerDocument 會被提示,即使是在全域範圍內宣告 var ownerDocument 這種情況依然會發生。

這意味著,無論你何時在事件處理器內容屬性存取了一個全域變數,包括呼叫任何全域函數,當規格中新增了和您變數或函式同名的 DOM 屬性到元素或文件之中,在瀏覽器實作之後,就會產生名稱衝突。這時你的函式將突然被停止呼叫這種情況HTML5 的發展之下,多次在不同網站中發生

為了避免這種情況,以 window 來限定全域變數的存取,例如:

<script>
  function localName() {
    alert('Function localName has been called');
  }
</script>
<div onclick="window.localName()">Clicking me should show an alert<div>

不要直接附加非您能控制的腳本

"use strict;" 指令在 ECMAScript 裡,使用於檔案層級時適用於檔案的所有程式碼。因此,若將取決嚴格模式行為的腳本直接附加到要求嚴格模式的腳本會導致不正常的行為。

要求 JavaScript 函式庫的作者遵守這些規則

向您喜歡的函式庫開發者們建議他們遵循這些規範,否則您無法確保未來這些函式庫能否依舊正常運作。可惜的是函式庫往往違反這些準則。

偵測

偵測特定功能支援

如果您打算使用某些功能,盡可能使用物件偵測來偵測功能是否支援。簡單來說,不要假設只要 "filter" in body.style 測試結果為 true 的瀏覽器必定是 Microsoft Internet Explorer,進而我們一定會有 window.event 物件提供事件處理器。不要假設一個擁有特定 DOM 功能的瀏覽器一定也有另外一個 DOM 功能(特別是非標準功能);或著反過來假設一定不會支持某些功能(例如,假設在腳本元素中支援 onload 的瀏覽器一定不會支援 onreadystatechange)。隨著瀏覽器們整合他們的行為,它們會同時新增和刪除許多功能並修正錯誤。過去即是如此,未來也將會如此。

所以,在偵測特定功能時,不要接著假定「只要某個功能支援與否,另外一樣功能就一定支援與否」

別做 UA 偵測

這就是假設一項功能存在(User Agent 中包含特定的字元)時,必定有哪些東西可用或不可用的常見實例。

如果您不得不做 UA 偵測,僅針對過去的瀏覽器版本

如果您還是得訴諸 UA(User Agent)偵測,請只針對特定瀏覽器的過去版本進行偵測。首先,對於未知的、所測試瀏覽器的目前與未來版本執行預設的程式內容。接著如果無法透過偵測,找出過去瀏覽器版本中預設程式內容中無法使用的功能,就可以透過偵測特定瀏覽器的過去版本來追加對應的修正。

在這個提案中,「目前的版本」意指您所能測試到的最新版本。如果您的預設程式內容在 Firefox Aurora 中可以正常運作,而在 Beta 和最新釋出版中存在問題而無法運作,此時您可以將您所測試中的 Firefox Aurora 版本標為「目前的版本」,將 Beta 以前的版本都視為「過去的版本」,即使它們還沒有被正式釋出給大眾。

不要為了不同的瀏覽器設計多餘的對應程式

當您所用的一部分程式內容可能在所有瀏覽器都能運作時,別隨便透過物件或 UA 偵測來決定執行不同的程式碼。瀏覽器很有可能改變它們的行為並互相整合,若您任意切出不同的替代程式,您的網站將有可能會損壞。

測試

測試所有主流引擎

至少在 Firefox、Chrome 或 Safari(因為兩者都基於相同的 WebKit 引擎)、Opera 及 Internet Explorer 測試您的程式碼。若遵循以上原則,你有一個單一的程式碼內容在目前所有的和未知的瀏覽器都測試過,在所有主要引擎都能運作下,極有可能表示您的程式碼將不會在未來被破壞。

有時不同瀏覽器對特定功能的實作不盡相同。如果你有一個單一的程式碼內容,在所有常用的引擎中都沒問題,這可能表示,你使用了各瀏覽器間已經整合的行為,或著使用了尚未整合,而程式碼無關引擎的行為標準所堅持的部份。

瀏覽器特定的功能和前綴

Edit section

不針對當前或未來的瀏覽器版本的黑客

Edit section

這也是一個共同的假設目前的錯誤之間的相關性之間意味著未來的錯誤相關性的實例。針對舊版本的瀏覽器的當前版本不再有錯誤,你靠你的黑客是確定的,一旦瀏覽器有修改X錯誤,你可以知道,對於某些有錯誤X的所有版本,也有錯誤Ÿ,使用存在缺陷X目標的解決方法去針對錯誤Y。

對於這樣的忠告,“當前”是指一個以上的UA嗅探意見的情況下,你已經測試瀏覽器的最新版本。

避免根據尖端非標準特色

Edit section

即使前綴功能,使用它可能是危險的:作為規範的發展同樣可以改變瀏覽器的前綴實施跟踪規範。一旦特點被標準化,前綴的版本是有可能被刪除。

前綴,瀏覽器開發者提供非標準功能試驗,並提供反饋,是注定不會被開發。如果您選擇使用它們,需要經常更新您的網站以趕上變化。

當使用尖端的功能(即使是標準的),沒有得到普遍實施,確保測試後備路徑

Edit section

要確保測試在瀏覽器中沒有實現的功能當你使用,特別是如果你不每天使用這種瀏覽器當在網站上的工作時。

不要使用廠商前綴功能,除了針對老版本

Edit section

賣方前綴的功能,可以在將來的版本中改變。然而,一旦瀏覽器出貨量已沒有前綴的功能,您可以使用前綴版本針對舊版本,確保總是使用不帶前綴的功能版本可用時。一個很好的例子,對越南盾的CSS前綴,已售出的牌子,它漂亮的財產沒有前綴的實施,使用行為的價值“有時”,從不同的前綴版本的瀏覽器供應商:

<style>
  .pretty-element {
    -vnd-make-it-pretty: sometimes;
    make-it-pretty: sometimes;
  }
</style>

上述規則的聲明的順序是很重要的:沒有前綴的人需要排在最後。

不要使用沒有前綴的CSS屬性或API版本,直到至少有一個瀏覽器支持他們

Edit section

直到有體面的東西沒有前綴的版本廣泛支持,其行為仍然可以以意想不到的方式改變。最特別的是,的版本,不要使用不帶前綴如果沒有瀏覽器支持。你不能假設,最終版本的語法,將是任何的前綴版本的語法相同。

Code hygiene

Edit section

Avoid missing >

Edit section

通過一個驗證程序是確保這個問題的方法之一,但即使你的網站沒有完全驗證,你應該確保你所有的>字符呈現。失踪的可能會導致意想不到的情況下由於以下的標記名稱,作為前一個標籤上的屬性處理。這可以工作對一個位元,然後打破規範的含義,該屬性的重視。下面是一個例子,在瀏覽器中工作,不在支持HTML5的瀏覽器:

Passing a validator is one way to ensure this, but even if your website doesn't validate entirely you should make sure all your > characters are present. Missing those can lead to unexpected situations due to a following tag name being treated as an attribute on a previous tag. This can work for a bit, then break if a specification attaches a meaning to that attribute. Here's an example that works in browsers without HTML5 support but breaks in a browser supporting HTML5:

  1. <form action="http://www.example.com">  
  2.   <input type="submit" value="Submit the form"  
  3. </form>  

due to the missing > on the input tag.

Don't leave experiments that didn't work in your code

Edit section

If you try using a CSS property to do something you want, but it has no effect, remove it.  It might start doing something you don't expect in the future.

版本來源

<p>這個頁面將解釋如何撰寫在新的瀏覽器版本發布時不會遭受毀損的網頁。</p>
<p>這對內部網路和<span>其他</span><span>非公共</span>網站尤其重要,如果我們不能看到你的原始碼,我們將無法<span>看到</span><span>它是否已遭受毀損</span>。底下所提到的原則可能無法全數做到,但盡可能遵守這些原則,對於你的網站在未來發展維護上有所幫助。</p>
<div id="section_1"> <h2 class="editable">JavaScript<a href="/en/Web_development/Writing_forward-compatible_websites?action=edit&amp;sectionId=1" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="/skins/common/icons/icon-trans.gif"></span></a></h2> <div id="section_2"> <h3 class="editable"><span class="icon">使用 "window</span>  <span class="icon">." 前綴修飾(Prefix) 所有存取於 </span><code>onfoo</code><code> 屬性</code>的全域變數<a href="/en/Web_development/Writing_forward-compatible_websites?action=edit&amp;sectionId=2" title="Edit section"><img alt="Edit section" class="sectionedit" src="/skins/common/icons/icon-trans.gif"></a></h3> <p><span>當一個</span>事件<span>處理器</span><span>內容</span><span>屬性</span>(例如: <code>onclick</code>, <code>onmouseover</code> 等等)被使用在 HTML 的元素上時,所有對於屬性內名稱的查找首先發生在元素本身,若元素為表單控制項,再來尋找元素的表單,接著是 document,最後是 window(你定義全域變數的地方)。例如,如果你有這樣的原始碼:</p> <pre>&lt;div onclick="alert(ownerDocument)"&gt;Click me&lt;/div&gt;</pre> <p><span>在點選文字時,</span><span>div 中的 </span><span>ownerDocument 會被提示</span>,即使是在全域範圍內宣告 var ownerDocument 這種情況依然會發生。</p> <p>這意味著,無論你何時在事件處理器內容屬性存取了一個全域變數,包括呼叫任何全域函數,當規格中新增了和您變數或函式同名的 DOM 屬性到元素<span>或文件</span>之中,在瀏覽器實作之後,就會產生名稱衝突。<span>這時</span>你的函式將突然被停止呼叫<span>。</span><span>這種情況</span><span>在 </span><span>HTML5 的</span><span>發展之下,多次在不同網站中發生</span><span>。</span></p> <p><span>為了避免這種情況</span>,以 window 來限定全域變數的存取,例如:</p> <pre>&lt;script&gt;
  function localName() {
    alert('Function localName has been called');
  }
&lt;/script&gt;
&lt;div onclick="<strong>window.</strong>localName()"&gt;Clicking me should show an alert&lt;div&gt;
</pre> </div> <div id="section_3"> <h3 class="editable">不要直接附加非您能控制的腳本</h3>
<p><code>"use strict;"</code> 指令在 ECMAScript 裡,使用於檔案層級時適用於檔案的所有程式碼。因此,若將<span>取決</span>非<span>嚴格</span><span>模式</span><span>行為</span>的腳本<span>直接附加到要求</span>嚴格模式的腳本會導致不正常的行為。</p></div> <div id="section_4"> <h3 class="editable">要求 JavaScript 函式庫的作者遵守這些規則</h3>
<p>向您喜歡的函式庫開發者們建議他們遵循這些規範,否則您無法確保未來這些函式庫能否依舊正常運作。可惜的是函式庫往往違反這些準則。</p>
</div>
</div>
<div id="section_5"> <h2 class="editable">偵測</h2> <div id="section_6"> <h3 class="editable">偵測特定功能支援</h3>
<p>如果您打算使用某些功能,盡可能使用物件偵測來偵測功能是否支援。簡單來說,不要假設只要 "filter" in body.style 測試結果為 true 的瀏覽器必定是 Microsoft Internet Explorer,進而我們一定會有 window.event 物件提供事件處理器。不要假設一個擁有特定 DOM 功能的瀏覽器一定也有另外一個 DOM 功能(特別是非標準功能);或著反過來假設一定不會支持某些功能(例如,假設在腳本元素中支援<span> onload 的</span><span>瀏覽器一定不會支援</span> onreadystatechange)。隨著瀏覽器們整合他們的行為,它們會同時新增和刪除許多功能並修正錯誤。過去即是如此,未來也將會如此。</p>
<p><span>所以,在偵測特定功能時,不要接著假定「只要某個功能支援與否,另外一樣功能就一定支援與否」</span>。</p></div>
<div id="section_7"> <h3 class="editable">別做 UA 偵測</h3>
<p>這就是假設一項功能存在(User Agent 中包含特定的字元)時,必定有哪些東西可用或不可用的常見實例。</p>
<div id="section_8"> <h4 class="editable">如果您不得不做 UA 偵測,僅針對過去的瀏覽器版本</h4>
<p>如果您還是得訴諸 UA(User Agent)偵測,請只針對特定瀏覽器的過去版本進行偵測。首先,對於未知的、所測試瀏覽器的目前與未來版本執行預設的程式內容。接著如果無法透過偵測,找出過去瀏覽器版本中預設程式內容中無法使用的功能,就可以透過偵測特定瀏覽器的過去版本來追加對應的修正。</p>
<p>在這個提案中,「目前的版本」意指您所能測試到的最新版本。如果您的預設程式內容在 Firefox Aurora 中可以正常運作,而在 Beta 和最新釋出版中存在問題而無法運作,此時您可以將您所測試中的 Firefox Aurora 版本標為「目前的版本」,將 Beta 以前的版本都視為「過去的版本」,即使它們還沒有被正式釋出給大眾。</p>
</div></div>
<div id="section_9"> <h3 class="editable">不要為了不同的瀏覽器設計多餘的對應程式</h3> <p>當您所用的一部分程式內容可能在所有瀏覽器都能運作時,別隨便透過物件或 UA 偵測來決定執行不同的程式碼。瀏覽器很有可能改變它們的行為並互相整合,若您任意切出不同的替代程式,您的網站將有可能會損壞。</p></div></div>
<div id="section_10"> <h2 class="editable">測試</h2> <div id="section_11"> <h3 class="editable">測試所有主流引擎</h3> <p>至少在 Firefox、Chrome 或 Safari(因為兩者都基於相同的 WebKit 引擎)、Opera 及 Internet Explorer 測試您的程式碼。若遵循以上原則,你有一個單一的程式碼內容在目前所有的和未知的瀏覽器都測試過,在所有主要引擎都能運作下,極有可能表示您的程式碼將不會在未來被破壞。</p> <p>有時不同瀏覽器對特定功能的實作不盡相同。如果你有一個單一的程式碼內容,在所有常用的引擎中都沒問題,這可能表示,你使用了各瀏覽器間已經整合的行為,或著使用了尚未整合,而程式碼無關引擎的行為標準所堅持的部份。</p>
</div></div>
<div id="section_12"> <h2 class="editable">瀏覽器特定的功能和前綴</h2>
<div class="editIcon"> <h2 class="editable"><a href="/en/Web_development/Writing_forward-compatible_websites?action=edit&amp;sectionId=12" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="/skins/common/icons/icon-trans.gif"></span></a></h2>
</div>
<div id="section_13"> <h3 class="editable">不針對當前或未來的瀏覽器版本的黑客</h3> <div class="editIcon"> <h3 class="editable"><a href="/en/Web_development/Writing_forward-compatible_websites?action=edit&amp;sectionId=13" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="/skins/common/icons/icon-trans.gif"></span></a></h3> </div> <p>這也是一個共同的假設目前的錯誤之間的相關性之間意味著未來的錯誤相關性的實例。針對舊版本的瀏覽器的當前版本不再有錯誤,你靠你的黑客是確定的,一旦瀏覽器有修改X錯誤,你可以知道,對於某些有錯誤X的所有版本,也有錯誤Ÿ,使用存在缺陷X目標的解決方法去針對錯誤Y。</p> <p>對於這樣的忠告,“當前”是指一個以上的UA嗅探意見的情況下,你已經測試瀏覽器的最新版本。</p>
</div>
<div id="section_14"> <h3 class="editable">避免根據尖端非標準特色</h3> <div class="editIcon"> <h3 class="editable"><a href="/en/Web_development/Writing_forward-compatible_websites?action=edit&amp;sectionId=14" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="/skins/common/icons/icon-trans.gif"></span></a></h3> </div> <p>即使前綴功能,使用它可能是危險的:作為規範的發展同樣可以改變瀏覽器的前綴實施跟踪規範。一旦特點被標準化,前綴的版本是有可能被刪除。</p> <p>前綴,瀏覽器開發者提供非標準功能試驗,並提供反饋,是注定不會被開發。如果您選擇使用它們,需要經常更新您的網站以趕上變化。</p>
</div>
<div id="section_15"> <h3 class="editable">當使用尖端的功能(即使是標準的),沒有得到普遍實施,確保測試後備路徑</h3> <div class="editIcon"> <h3 class="editable"><a href="/en/Web_development/Writing_forward-compatible_websites?action=edit&amp;sectionId=15" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="/skins/common/icons/icon-trans.gif"></span></a></h3> </div> <p>要確保測試在瀏覽器中沒有實現的功能當你使用,特別是如果你不每天使用這種瀏覽器當在網站上的工作時。</p>
</div>
<div id="section_16"> <h3 class="editable">不要使用廠商前綴功能,除了針對老版本</h3> <div class="editIcon"> <h3 class="editable"><a href="/en/Web_development/Writing_forward-compatible_websites?action=edit&amp;sectionId=16" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="/skins/common/icons/icon-trans.gif"></span></a></h3> </div> <p>賣方前綴的功能,可以在將來的版本中改變。然而,一旦瀏覽器出貨量已沒有前綴的功能,您可以使用前綴版本針對舊版本,確保總是使用不帶前綴的功能版本可用時。一個很好的例子,對越南盾的CSS前綴,已售出的牌子,它漂亮的財產沒有前綴的實施,使用行為的價值“有時”,從不同的前綴版本的瀏覽器供應商:</p> <pre>&lt;style&gt;
  .pretty-element {
    -vnd-make-it-pretty: sometimes;
    make-it-pretty: sometimes;
  }
&lt;/style&gt;
</pre> <p>上述規則的聲明的順序是很重要的:沒有前綴的人需要排在最後。</p>
</div>
<div id="section_17"> <h3 class="editable">不要使用沒有前綴的CSS屬性或API版本,直到至少有一個瀏覽器支持他們</h3> <div class="editIcon"> <h3 class="editable"><a href="/en/Web_development/Writing_forward-compatible_websites?action=edit&amp;sectionId=17" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="/skins/common/icons/icon-trans.gif"></span></a></h3> </div> <p>直到有體面的東西沒有前綴的版本廣泛支持,其行為仍然可以以意想不到的方式改變。最特別的是,的版本,不要使用不帶前綴如果沒有瀏覽器支持。你不能假設,最終版本的語法,將是任何的前綴版本的語法相同。</p>
</div></div>
<div id="section_18"> <h2 class="editable">Code hygiene</h2> <div class="editIcon"> <h2 class="editable"><a href="/en/Web_development/Writing_forward-compatible_websites?action=edit&amp;sectionId=18" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="/skins/common/icons/icon-trans.gif"></span></a></h2> </div> <div id="section_19"> <h3 class="editable">Avoid missing <code>&gt;</code></h3> <div class="editIcon"> <h3 class="editable"><a href="/en/Web_development/Writing_forward-compatible_websites?action=edit&amp;sectionId=19" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="/skins/common/icons/icon-trans.gif"></span></a></h3> </div> <p>通過一個驗證程序是確保這個問題的方法之一,但即使你的網站沒有完全驗證,你應該確保你所有的&gt;字符呈現。失踪的可能會導致意想不到的情況下由於以下的標記名稱,作為前一個標籤上的屬性處理。這可以工作對一個位元,然後打破規範的含義,該屬性的重視。下面是一個例子,在瀏覽器中工作,不在支持HTML5的瀏覽器:</p> <p>Passing a validator is one way to ensure this, but even if your website doesn't validate entirely you should make sure all your <code>&gt;</code> characters are present. Missing those can lead to unexpected situations due to a following tag name being treated as an attribute on a previous tag. This can work for a bit, then break if a specification attaches a meaning to that attribute. Here's an example that works in browsers without HTML5 support but breaks in a browser supporting HTML5:</p> <div class="dp-highlighter"> <div class="bar"> <div class="tools"><a href="/en/Web_development/Writing_forward-compatible_websites#" title="en/Web_development/Writing_forward-compatible_websites#">view plain</a><a href="/en/Web_development/Writing_forward-compatible_websites#" title="en/Web_development/Writing_forward-compatible_websites#">print</a><a href="/en/Web_development/Writing_forward-compatible_websites#" title="en/Web_development/Writing_forward-compatible_websites#">?</a></div> </div> <ol class="dp-xml" start="1"> <li class="alt"><span class="tag">&lt;</span><span class="tag-name">form</span> <span class="attribute">action</span>=<span class="attribute-value">"<a class=" external" href="http://www.example.com" rel="freelink">http://www.example.com</a>"</span><span class="tag">&gt;</span>  </li> <li>  <span class="tag">&lt;</span><span class="tag-name">input</span> <span class="attribute">type</span>=<span class="attribute-value">"submit"</span> <span class="attribute">value</span>=<span class="attribute-value">"Submit the form"</span>  </li> <li class="alt"><span class="tag">&lt;/</span><span class="tag-name">form</span><span class="tag">&gt;</span>  </li> </ol> </div> <p>due to the missing <code>&gt;</code> on the <code>input</code> tag.</p> </div> <div id="section_20"> <h3 class="editable">Don't leave experiments that didn't work in your code</h3> <div class="editIcon"> <h3 class="editable"><a href="/en/Web_development/Writing_forward-compatible_websites?action=edit&amp;sectionId=20" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="/skins/common/icons/icon-trans.gif"></span></a></h3> </div> <p>If you try using a CSS property to do something you want, but it has no effect, remove it.  It might start doing something you don't expect in the future.</p> </div>
</div>
Revert to this revision