1. 程式人生 > >使用Modernizr探測HTML5/CSS3新特性

使用Modernizr探測HTML5/CSS3新特性

HTML5, CSS3以及相關技術(例如canvas和web sockets)帶來了非常有用的特性,可以讓我們的web程式提升一個新的level。這些新技術允許我們只用HTML,CSS和JavaScript就可以構建包括在平板和移動裝置上能夠執行的多樣化表單頁面。HTML5雖然提供了很多新特性,但是如果我們不考慮舊版本的瀏覽器就是用這些新技術也不太現實,老版本瀏覽器已經使用了很多年,我們依然需要考慮這些版本的相容性問題。本文要解決的問題就是:在我們使用HTML5/CSS3技術的時候,如何更好地處理不支援HTML5/CSS3特性的舊版本瀏覽器問題。


儘管我們可以自己寫程式碼來判斷瀏覽器是否支援某些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下產生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個例子都是分別檢查一個特性,如果有很多HTML5/CSS3特性的話,我們不得不寫多份程式碼來判斷,不過還算幸運的是這些程式碼沒有依賴順序。Modernizr可以讓你用很少的程式碼來實現上述複雜的功能,讓我們來看一下Modernizr的一些重要特性:

開始使用Modernizr

第一次我聽到Modernizr的時候,我以為它的意思是modernized,可以在舊版本瀏覽器上新增一些HTML5/CSS3的新特性。事實上,Modernizr不是幹這個的,它是幫助我們提高開發實踐的,使用一個非常時髦的方法來幫助探測瀏覽器是否支援某種新特性,甚至可以載入額外的script指令碼。如果你是一個web開發人員的話,那對你來說它就是一件很牛逼的兵器。

Modernizr官方站點:http://modernizr.com,2個型別的指令碼你都可以使用(開發版和自定義的生產版本)。網站提供了一個自定義需求的工具來生成僅僅你需要的探測功能,而不是一個什麼都可以探測的大而全的版本,就是說你可以讓你的指令碼最小化。下圖是官方網站生成工具的介面,可以看到很多HTML5/CSS3和相關技術的探測功能都可以選擇上。

下載完你自定義的指令碼以後,你就可以像引用普通js檔案一樣引用它了,然後就可以用了。

<script src="Scripts/Modernizr.js" type="text/javascript"></script>

Modernizr和HTML元素

新增完Modernizr引用以後,它就立即生效了。執行的時候它會在html元素上新增一批CSS的class名稱,這些class名稱標記當前瀏覽器支援哪些特性和不支援哪些特性,支援的特性就直接顯示該天特性的名稱作為一個class(例如:canvas,websockets),不支援的特性顯示的class是“no-特性名稱”(例如:no-flexbox)。下面這段程式碼是執行在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">

下面這段程式碼是執行在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,有可能會出現下面程式碼的情況(新增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刪掉。非常爽,對吧?

結合HTML5/CSS3特性一起使用

你可以直接使用Modernizr在<html>元素裡生成的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新增到<html>元素,然後你可以將它管理到一個相應的div的id上。如果不支援,Modernizr就會將no-boxshadow class新增到<html>元素,這樣顯示的就是一個標準的邊框。這樣我們就可以很方便地在支援CSS3特性的瀏覽器上使用CSS3新功能,不支援的瀏覽器上繼續使用以前的方式。

Modernizr除了新增相應的class到<html>元素以外,還提供一個全域性的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絕對是一個必需的工具。使用它你可以節約很多程式碼以及測試工作量,甚至可以對一些不支援新特性的瀏覽器通過額外載入指令碼的形式來實現相應的新特性。

原文地址:http://weblogs.asp.net/dwahlin/archive/2011/11/16/detecting-html5-css3-features-using-modernizr.aspx