一、站在使用者的角度看問題
一個使用者,訪問一個web頁面的真實場景是怎樣的呢?
下面是某使用者訪問某站點的一個場景:
1. 小明開啟了自己的電腦,訪問了鑫空間-鑫生活;
2. 小明體內洪荒之力無法控制,瘋狂拖動瀏覽器改變其寬度感受頁面佈局變化;
3. 臥槽,發現頁面居然是響應式的,不由得感嘆:實現的夠騷氣!
很顯然,小明要麼是雷蜜胡粉心碎抓狂,要不就是前端開發職業病發作難耐。作為真實的使用者是不會把瀏覽器刻意縮小去體驗的,你想想看你平時上網的時候,會把瀏覽器視窗拉到很小嗎?怕是嫌螢幕小,恨不得顯示器大到鋪滿辦公桌吧~~
二、回到傳統的響應式開發
傳統的響應式實現往往基於基於media query查詢,例如:
1 2 3 |
@media screen and (max-width: 480px) { /* 窄屏下 */ } |
這是基於CSS的佈局控制,因此,當我們縮小瀏覽器視窗,可以即時看到佈局變化。但是,這種實現在我看來,除了讓總監大人可以方便體驗窄屏效果外,就然並卵了! 而反倒是有可能增加了額外的資源消耗和開發成本。
@media
可以即時控制寬窄佈局,很自然地,我們的JS邏輯也要一併跟上。假如說,PC和mobile有很多不同的互動邏輯,我們的HTML是同一套,當我們在響應PC和Mobile零界點不停變換的時候,我們的JS邏輯是不是也要跟著即時變化!
這就導致問題來了,CSS瀏覽器渲染,本身即時響應。但JS且不一樣,我們必須實時監測是PC寬度還是Mobile寬度,同時PC的click事件和Mobile的touch事件可能就在同一個元素上搞基了,也蠻累心的。為了我們自己省心,我們就可能去限制設計師再做響應式設計的時候,兩者差異不要太大。我去,技術已經不是幫助產品設計體驗升級,而是去制約設計了,貴司的設計師好慘!
還有一個問題就是資源消耗的問題,拿網站頭圖舉例,PC的頭圖可能是張大大的長圖,Mobile是個方方的圖片。即時響應也就意味著這兩個圖都可能會被載入。
那有沒有什麼辦法既能滿足響應式的需求,同時我們開發這邊不要那麼煩心呢?
試試使用screen.width
來做偽響應式開發。
三、screen.width偽響應式開發
首先要了解下不會說謊的screen.width
,screen.width
顧名思義就是螢幕的寬度,對,螢幕的寬度,與顯示器寬度沒有任何關係,就算你把顯示器寬度縮小到芝麻糊那麼大,screen.width
還是不會變。
在“CSSOM檢視模式相關整理”一文中有過介紹,IE9以及以上瀏覽器才支援。
由於screen.width
不會說謊,我們就可以瞬間確定使用者實現的寬屏裝置還是窄屏裝置,而@media screen
的寬度是瀏覽器的可用寬度,很容易就被使用者欺騙的。
關於screen.width可能的疑問
- IE7/IE8怎麼辦?
請問,移動端瀏覽器會是IE7/IE8嗎?明擺著如果不支援screen.width
就是PC裝置啊。如果有1000和1200的響應結點,按小的來,使用這麼挫瀏覽器的使用者的顯示器很大概率不會是大屏。 - 手機如果橫著訪問會怎樣?
根據我在自己手機上的測試,你手機橫過來還是豎過來,screen.width
都是你螢幕豎著瀏覽時候的寬度。好比腎6,你橫豎瀏覽,此時screen.width
都是375px
; - PC瀏覽器如何測試?
測試的話不是縮小瀏覽器寬度,而是開啟控制檯,進入手機模式,此時,screen.width
也會跟著一起變哦~記得重新整理下頁面~
只要我們確認了使用者的螢幕尺寸,我們就可以在一開始就確定我們的頁面佈局以及所需要的互動,例如,可以在標籤內放入這麼一段內聯script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
(function(doc, win) { var screenWidth = 0, size = 'M', root = doc.documentElement; if (window.screen & screen.width) { screenWidth = screen.width; if (screenWidth > 1920) { // 超大屏,例如iMac size = 'L'; } else if (screenWidth // 小屏,如手機 size = 'S'; } } // 標記CSS root.className = size; // 標記JS win.SIZE = size; })(document, window); |
上面的指令碼在頁面載入的一開始,就確定了是大屏,普通屏還是小屏,然後再執行響應的渲染和指令碼執行。您可以根據自己實際專案,修改上面的size
變數。
於是乎,我們無論是CSS渲染還是JS邏輯處理,都是1條線下來,完全沒有@media screen
即時切換而不得已耦合在一起的JS邏輯處理。
典型的偽響應式程式碼如下:
1 2 3 |
.S .example { /* 移動端的樣式 */ } |
1 2 3 4 5 |
if (window.SIZE == 'S') { // 移動端的處理 } else { // 桌面端的處理 } |
考慮到真實的使用者使用場景,基於screen.width
的偽響應式開發對使用者而言,沒有任何區別,該什麼裝置看到的還是那個裝置該有的樣子;但是,對於開發人員,也就是我們前端開發自己而言,那就不一樣了,一條故事線下來,邏輯清晰,處理輕鬆,設計師把PC和Mobile涉及的差異再明顯,我也能從容應對,對吧,if{} else{}
裡面互不干擾,好輕鬆~
四、結語
本文並不是否決基於media queries的響應式處理,只是提供另外的一個解決問題的思路。如果你的PC和Mobile的有很多不同的邏輯處理,試試這種一棒子打死的“響應式”策略。
然後,本文的策略是經過真實目前線上的有一定分量的專案驗證過的,同事認同,Boss認同(除了縮小螢幕沒法體驗手機),自己跳開了很多坑,更加認同。有機會,你也不妨試試。