用Modernizr探測HTML 5/CSS3新特性
HTML5, CSS3以及相關(guān)技術(shù)(例如canvas和web sockets)帶來了非常有用的特性,可以讓我們的web程序提升一個(gè)新的level。這些新技術(shù)允許我們只用HTML,CSS和JavaScript就可以構(gòu)建包括在平板和移動(dòng)設(shè)備上能夠運(yùn)行的多樣化表單頁面。HTML5雖然提供了很多新特性,但是如果我們不考慮舊版本的瀏覽器就是用這些新技術(shù)也不太現(xiàn)實(shí),老版本瀏覽器已經(jīng)使用了很多年,我們依然需要考慮這些版本的兼容性問題。本文要解決的問題就是:在我們使用HTML5/CSS3技術(shù)的時(shí)候,如何更好地處理不支持HTML5/CSS3特性的舊版本瀏覽器問題。
51CTO推薦專題:HTML 5 下一代Web開發(fā)標(biāo)準(zhǔn)詳解
盡管我們可以自己寫代碼來判斷瀏覽器是否支持某些HTML5/CSS3特性,但是代碼都不是很簡單。例如:寫代碼判斷瀏覽器支付支持canvans,我們的代碼可能和下面的類似:
- <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下產(chǎn)生bug。
- <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個(gè)例子都是分別檢查一個(gè)特性,如果有很多HTML5/CSS3特性的話,我們不得不寫多份代碼來判斷,不過還算幸運(yùn)的是這些代碼沒有依賴順序。Modernizr可以讓你用很少的代碼來實(shí)現(xiàn)上述復(fù)雜的功能,讓我們來看一下Modernizr的一些重要特性:
開始使用Modernizr
第一次我聽到Modernizr的時(shí)候,我以為它的意思是modernized,可以在舊版本瀏覽器上添加一些HTML5/CSS3的新特性。事實(shí)上,Modernizr不是干這個(gè)的,它是幫助我們提高開發(fā)實(shí)踐的,使用一個(gè)非常時(shí)髦的方法來幫助探測瀏覽器是否支持某種新特性,甚至可以加載額外的script腳本。如果你是一個(gè)web開發(fā)人員的話,那對你來說它就是一件很牛逼的兵器。
Modernizr官方站點(diǎn):http://modernizr.com,2個(gè)類型的腳本你都可以使用(開發(fā)版和自定義的生產(chǎn)版本)。網(wǎng)站提供了一個(gè)自定義需求的工具來生成僅僅你需要的探測功能,而不是一個(gè)什么都可以探測的大而全的版本,就是說你可以讓你的腳本最小化。下圖是官方網(wǎng)站生成工具的界面,可以看到很多HTML5/CSS3和相關(guān)技術(shù)的探測功能都可以選擇上。

下載完你自定義的腳本以后,你就可以像引用普通js文件一樣引用它了,然后就可以用了。
- <script src="Scripts/Modernizr.js" type="text/javascript"></script>
Modernizr和HTML元素
添加完Modernizr引用以后,它就立即生效了。運(yùn)行的時(shí)候它會(huì)在html元素上添加一批CSS的class名稱,這些class名稱標(biāo)記當(dāng)前瀏覽器支持哪些特性和不支持哪些特性,支持的特性就直接顯示該天特性的名稱作為一個(gè)class(例如:canvas,websockets),不支持的特性顯示的class是“no-特性名稱”(例如:no-flexbox)。下面這段代碼是運(yùn)行在Chrome下的效果:
- <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">
下面這段代碼是運(yùn)行在IE9下的效果:
- <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,有可能會(huì)出現(xiàn)下面代碼的情況(添加no-js名稱到class里):
- <html class="no-js">
你可以訪問(http://html5boilerplate.com)站點(diǎn)查看HTML5 Boilerplate相關(guān)的內(nèi)容,或者(http://initializr.com)查看Initializr相關(guān)的內(nèi)容,添加no-js class到html元素下,是告訴瀏覽器是否支持JavaScript,如果不支持就顯示no-js,如果支持就把no-js刪掉。非常爽,對吧?
結(jié)合HTML5/CSS3特性一起使用
你可以直接使用Modernizr在元素里生成的class名稱,在你的css文件里定義相應(yīng)的屬性以便支持當(dāng)前瀏覽器。例如,下面的代碼可以屬性,在支持shadow陰影的瀏覽器顯示shadow,不支持的瀏覽器顯示標(biāo)準(zhǔn)的邊框:
- .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;
- }
因?yàn)槿绻麨g覽器支持box-shadows的話,Modernizr就會(huì)將boxshadow class添加到元素,然后你可以將它管理到一個(gè)相應(yīng)的div的id上。如果不支持,Modernizr就會(huì)將no-boxshadow class添加到元素,這樣顯示的就是一個(gè)標(biāo)準(zhǔn)的邊框。這樣我們就可以很方便地在支持CSS3特性的瀏覽器上使用CSS3新功能,不支持的瀏覽器上繼續(xù)使用以前的方式。
Modernizr除了添加相應(yīng)的class到元素以外,還提供一個(gè)全局的Modernizr JavaScript對象,該對象提供了不同的屬性來表示某種新特性在當(dāng)前瀏覽器下是否支持。例如,下面的代碼可以用于判斷瀏覽器是否支持canvas和local storag。對于多個(gè)開發(fā)人員在多版本瀏覽器下開發(fā)測試的時(shí)候很有好處的,大家可以統(tǒng)一代碼。
- $(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特性可以探測到結(jié)果,例如:opacity, rgba, text-shadow, CSS animations, CSS transitions, multiple backgrounds等等,Modernizr支持的完整的HTML5/CSS3可探測列表可以在如下http://www.modernizr.com/docs找到。
使用Modernizr加載Script腳本
在某些不支持新特性的瀏覽器上,Modernizr不僅僅提供了上述方式告訴你,也提供了load功能允許你加載一些shim/polyfill腳本來達(dá)到支持的目的(關(guān)于shim/polyfill的信息請?jiān)L問:https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills)。Modernizr提供了一個(gè)腳本加載器來判斷一個(gè)功能,如果不支持就加載相應(yīng)的腳本。單獨(dú)的腳本也可以在http://yepnopejs.com找到。
可以使用Modernizr的load()函數(shù)來動(dòng)態(tài)加載腳本,該函數(shù)的test屬性是表明要測試是否支持的新特性,如果測試成功支持的話,就加載yep屬性設(shè)置的腳本,如果不支持就加載nope屬性設(shè)置的腳本,不管是否支持,both屬性里設(shè)置的腳本都會(huì)加載的。例子代碼如下:
- Modernizr.load({
- test: Modernizr.canvas,
- yep: 'html5CanvasAvailable.js’,
- nope: 'excanvas.js’,
- both: 'myCustomScript.js'
- });
在該例子里,Modernizr會(huì)判斷當(dāng)前瀏覽器是否支持canvas特性,如果支持,那就會(huì)加載html5CanvasAvailable.js和myCustomScript.js這兩個(gè)腳本,如果不支持,就會(huì)加載excanvas.js(用于IE9之前的版本)腳本文件以讓該瀏覽器支持canvas功能,然后再加載myCustomScript.js腳本。
因?yàn)镸odernizr可以加載腳本,所以你還可以用于其它的用途,比如,如果你引用的第三方腳本(例如提供CDN服務(wù)的Google和Microsoft提供jquery的托管)加載失敗的情況下,可以加載備用的文件。下面的代碼是Modernizr提供的一個(gè)加載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'
- }
- ]);
該代碼會(huì)首先從Google CDN加載jQuery文件,如果下載或加載失敗,complete函數(shù)就會(huì)執(zhí)行,首先判斷jQeury對象是否存在,如果不存在,Modernizr就會(huì)加載定義好的本機(jī)js文件,如果連 complete里的文件都加載不成功,就會(huì)加載needs-jQuery.js文件。
總結(jié):
如果你正在使用最新的HTML5/CSS3來構(gòu)建你的程序,Modernizr絕對是一個(gè)必需的工具。使用它你可以節(jié)約很多代碼以及測試工作量,甚至可以對一些不支持新特性的瀏覽器通過額外加載腳本的形式來實(shí)現(xiàn)相應(yīng)的新特性。
原文:http://www.cnblogs.com/TomXu/archive/2011/11/18/detecting-html5-css3-features-using-modernizr.html
【編輯推薦】