天天看點

實踐 HTML5 的 CSS3 Media Queries

先來介紹下 media,确切的說應該是 CSS media queries(CSS 媒體查詢),媒體查詢包含了一個媒體類型和至少一個使用如寬度、高度和顔色等媒體屬性來限制樣式表範圍的表達式。CSS3 加入的媒體查詢使得無需修改内容便可以使樣式應用于某些特定的裝置範圍。 

那麼該怎麼定義 media 呢,看下面的代碼,你肯定能猜出個大概。

關于解釋,文檔中是這麼說的,當媒體查詢為真時,相關的樣式表或樣式規則就會按照正常的級聯規則被應用。即使媒體查詢傳回假, <link> 标簽上帶有媒體查詢的樣式表仍将被下載下傳(隻不過不會被應用)。

是以呢,這也是一種弊端,如果說對某個頁面定義了多個樣式标準來因對不同的 media 屬性的話,那在頁面的加載時間将會受到影響,但是話有說回來,在目前網絡快速發展的時代,網速也在不斷地完善和提高,是以影響并不大,幾乎可以忽略不計。

接下來我們來用幾個 Demo 來示範下 media 的用法及表現。

既然我們今天的目的是探讨如何監聽 devicePixelRatio 屬性的變化,那麼我們就以在不同的 devicePixelRatio 值情況下,來改變某個 div 的 background 樣式,具體的代碼如下:

代碼有了,那麼要怎麼測試呢?在一般情況下,devicePixelRatio 屬相是不會變化的,但是肯定會存在特殊情況的,就比如說,你的電腦接了兩個顯示器,而且兩台浏覽器的 devicePixelRatio 屬性是不一樣的,那麼恭喜你,你已經具備測試條件,隻需要将頁面從一個屏拖到另外一個屏,這樣你就可以看到效果了。

有去測試的同學會發現,div 的背景色并沒有想代碼中設定的那樣,在不同的 devicePixelRatio 屬性值下,展現出不同的顔色,這是為什麼呢?

這代碼是我最開始寫代碼,運作後發現沒效果,起初我也不知道原因,在跨屏拖動頁面的時候,在浏覽器控制台中,我找到了原因。那麼到底是什麼原因導緻設定無效的呢?我們來看看兩個螢幕下的 Style 内容截圖,左邊是 min-resolution 等于 1,右邊是等于 2

實踐 HTML5 的 CSS3 Media Queries
實踐 HTML5 的 CSS3 Media Queries

對比着兩個圖,可以發現,在 min-resolution 等于 2 的情況下,在裡面定義的屬性被覆寫掉了,并沒有生效,這是為什麼呢?

要解釋的話,這裡恐怕需要補充一點知識,就是關于 min- 和 max- 的字首,在代碼中的所起到的具體效果,在文檔中是這麼描述的:大多數媒體屬性帶有 “min-” 和 “max-” 字首,用于表達 “大于等于” 和 “小于等于”。這避免了使用與HTML和XML沖突的 “<” 和 “>” 字元。如果你未向媒體屬性指定一個值,并且該特性的實際值不為零,則該表達式被解析為真。如果浏覽器運作的裝置上沒有該屬性值,包含這個屬性值的表達式一般傳回假。

其實上面的說明已經幫我解釋清楚了,我再通俗地和大家解釋一下:當 devicePixelRatio 為 1 時,隻有 min-resolution: 1dppx 這個條件滿足,是以 div 的顔色是黑色沒錯;當 devicePixelRatio 為 2 時,兩個 media 都滿足條件,同時 CSS 的規則是後加載的樣式将會覆寫先加載的樣式,由于我麼将 min-resolution: 1dppx 的 media 寫在後面,是以如果兩個 media 都滿足條件的話, min-resolution: 1dppx 的 media 将會覆寫 min-resolution: 2dppx 的 media,是以不管你把頁面拖到那個螢幕,那個 div 的背景色都是黑色。

那麼我們将兩個 media 調換一下位置,問題就順利地解決了。

以上是根據不同的 media 條件設定不同的樣式,這是 CSS 的做法,在 JavaScript 中,沒有專門的方法來監聽 window.devicePixelRatio 屬性變化,那麼該怎麼監聽 devicePixelRatio 屬性的變化呢?方法也很簡單,看看下面的代碼,你一定就明白了:

稍微解釋下,通過 window.matchMedia(‘media expression’) 方法擷取到對應的 media,然後通過 addListener(function(e) {}) 來監聽 media 的變化。

有玩過 Canvas 的朋友一定知道,要想繪制出來的内容效果最佳的話,Canvas 自身的 width 和 height 屬性值與 style 中的 width 和 height 的比例應該恰好等于 devicePixelRatio 的值,所有如果你在切換不同 devicePixelRatio 屬性值的螢幕時,沒有重新設定 Canvas 的寬高的話,繪制出來的畫面将不是最佳的效果。

實踐 HTML5 的 CSS3 Media Queries
實踐 HTML5 的 CSS3 Media Queries

上面兩張圖分别是在不同的螢幕中的截圖,車子動起來的效果可以通路以下連結:

在 obj 文檔中,你會看到一個一個飛機的例子,飛機沿着設定好的路線飛行,你應該會想,這個尋路是怎麼實作的呢?其實很簡單,我們将路線切割成一個個很小很小的單元,然後根據算法依次擷取到小單元的坐标設定到移動的物體上,這樣物體就動起來了。 

在 Demo 中,有一條很精緻的馬路,這條馬路就是一個 Shape 節點,根據車的路徑生成的馬路,Shape 是一個六面體,因為首尾相連了,是以沒有左右面,在這個例子中,我将馬路的 back 和 top  面隐藏了,然後 bottom 面支援翻轉,讓 bottom 面的貼圖顯示在内表面上,這樣馬路就建成了。