HTML5, CSS3 以及相關技術(例如 canvas 和 web sockets)帶來了很是有用的特性,可讓咱們的 web 程序提高一個新的 level。這些新技術容許咱們只用 HTML,CSS 和 JavaScript 就能夠構建包括在平板和移動設備上可以運行的多樣化表單頁面。HTML5 雖然提供了不少新特性,可是若是咱們不考慮舊版本的瀏覽器就是用這些新技術也不太現實,老版本瀏覽器已經使用了不少年,咱們依然須要考慮這些版本的兼容性問題。本文要解決的問題就是:在咱們使用 HTML5/CSS3 技術的時候,如何更好地處理不支持 HTML5/CSS3 特性的舊版本瀏覽器問題。
儘管咱們能夠本身寫代碼來判斷瀏覽器是否支持某些 HTML5/CSS3 特性,可是代碼都不是很簡單。例如:寫代碼判斷瀏覽器是否支持 canvans,咱們的代碼可能和下面的相似:javascript
<script> window.onload = function () { if (canvasSupported()) { alert('canvas supported'); } }; function canvasSupported() { var canvas = document.createElement('canvas'); return (canvas.getContext && canvas.getContext('2d')); } </script>
若是要判斷是否支持本地存儲(local storage),代碼可能和下面的相似,可是很容易再 Firefox 下產生 bug。css
<script> window.onload = function () { if (localStorageSupported()) { alert('local storage supported'); } }; function localStorageSupported() { try { return ('localStorage' in window && window['localStorage'] != null); } catch(e) {} return false; } </script>
前面 2 個例子都是分別檢查一個特性,若是有不少 HTML5/CSS3 特性的話,咱們不得不寫多份代碼來判斷,不過還算幸運的是這些代碼沒有依賴順序。Modernizr 可讓你用不多的代碼來實現上述複雜的功能,讓咱們來看一下 Modernizr 的一些重要特性:html
開始使用 Modernizrhtml5
第一次我聽到 Modernizr 的時候,我覺得它的意思是 modernized,能夠在舊版本瀏覽器上添加一些 HTML5/CSS3 的新特性。事實上,Modernizr 不是幹這個的,它是幫助咱們提升開發實踐的,使用一個很是時髦的方法來幫助探測瀏覽器是否支持某種新特性,甚至能夠加載額外的 script 腳本。若是你是一個 web 開發人員的話,那對你來講它就是一件很牛逼的兵器。java
Modernizr 官方站點:http://modernizr.com,2 個類型的腳本你均可以使用(開發版和自定義的生產版本)。網站提供了一個自定義需求的工具來生成僅僅你須要的探測功能,而不是一個什麼均可以探測的大而全的版本,就是說你可讓你的腳本最小化。下圖是官方網站生成工具的界面,能夠看到不少 HTML5/CSS3 和相關技術的探測功能均可以選擇上。
下載完你自定義的腳本之後,你就能夠像引用普通 js 文件同樣引用它了,而後就能夠用了。<script src="Scripts/Modernizr.js" type="text/javascript"></script>
jquery
Modernizr 和 HTML 元素
添加完 Modernizr 引用之後,它就當即生效了。運行的時候它會在 html 元素上添加一批 CSS 的 class 名稱,這些 class 名稱標記當前瀏覽器支持哪些特性和不支持哪些特性,支持的特性就直接顯示該天特性的名稱做爲一個 class(例如:canvas,websockets),不支持的特性顯示的 class 是「no- 特性名稱」(例如:no-flexbox)。下面這段代碼是運行在 Chrome 下的效果:git
<html class=" js flexbox canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths">
下面這段代碼是運行在 IE9 下的效果:github
<html class=" js no-flexbox canvas canvastext no-webgl no-touch geolocation postmessage no-websqldatabase no-indexeddb hashchange no-history draganddrop no-websockets rgba hsla multiplebgs backgroundsize no-borderimage borderradius boxshadow no-textshadow opacity no-cssanimations no-csscolumns no-cssgradients no-cssreflections csstransforms no-csstransforms3d no-csstransitions fontface generatedcontent video audio localstorage sessionstorage no-webworkers no-applicationcache svg inlinesvg smil svgclippaths">
使用 Modernizr,有可能會出現下面代碼的狀況(添加 no-js 名稱到 class 裏):<html class="no-js">
你能夠訪問 (http://html5boilerplate.com) 站點查看 HTML5 Boilerplate 相關的內容,或者 (http://initializr.com) 查看 Initializr 相關的內容,添加 no-js class 到 html 元素下,是告訴瀏覽器是否支持 JavaScript,若是不支持就顯示 no-js,若是支持就把 no-js 刪掉。很是爽,對吧?web
結合 HTML5/CSS3 特性一塊兒使用ajax
你能夠直接使用 Modernizr 在元素裏生成的 class 名稱,在你的 css 文件裏定義相應的屬性以便支持當前瀏覽器。例如,下面的代碼能夠屬性,在支持 shadow 陰影的瀏覽器顯示 shadow,不支持的瀏覽器顯示標準的邊框:
.boxshadow #MyContainer { border: none; -webkit-box-shadow: #666 1px 1px 1px; -moz-box-shadow: #666 1px 1px 1px; } .no-boxshadow #MyContainer { border: 2px solid black; }
由於若是瀏覽器支持 box-shadows 的話,Modernizr 就會將 boxshadow class 添加到元素,而後你能夠將它管理到一個相應的 div 的 id 上。若是不支持,Modernizr 就會將 no-boxshadow class 添加到元素,這樣顯示的就是一個標準的邊框。這樣咱們就能夠很方便地在支持 CSS3 特性的瀏覽器上使用 CSS3 新功能,不支持的瀏覽器上繼續使用之前的方式。
Modernizr 除了添加相應的 class 到元素之外,還提供一個全局的 Modernizr JavaScript 對象,該對象提供了不一樣的屬性來表示某種新特性在當前瀏覽器下是否支持。例如,下面的代碼能夠用於判斷瀏覽器是否支持 canvas 和 local storag。對於多個開發人員在多版本瀏覽器下開發測試的時候頗有好處的,你們能夠統一代碼。
$(document).ready(function () { if (Modernizr.canvas) { //Add canvas code } if (Modernizr.localstorage) { //Add local storage code } });
全局的 Modernizr 對象也能夠用來探測是否支持 CSS3 特性,下面的代碼用於測試是否支持 border-radius 和 CSS transforms:
$(document).ready(function () { if (Modernizr.borderradius) { $('#MyDiv').addClass('borderRadiusStyle'); } if (Modernizr.csstransforms) { $('#MyDiv').addClass('transformsStyle'); } });
其它的一些 CSS3 特性能夠探測到結果,例如:opacity, rgba, text-shadow, CSS animations, CSS transitions, multiple backgrounds 等等,Modernizr 支持的完整的 HTML5/CSS3 可探測列表能夠在以下http://www.modernizr.com/docs 找到。
使用 Modernizr 加載 Script 腳本
在某些不支持新特性的瀏覽器上,Modernizr 不只僅提供了上述方式告訴你,也提供了 load 功能容許你加載一些 shim/polyfill 腳原本達到支持的目的(關於 shim/polyfill 的信息請訪問:https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills)。Modernizr 提供了一個腳本加載器來判斷一個功能,若是不支持就加載相應的腳本。單獨的腳本也能夠在 http://yepnopejs.com 找到。
可使用 Modernizr 的 load() 函數來動態加載腳本,該函數的 test 屬性是代表要測試是否支持的新特性,若是測試成功支持的話,就加載 yep 屬性設置的腳本,若是不支持就加載 nope 屬性設置的腳本,不論是否支持,both 屬性裏設置的腳本都會加載的。例子代碼以下:
Modernizr.load({ test: Modernizr.canvas, yep: 'html5CanvasAvailable.js’, nope: 'excanvas.js’, both: 'myCustomScript.js' });
在該例子裏,Modernizr 會判斷當前瀏覽器是否支持 canvas 特性,若是支持,那就會加載 html5CanvasAvailable.js 和 myCustomScript.js 這兩個腳本,若是不支持,就會加載 excanvas.js(用於 IE9 以前的版本)腳本文件以讓該瀏覽器支持 canvas 功能,而後再加載 myCustomScript.js 腳本。
由於 Modernizr 能夠加載腳本,因此你還能夠用於其它的用途,好比,若是你引用的第三方腳本(例如提供 CDN 服務的 Google 和 Microsoft 提供 jquery 的託管)加載失敗的狀況下,能夠加載備用的文件。下面的代碼是 Modernizr 提供的一個加載 jquery 的示例:
Modernizr.load([ { load: '//ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.js', complete: function () { if (!window.jQuery) { Modernizr.load('js/libs/jquery-1.6.4.min.js'); } } }, { // This will wait for the fallback to load and // execute if it needs to. load: 'needs-jQuery.js' } ]);
該代碼會首先從 Google CDN 加載 jQuery 文件,若是下載或加載失敗,complete 函數就會執行,首先判斷 jQeury 對象是否存在,若是不存在,Modernizr 就會加載定義好的本機 js 文件,若是連 complete 裏的文件都加載不成功,就會加載 needs-jQuery.js 文件。
總結:
若是你正在使用最新的 HTML5/CSS3 來構建你的程序,Modernizr 絕對是一個必需的工具。使用它你能夠節約不少代碼以及測試工做量,甚至能夠對一些不支持新特性的瀏覽器經過額外加載腳本的形式來實現相應的新特性。