本文章是由機器翻譯。

HTML5

瀏覽器和功能偵測

Sascha p。Corti

 

現在建置網站,不僅要外觀亮眼,還要能歷久彌新。也就是說,您的網站不僅要能夠在當今的瀏覽器內運作,在未來的版本也要能夠運作才行。本文中我將提供秘訣和最佳作法,可協助您達到這個目的。

位元的歷程記錄

現在,所有的 Web 瀏覽器都以一個共同的目標中建置: 最新的規格的最佳方式呈現網頁。

這不見得一定代表這種情況。在過去,如瀏覽器廠商好友成為基準,已經最即使它們未尚未標準化實作高的需求中的功能。當然,每個瀏覽器中它自己的方式進行過它。以下是範例的方式設定在 CSS 中的投影片各不相同。

第 8 版瞭解下列 CSS 之前,就會 Internet Explorer:

    .transparent {      /* Internet Explorer < 9 */
        width: 100%;
        filter:alpha(opacity=50);
    }

雖然 Firefox 有它自己的屬性:

    .transparent {
        /* Firefox < 0.9 */
        -moz-opacity:0.5;
    }

如未 Safari:

    .transparent {
        /* Safari < 2 */
        -khtml-opacity: 0.5;
    }

現在,不過,在 CSS3,沒有設定的項目透明度的統一的方式:

    .transparent {
        /* IE >= 9, Firefox >= 0.9, Safari >= 2, Chrome, Opera >= 9 */
        opacity: 0.5;
    }

雖然它看起來適合瀏覽器移來支援非標準功能額外的英哩,這會讓網頁開發人員的生命週期比需要的是,因為他加入網頁時所採取的所有各種實作功能的考量。

一致的標記

請確定網頁會最佳化所有瀏覽器中呈現的最佳方式是將焦點集中在確定所有的目前版本的瀏覽器可支援的標記。直到非常短,這是 HTML 4.01,10 年歷史標準非常有限的功能。

現在,將所有的瀏覽器正向多功能 HTML5,但許多新的一般詞彙,包括 HTML5 標記、 其 Api,例如 DOM 層級 2 和 3,CSS3、 SVG 與 EcmaScript 262,在合併彙算的規格仍在開發中且因此可能隨時變更。瀏覽器廠商持續加入新的 HTML5 功能,但很大的差異會在支援。

Firefox 和 Opera 是採用新的 HTML5 規格,有時候甚至那些在早期的開發過程中並進行變更,或有安全性問題通常非常快速。雖然這可能很有趣的開發人員若要測試新的功能,則會造成中斷之間的一種規格,它的實作之間的大幅變更因為瀏覽器版本的網頁。這是令人沮喪的經驗的使用者和開發人員。這個範例是 Firefox 4 停用測試 7 和 8 之間的 Websockets 限於安全性的理由。

組件區塊,這個方法也很快速,採用新的 HTML5 標準,最近,讓 HTML5 社群宣告它已放棄受歡迎的 h.264 視訊轉碼器支援 HTML5 <video> 項目,而切換免費 WEBM 標準。雖然這可能是很好的開發人員目前支付 h.264 授權,它會加入另一個開發人員必須追蹤的為了盡可能支援多個瀏覽器的選擇。

Microsoft 是實作標準,較慢,但它但與密切合作 W3C 來建置測試套件,減少模稜兩可的規格中,並建立來幫助 homogenizing 瀏覽器呈現 HTML5 的方式處理的廠商的技術基礎。若要查看最新的工作,在此] 區域,看看 Internet Explorer 10 平台預覽,您可以找到在 IE 測試一下。您也會想要簽出 HTML5labs Microsoft 原型的早期、 不穩定規格的 Web 標準組織如 W3C 的位置。請參閱] 區段中,"改進互通性,透過標準支援,」 Internet Explorer 9 輔助線,如需如何 Internet Explorer 9 支援各種 HTML5 規格今天的深入資訊的開發人員。

然而,由於新的 HTML5 標準維持目標,而且大部分的網際網路使用者不會使用各種 Web 瀏覽器的最新版本,做正確的標記是比以往更重要。

偵測瀏覽器

若要處理瀏覽器之間的差異的一種方法是使用瀏覽器偵測。若要這麼做最常見的方式是使用查詢的使用者代理標頭的 JavaScript:

    <script type="text/javascript">
      if ( navigator.userAgent.indexOf("MSIE")>0 )
      {
        // Run custom code for Internet Explorer.
    }
    </script>

這個方法的問題有雙重。 首先,它可將多個假設在一次檢查的瀏覽器支援的功能。 單一的錯誤假設可能會破壞的網站。 因此,身為開發人員,您必須完全相同的功能每個版本的特定瀏覽器支援追蹤。

第二個問題就此瀏覽器檢查不會將瀏覽器版本列入考量,因此不是未來證明。 即使它使用今天的版本的瀏覽器時,可能不需要在下一版,或更糟的是,可能會移除支援完全 — 因應措施偵測瀏覽器用來新增至網站。

因此,如果您有使用瀏覽器偵測,請確定您考慮版本,只能使用這種方法來偵測舊版瀏覽器中,如所示圖 1

偵測舊版瀏覽器的 [圖 1

    <script type="text/javascript">
      functiongetInternetExplorerVersion()
      // Returns the version of Internet Explorer or a -1 for other browsers.
    {
        var rv = -1;
        if(navigator.appName == 'Microsoft Internet Explorer')
        {
          var ua = navigator.userAgent;
          varre  = newRegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
          if(re.exec(ua) != null)
          rv = parseFloat( RegExp.$1 );
        }
        return rv;
      }
      functiononLoad()
      {
        var version = GetInternetExplorerVersion()
        if (version <= 7 && version > -1)
        {
          // Code to run in Internet Explorer 7 or earlier.
    }
      }
    </script>

MSDN 程式庫] 頁面上,「偵測瀏覽器更有效地,「 更多的資訊,以及您可以找到如何使用巡覽器物件和規則運算式來偵測各種的瀏覽器,並在其確切的版本是完整的文件 JavaScript 教學課程

從第 5 版開始,Internet Explorer 都有唯一的方法,可偵測瀏覽器使用條件式註解。 這個語法會延伸標準的 HTML 註解。 您可以使用這些條件式註解 CSS 實作某些 Internet Explorer 特定 CSS 規則想要略過的其他瀏覽器。 在下列範例中,偵測到 Internet Explorer 7 或更早版本時,才會載入"ie7.css":

    <!--[if lte IE 7]>
      <style TYPE="text/css">
        @import url(ie7.css);
      </style>
    <![endif]-->

如何使用條件式註解的詳細的資訊,請參閱 MSDN 文件庫] 頁面上,在"條件式註解的相關。"

指定所有的問題和限制瀏覽器偵測,不過,我們看另一個方法。

偵測功能

以比較好的方法來處理 Web 瀏覽器之間的差異是使用偵測功能。在使用前一項功能,您知道具有不同的實作在各種瀏覽器中,您可以執行小型的測試,會尋找特定的物件、 方法、 屬性或行為的可用性。在大多數情況下這可以藉由嘗試建立新的執行個體的功能有問題,如果該執行個體化傳回 null 以外的其他項目,正在執行的瀏覽器會知道這項功能。如果沒有,您可以藉由測試因應措施的可用性或專屬的繼承實作功能的追蹤。

比較的瀏覽器和功能偵測

我們將使用中的圖表數字 2,34 若要協助視覺化這兩種方法在不同狀況下的運作方式。


[圖 2 簡單程式碼路徑透過測試網站


[圖 3 的結果與已知的瀏覽器設定

已知的瀏覽器設定時,就會使用這兩種方法,但偵測瀏覽器功能 a 和 b 功能所支援的瀏覽器中,固定的假設而功能偵測個別測試每個功能。


圖 4] 的 [無法辨識瀏覽器設定

它是所面臨的事情就有趣了未知的瀏覽器設定。功能偵測處理這個格式與找出瀏覽器可顯示功能 a,但需要回溯程式碼的功能 b。瀏覽器偵測,相反地,來選擇路徑,根據瀏覽器的名稱,或選擇的預設路徑,因為查詢的瀏覽器版本組合都不相符。不管怎麼說,在這個範例中的頁面將不會正確呈現因為沒有程式碼路徑連接的所有有效的程式碼區段,即使頁面實際上包含所有正確地顯示在此無法辨識的瀏覽器設定所需的程式碼。

功能偵測範例

有兩個非常重要的建議,可使用偵測功能時,請記住:

  • 一定先測試標準因為瀏覽器通常支援較新的標準,以及舊版的因應措施。
  • 目標永遠只相關功能的單一核取、 有效地最小化的瀏覽器能力的假設。

現在讓我們看看一些功能偵測的範例。

下列指令碼會建立兩個程式碼路徑。若瀏覽器支援 window.addEventListener,但如果沒有,請探查的傳統可用性功能的 window.attachEvent,它首先會檢查:

    <script type="text/javascript">
      if(window.addEventListener) {
        // Browser supports "addEventListener"
        window.addEventListener("load", myFunction, false);
      } else if(window.attachEvent) {
        // Browser supports "attachEvent"
        window.attachEvent("onload", myFunction);
      }
    </script>

另一個很好的方法是來封裝功能偵測到一組可以用在程式碼的函式。 以下是最佳的作法,來偵測瀏覽器是否支援 HTML5 <canvas> 項目,如果是的話,可確保的 canvas.getContext('2d') 方法以及運作。 這個函式只會傳回 true 或 false,使其更容易重複使用。

    <script type="text/javascript">
      functionisCanvasSupported()
      {
        var elem = document.createElement('canvas'); 
        return!!(elem.getContext && elem.getContext('2d');
      }
    </script>

一件事来牢記在心,當使用偵測功能是永遠使用它在新建立的項目或物件,因此避免可能表示在頁面上的任何其他指令碼已修改過的項目或物件自建立以來,因而可能會造成隨機或異常的結果。

偵測功能也可以直接對一些 HTML 項目,例如 <video>,HTML5 <audio>,和 <canvas> 形式的 「 後援"。瀏覽器會顯示第一個支援的子項目,從頂端,並以視覺化方式隱藏的項目。

最簡單的表單看起來像這樣:

    <video src="video.mp4">
        Your browser doesn't support videos natively.
    </video>

支援 <video> 的瀏覽器 項目會顯示視訊的"video.mp4",而不是瀏覽器會改為使用提供的文字。 但是,後援也適合視訊的標記中的各種視訊格式:

    <video>
        <source src="video.mp4" type="video/mp4" />
        <source src="video.webm" type="video/webm" />
        Your browser doen't suppport videos natively.
    </video>

在此情況下,瀏覽器支援的 HTML5 <video> 將會先嘗試載入 mp4 視訊。 如果它不支援這種格式,它將會改為使用 webm 編碼視訊。 應該該格式不支援或瀏覽器不支援 <video> 就會回歸到文字。

當然,它更有意義改為外掛程式的視訊播放程式,而非文字,以防瀏覽器不支援 HTML5 <video> 在所有項目。 下列範例會使用 Silverlight 視訊播放程式:

    <video>
        <source src="video.mp4" type='video/mp4' />
        <source src="video.webm" type='video/webm' />
        <object type="application/x-silverlight-2">
            <param name="source" value="http://url/player.xap">
            <param name="initParams" value="m=http://url/video.mp4">
        </object>
        Download the video <a href="video.mp4">here</a>.
    </video>

類似的邏輯也適用於 CSS。 Css,只會忽略無法辨認的屬性。 因此當您想要新增多個實驗]、 [供應商為字首的內容,如 「 框線半徑 」 下面所示,您只可以包含所有變量在程式碼中。 這可能會覺得有點不精確,但它很容易使用,並取得這種情況下,完成工作。 請注意將您想要包含第一次的廠商特定首碼的最佳作法與標準的標記上一次。

    <style type="text/css">
        .target
        {
            -moz-border-radius: 20px;
            -webkit-border-radius: 20px;
            border-radius: 20px;
        }
    </style>

功能偵測大優點是它也適用於您沒有甚至思考建立您的網頁時,即使與未來版本的瀏覽器因為它不會依賴哪些功能假設瀏覽器支援的瀏覽器。

開發和測試功能偵測

F12 開發者工具 Internet Explorer 9 中非常適合在開發和測試功能偵測跨許多瀏覽器。您可以使用這些偵錯指令碼的逐步解說和變更瀏覽器的使用者代理字串,也知道要使用前一版的轉譯引擎的 Internet Explorer**.**找 5、 6、 7 和 8 顯示一些範例,告訴您可以使用這些工具。


使用中斷點,偵錯在 Internet Explorer 9 的 JavaScript 時的 [圖 5


圖 6] 中執行 「 文件模式: IE9 標準,」 bBrowser 使用現代的 addEventListener 方法


圖 7] 中執行 「 文件模式: IE7 標準,「 偵錯工具落回傳統 attachEvent 方法


圖 8 您可以變更 Internet Explorer 使用者代理字串即時和甚至新增您自己的字串,包括行動瀏覽器

在大型專案中的管理功能偵測

建立複雜的 Web 專案時,表示建立及管理所有的功能偵測程式碼很瑣碎無聊。幸好有絕佳 JavaScript 庫可用,也就是協助評估, ModernizrjQuery

Modernizr 的 HTML5 和 CSS3 的多數功能是非常容易使用您的程式碼中的內建偵測。它有非常廣泛採用,並不斷增強。Modernizr 和 jquery 也被隨附 ASP。NET MVC 工具。

看一下中的程式碼圖 9,它會偵測瀏覽器的功能,以顯示網頁字型,而不使用 Modernizr,然後在中的程式碼 圖 10 ,並使用 Modernizr。

圖 9,而不會 Modernizr

function(){
  var
    sheet, bool,
    head = docHead || docElement,
    style = document.createElement("style"),
    impl = document.implementation || { hasFeature: function()
      { return false; } };
    style.type = 'text/css';
    head.insertBefore(style, head.firstChild);
    sheet = style.sheet || style.styleSheet;
    var supportAtRule = impl.hasFeature('CSS2', '') ?
function(rule) {
        if (!(sheet && rule)) return false;
          var result = false;
          try {
            sheet.insertRule(rule, 0);
            result = (/src/i).test(sheet.cssRules[0].cssText);
            sheet.deleteRule(sheet.cssRules.length - 1);
          } catch(e) { }
          return result;
        } :
        function(rule) {
          if (!(sheet && rule)) return false;
          sheet.cssText = rule;
          return sheet.cssText.length !== 0 &&
            (/src/i).test(sheet.cssText) &&
            sheet.cssText
              .replace(/\r+|\n+/g, '')
              .indexOf(rule.split(' ')[0]) === 0;
        };
    bool = supportAtRule('@font-face { font-family: "font";
    src: url(data:,); }');
    head.removeChild(style);
    return bool;
  };

圖 10 與 Modernizr

    <script type="text/javascript" src"modernizr.custom.89997.js"></script>
    <script type="text/javascript">
      if(Modernizr.fontface){
        // font-face is supported
      }
    </script>

新增遺失的功能的支援

偵測功能並不會消除當測試的瀏覽器不支援您所需要的功能,接下來的因應措施的負擔。 在先前的 HTML5 視訊範例,為後援使用 Silverlight 是明顯的解決方案。 但其他 HTML5 的功能,該怎麼想 <canvas> 新的語意標記,例如 <nav>、 <section> 或 和 <article>,<aside>,或新的 <header> 而 <footer>?

越來越多的現成 「 回溯 」 對許多 HTML5 功能,即為 「 相容性修正減緩,polyfills,可以簡化的負擔。 這些檔案出現在 CSS 和 JavaScript 程式庫的表單中或有時候般或 Silverlight 控制,您可以使用在專案中,否則不支援的瀏覽器中加入遺失的 HTML5 功能。

基本概念是開發人員應該要能夠使用 HTML5 的 Api,開發和指令碼可以建立的方法和應該存在的物件。 開發未來證明這樣表示使用者升級,因為程式碼並不需要變更,使用者就會完全移到更好的原生經驗。

相容性修正和 polyfills 之間的差異是只模擬的相容性修正的功能,以及每一個都有自己專屬的 API,而 polyfills 模擬 HTML5 功能本身和其確切的 API。 因此,一般來說,使用 polyfill 讓您不必採用專屬的 API 麻煩。

HTML5 跨瀏覽器 Polyfills github 集合包含日益增加可用的相容性修正和 polyfills 的清單。

Modernizr,例如,包括語意標記支援,"HTML5Shim",但是很容易就可以載入其他相容性修正和 polyfills,如果 Modernizr 偵測到不支援的功能。

動態加入支援

您也許會自問,「 不加入這些指令碼程式庫對我的頁面大和載入速度緩慢,? 」

這就是,則為 true,使用許多這些支援程式庫也可以將負荷量加入至您的網站,因此以動態方式載入它們,只有在真正需要時才有意義。 情況下 shim 或 polyfill 中,最佳的作法是您已偵測到瀏覽器不支援原生 HTML5 功能時才載入。

一次我們幸運因為有很好的程式庫支援這種情況下確實: yepnope.js

Yepnope 是非同步的資源載入器會與 JavaScript 和 CSS,完全以減少執行預先載入。 這表示您擁有完全控制何時執行您的資源,而且您可以變更即時的順序。 Yepnope 會整合在 Modernizr 2 中,但也可以單獨使用。 讓我們看看它的語法:

    <script type="text/javascript" src="yepnope.1.0.2-min.js"></script>
    <script type="text/javascript">
        yepnope({
            test : Modernizr.geolocation,
            yep  : 'normal.js',
            nope : ['polyfill.js', 'wrapper.js']
        });
    </script>

從 [Yepnope] 頁面的本範例測試使用使用 Modernizr 的 HTML5 geolocation 的瀏覽器的能力。如果支援,則會載入自己的程式碼 (normal.js)。 否則,將會載入自訂的 polyfill (也包含 polyfill.js 和 wrapper.js)。

最重要的點,摘要於圖 11

圖 11 偵測瀏覽器和功能偵測守則

  DO 不要
偵測瀏覽器

請試著儘量避免。

-或-

針對特定瀏覽器測試版本。

做為未來的瀏覽器的假設,藉由只測試瀏覽器名稱。
偵測功能 第一次測試的標準。 假設不相關的功能所面臨一項測試。

資源:

深入了解在瀏覽器和功能偵測:

Sascha p。 Corti  適用於以將焦點放在 Microsoft 系統平台和開發人員工具,開發人員編輯的 Microsoft 瑞士,他會介紹瑞士的開發人員社群最新的趨勢。他目前著重於 Web 技術和 Windows Phone 7 平台。

他研究涉及式乙太網路蘇黎世在電腦科學和資訊管理在大學的蘇黎世。

這七年為 Sascha 的軟體開發人員和架構設計人員的主要瑞士銀行,他曾為美國 hi-tech 公司,包括矽圖形和 Microsoft 系統工程和技術專家。

您可以讀到他最新的活動,在他難怪上 http://techpreacher.corti.comhttp://blogs.msdn.com/swiss_dpe_team/ 或 Twitter 上都追隨他 @ TechPreacher

*感謝到下列的技術專家來檢閱這份文件: Justin Garret ,*Thomas Lewis