幾行代碼徹底解決HTML5在低版本瀏覽器中兼容性問題

 HTML5 有許多激動人心的特性,有了新的標籤、新的CSS 能力和新的JavaScript API,Web 的能力範圍有了大的飛躍。除了瀏覽器廠商的士氣高漲以外,使人激動的新功能列表幾乎天天都在增長。從「nightly builds」(每夜都構建一版)到開發渠道發行版和正常的平臺預覽版,瀏覽器在飛速變化,世界各地Web 開發人員們正在加入這個狂歡。
可是,儘管開發和瀏覽器社區正在把HTML5 的喧囂推到一個極度興奮的高潮,網上的大多數人卻不像咱們同樣使用最新的瀏覽器和最新版本。若是你是一個大型開發機構的Web 開發人員或者是擁有龐大用戶羣的大企業,那你對此可能很清楚。即便你爲經過Web 提供服務的小型機構或新創立的企業工做,你可能也要花上大量時間來確保本身的網站可以支持儘量多的瀏覽器和瀏覽器版本。  
基於這一現實,很容易看出,HTML5 還談不到它是否已爲當今的使用作好準備,而是你是否爲它作好了準備。例如,假設你用一些新的語法標籤(例如和)新建了一個頁面,添加了一些新的CSS 功能,例如圓角(border-radius)和陰影(box-shadow),甚至添加了一個元素在頁面上繪製出一個HTML5 標識。  
在較新的瀏覽器上,例如Internet Explorer 九、Firefox 4 及以上版本、或者Google Chrome上,這個頁面的顯示如圖1 所示。但若是嘗試在Internet Explorer 8 或更早的瀏覽器上加載頁面,頗有可能看到的是圖2 所示的效果:一個殘缺不全的頁面。
 javascript

a.png

1 小時前 上傳php

下載附件 (77.97 KB)html


  若是你在研究HTML5 的全部強大功能卻獲得上述體驗以後告訴本身說:最好仍是等等,那麼我不會對你有任何責怪。若是我問你準備好了嗎?你很容易得出這樣的結論:HTML5 尚未爲你或你的用戶作好準備。  
在你決定等到2022 年再考慮HTML5 的以前,我建議你繼續閱讀本文的後面部分,我將向你提供一些實用的策略,讓你如今就能採用HTML5 技術,同時避免出現圖2 所示的糟糕的降級狀況。我將從下面三個主題進行詳細地介紹:
  •功能檢測與用戶代理(UA)嗅探比較
  •用 JavaScript 實現填補(Polyfill)
  •優雅降級
  這些應該能夠教會你不少構建支持各類瀏覽器的網站所須要瞭解的知識。在本文結束時,你會擁有一個可靠的策略,能夠充滿自信、絕不猶豫地採用HTML5 技術。你還會擁有一些工具在手,能夠逐步地爲新瀏覽器加強網站,同時更好地適應舊的瀏覽器。由於HTML5 的採用策略就是一個瀏覽器也不放棄。
  1、功能檢測的重要性
  爲了提供跨瀏覽器的穩定且一致的體驗,開發人員常常須要得到一些關於用戶瀏覽器的信息。之前的廣泛作法是像下面這樣用JavaScript 檢測這些信息:  
 html5

  1. varuserAgent = navigator.userAgent;
  2. if (userAgent.indexOf('MSIE') >= 0) {
  3. console.log("Hello, IE user");
  4. } else if (userAgent.indexOf('Firefox') >= 0) {
  5. console.log("Hello, Firefox user");
  6. } else if (userAgent.indexOf('Chrome') >= 0) {
  7. console.log("Hello, Chrome user");
  8. }

複製代碼java


  這個技術稱爲用戶代理(UA)嗅探,普遍地用於判斷正在請求頁面的是哪一個瀏覽器。這裏的思路是:知道了用戶的瀏覽器(例如IE7),就能在運行的時候決定啓用或禁用網站的哪項功能。UA 嗅探就至關於對瀏覽器說:「你是誰?」(對UA 嗅探以及其餘檢測技術的深刻分析,請參閱http://t.cn/zOi5m72)
  這種作法的問題在於,瀏覽器會撒謊。UA 字符串是一個用戶能夠配置的信息,並不會提供100%正確的瀏覽器信息。並且,隨着這一技術的普遍採用,許多瀏覽器廠商在本身的UA 字符串中增長了額外內容,用來欺騙腳本,讓腳本對於實際使用的瀏覽器作出錯誤判斷,從而避免檢測。如今有些瀏覽器甚至提供小工具,容許用戶只要輕輕點擊幾下鼠標,就能修改UA 字符串。
  UA 嗅探的目的歷來就不是肯定用戶的瀏覽器和版本。並且它確定也不是爲了在你不喜歡用戶使用的瀏覽器時,讓你能夠告訴用戶說「請下載另外一個瀏覽器」——即便有些人就是這樣使用UA 嗅探技術的。用戶有權選擇本身使用什麼瀏覽器,開發人員的職責則是提供最可靠且一致的體驗,不要把瀏覽器的偏好強加給用戶。UA 嗅探的目標是讓你可以準確地瞭解在用戶當前的瀏覽器中,有哪些能力或功能能夠利用。對瀏覽器自己的瞭解,只是得到這些信息的一個途徑。目前有一些UA 嗅探的替代技術,其中一項正在日益流行的技術稱爲對象檢測或功能檢測。這兩個術語多數時候能夠互換使用,但本文統一使用「功能檢測」(feature detection)。功能檢測的目標是判斷某項功能或能力在用戶當前的瀏覽器中是否受支持。若是UA 嗅探是問瀏覽器「你是誰」,「功能檢測」就是問瀏覽器「你能幹什麼」,這個問題更直接,對於根據條件向用戶提供功能來講,這種方法也更可靠。若是功能檢測腳本實現正確,用戶或瀏覽器將很難造假或錯報功能支持。

  2、手動功能檢測
  那麼,與UA 嗅探的示例相比,功能檢測究竟是什麼樣呢?爲了回答這個問題,咱們先來看看若是在Internet Explorer 8 中查看前面的HTML5 頁面(如圖1 所示),如何解決出現的問題。這個頁面的標籤內容如代碼段1 所示。

 canvas

  1. <!DOCTYPE html>
  2. <htmllang="en">
  3. <head>
  4. <meta charset="utf-8" />
  5. <title>My Awesome Site</title>
  6. <style>
  7. body { font-size: 16px; font-family: arial,helvetica,clean,sans-serif; }
  8. header h1 { font-size: 36px; margin-bottom: 25px; }
  9. article
  10. {
  11. background: lightblue;
  12. margin-bottom: 10px;
  13. padding: 5px;
  14. border-radius: 10px;
  15. box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.5);
  16. }
  17. article h1 { font-size: 12px; }
  18. </style>
  19. </head>
  20. 37
  21. <body>
  22. <header><h1>My Awesome Site</h1></header>
  23. <article>
  24. <header><h1>An Article</h1></header>
  25. <p>Isn't this awesome?</p>
  26. </article>
  27. <canvas width="250" height="500"></canvas>
  28. </body>
  29. <script src="../js/html5CanvasLogo.js" type="text/javascript"></script>
  30. </html>

複製代碼
  代碼段1 帶有HTML5 新語義標籤的頁面
  如圖1 和圖2 所示,Internet Explorer 9 和 Internet Explorer 8 的顯示效果有很大的差異。對於初學者來講,個人頁面徹底沒有樣式,由於這個頁面的CSS 並不存在。並且,頁面底部丟失了好玩的HTML5 盾牌。每一個問題均可以輕鬆解決,而功能檢測則是明確問題的第一步。兩個問題的緣由都很簡單:對於Internet Explorer 8 來講,、和都不是有效的HTML 元素,因此沒法使用。要解決問題,咱們不用UA 嗅探來判斷所使用的瀏覽器/版本,而要經過JavaScript 詢問瀏覽器是否支持元素和它的JavaScript API,對Canvas 的功能檢測以下所示:
 瀏覽器

  1. !!document_createElement_x_x('canvas').getContext

複製代碼異步


  這條語句作了好幾件事:首先,它使用兩個否認(!!)操做符強行將未定義的值顯式地設爲false;而後,它手動新建一個canvas 元素,並將它加到DOM 中;最後,它調用getContext函數,這是元素的一個新函數,是經過JavaScript 操縱Canvas API 的途徑。若是使用IE9,則這條語句會返回true。若是使用IE8,則getContext會返回「undefined」(未定義),會被前面的兩個否認操做符強行變爲false。
  這是最基本的功能檢測。利用這條語句以及其餘相似語句,就有了查詢瀏覽器所支持功能的更可靠方法。關於手動功能檢測的更多信息,請參閱diveintohtml5.info/everything.html

  3、使用Modernizr進行功能檢測
  手動功能檢測確定是對UA 嗅探的提升,但這種作法仍然須要你作大量工做來檢測功能是否可用,以及在功能不存在的時候決定作什麼。雖然Canvas 示例很簡單,只須要一行代碼,但不是每一個要檢測的功能都這麼簡單——不一樣瀏覽器的檢測代碼也各不相同。例如,要檢測是否支持前面使用的CSS3 模塊(border-radius 和box-shadow)就有些麻煩。值得慶幸的是,Modernizr (modernizr.com) 提供了更好的方法。Modernizr是一個JavaScript 庫「……檢測下一代 Web 技術(即源於HTML 5 和CSS3 規範的功能)的本地實現是否可用」。在頁面上添加對Modernizr的引用能夠提供四大功能:
  1) 全面列出支持的功能,智能地加入標籤,從而實現CSS 的條件定義。
  2) 一個 JavaScript 對象,方便進行基於腳本的功能檢測。
  3) 在運行的時候將所有HTML5 新標籤加入DOM,方便IE8 和以前的IE 瀏覽器(稍  後就會知道不只如此)。
  4) 一個腳本加載器,能夠根據條件將polyfill加載到頁面中。

  本文對第1 項不作進一步介紹,但鼓勵你訪問modernizr.com 網站,學習這一功能及其他功能的文檔。
  上面的第2 項功能,能夠將下面的代碼:  
 函數

  1. !!document_createElement_x_x('canvas').getContext

複製代碼工具


  改成這行代碼:
 

  1. Modernizr.canvas

複製代碼


  這行代碼會返回一個布爾值,代表頁面是否支持Canvas 元素。使用Modernizr比自行執行功能檢測的好處是,Modernizr是一個通過良好測試、健壯的、廣爲採用的庫,它已經完成了許多繁重的工做。Twitter、Google、Microsoft 以及無數其餘機構和開發人員都在使用Modernizr,你固然也可使用。在ASP.NET MVC 3 工具更新(2011 年4 月發佈)中,Microsoft甚至隨新的ASP.NET MVC 應用程序一塊兒配備了Modernizr。固然,咱們迄今爲止所作的,不過是檢測是否支持元素。經過功能檢測知道了瀏覽器是否支持某一功能以後,接下來一般是建立一些條件邏輯,在功能不存在的時候阻止特定代碼的執行或者換個路徑來執行,例如:
 

  1. if (Modernizr.canvas) {
  2. // 這裏執行canvas 代碼。
  3. }

複製代碼


  根據附加的瀏覽器功能是否存在來給網站增長功能,這種作法稱爲「漸進式加強」,由於體驗加強針對的能力更強的瀏覽器。另外一方面是「優雅降級」,即某項功能的缺失不會形成瀏覽器出錯或發生故障,而是應該向用戶提供一些削弱的功能或替代能力。對於舊版瀏覽器來講,沒必要將優雅降級做爲默認選擇。在許多狀況下,甚至可能不是最佳選擇。相反,在Modernizr的幫助下,你一般可使用許多可用的瀏覽器polyfill,將相似於HTML5 的功能添加到不支持HTML5 的瀏覽器中。

  4、什麼是Polyfill
  根據Modernizr網站的說法,polyfill是「在舊版瀏覽器上覆制標準API 的JavaScript 補充」。「標準API」指的是HTML5 技術或功能,例如Canvas。「JavaScript 補充」指的是能夠動態地加載JavaScript 代碼或庫,在不支持這些標準API 的瀏覽器中模擬它們。例如,geolocation(地理位置)polyfill能夠在navigator 對象上添加全局的geolocation對象,還能添加getCurrentPosition函數以及「座標」回調對象,全部這些都是W3C 地理位置API 定義的對象和函數。由於polyfill模擬標準API,因此可以以一種面向全部瀏覽器將來的方式針對這些API 進行開發,最終目標是:一旦對這些API 的支持變成絕對大多數,則能夠方便地去掉polyfill,無需作任何額外工做。
  經過在頁面上添加對Modernizr的引用,我就獲得了與代碼段1 示例相關的polyfill的直接好處。頁面顯示沒有樣式,是由於IE8 不認識<article>和<header>標籤。由於它不認識這些標籤,因此沒將它們加入DOM,而CSS 選擇元素要發揮樣式做用,須要在DOM 中有這些元素。當我在頁面上添加<script>標籤和對Modernizr的引用時,結果就有了樣式,如圖3 所示。我之因此獲得這個好處,是由於Modernizr用JavaScript(document_createElement_x(‘nav’))手動地將全部HTML5 的新標籤添加到DOM,這樣CSS 就能選擇標籤並給標籤加上樣式。

b.png

 除了在Internet Explorer 中添加對新的HTML5 元素的支持外,Modernizr庫默認不提供任何額外的polyfill。額外的polyfill須要自行提供,或者使用本身的腳本,或者從Modernizr網站上日益增長的選項列表中選擇一個。在2.0 版中,Modernizr提供了一個條件腳本加載器(基於yepnope.js—yepnopejs.com),能夠幫助你只在須要的時候異步下載polyfill庫。使用Modernizr配合一個或多個polyfill庫來提供須要的功能,是一個強大的組合。

5、使用Polyfill模擬HTML5 功能
對於Canvas 來講,在Modernizr和JavaScript 庫excanvas的幫助下,用polyfill能夠在IE8 及以前的版本中實現Canvas 支持,能夠在IE六、IE7 和IE8 上添加API 級別的Canvas支持。能夠從bit.ly/bSgyNR下載excanvas,將它添加到本身的腳本文件夾,而後在頁面的腳本塊中添加一些代碼,如代碼段2 所示。
 

  1. Modernizr.load({
  2. test: Modernizr.canvas,
  3. nope: '../js/excanvas.js',
  4. complete: function () {
  5. Modernizr.load('../js/html5CanvasLogo.js');
  6. }
  7. }]);

複製代碼

 

 

代碼段3 用Modernizr和PIE 添加CSS3 支持

c.png

 6、使用Polyfill協助進行優雅降級
除了使用這裏討論的polyfill技術,在但願應用程序優雅降級的地方也能夠藉助於Modernizr,而不是用另外一個庫進行填補(polyfill)。
假設網頁上有一個Bing Maps 控件,並且我但願使用Geolocation來肯定用戶當前位置,而後將這個位置做爲大頭釘放在地圖控件上。雖然新版本的瀏覽器都支持Geolocation,但在舊版瀏覽器中並不支持。純粹使用JavaScript 提供完整的Geolocation支持還確實有些麻煩,即便有針對Geolocation的填補(polyfill)
實現起來也不輕鬆,因此我決定要對本身的應用程序進行優雅降級。當用戶的瀏覽器不支持Geolocation時,我會提供一個表單,用戶能夠在表單中手動輸入位置,我將用用戶輸入的位置定位和固定地圖。
經過Modernizr,只要用一個簡單的加載腳本,調用我建立的兩個腳本中的一個便可,如代碼段4 所示。在這個示例中,我測試的是Modernizr.geolocation屬性。若是爲true(「yep」分支),就加載fullGeolocation.js 腳本,這個腳本使用Geolocation API 定位(要獲得用戶許可),並將位置放在地圖上,如圖5 所示。若是測試爲false(「nope」分支),則加載備用腳本,在頁面上顯示一個地址表單。用戶提交表單時,我會使用用戶提供的地址將地圖居中並固定,如圖6 所示。這樣,個人頁面爲最新的瀏覽器提供了優秀的體驗,同時對舊版瀏覽器提供了降級到合理替代品的優雅方式。

  1. Modernizr.load({
  2. test: Modernizr.geolocation,
  3. yep: '../js/fullGeolocation.js',
  4. nope: '../js/geolocationFallback.js'
  5. });

 

 代碼段4 用Modernizr提供優雅降級
d.png

e.png

  在面對龐大的用戶羣仍然使用舊版瀏覽器的時候,很容易認爲HTML5 的一些高級功能對你的網站不適用。可是如今已經有了很好的解決方案,不只可以幫助你優雅地降級,還能提高舊版瀏覽器的能力,讓你的用戶當即就能體驗到HTML5 的能力。在本文中,你看到了功能檢測、Modernizr和polyfill,因此你能夠絕不遲疑地採用HTML5,既知足日益增加的使用最新瀏覽器的用戶,又不會丟失使用舊版瀏覽器的龐大用戶羣。而咱們要作的,不光是讓網站適應舊版瀏覽器,更多的是要讓用戶更好的體驗到網站的內容,若是你想要了解更多內容,能夠參考下IE10兼容性白皮書,相信你會得到不少幫助,下載地址:http://vdisk.weibo.com/s/bKgeq

相關文章
相關標籤/搜索