使用CSS媒體查詢(Media Queries)和JavaScript判斷瀏覽器設(shè)備類型的方法

有無數(shù)的理由要求我們在任何時候都應(yīng)該知道用戶是使用的什么設(shè)備瀏覽我們的網(wǎng)站——寬屏,普通屏,平板,手機?知道這些特征,我們web應(yīng)用的CSS和JavaScript才能同步做相應(yīng)的操作。在給Mozilla Developer Networks改版設(shè)計的過程中,我發(fā)現(xiàn)使用CSS媒體查詢(media queries)雖然非常的有效,但有時,JavaScript卻不能及時知道用戶瀏覽設(shè)備的狀態(tài)。瀏覽網(wǎng)站的用戶使用的是桌面電腦,還是平板,還是手機?這對于CSS來說很容易,但CSS卻無法將這些信息告訴JavaScript。我發(fā)明了一種基于CSS媒體查詢和z-index屬性的方法,能告訴JavaScript用戶當前使用的是什么屏幕,這樣我能調(diào)整JavaScript的動作來響應(yīng)這種屏幕尺寸。
CSS代碼
首先最重要的還是CSS媒體查詢代碼。這里只是示例,我們創(chuàng)建了三個媒體查詢規(guī)則(但不包括缺省的“all”),它能控制四種屏幕情況:桌面(這是缺省狀態(tài),不需要媒體查詢規(guī)則),“小屏幕”,平板,手機。針對每一種屏幕,我們給它一種不同的z-index值,這個值我們可以用JavaScript檢測到。我們把這個元素定位到屏幕外,這樣它就不會顯示出來;記住,它的作用就是存放z-index值,我們要用javaScript獲取這個值。
/* 缺省屏幕 */
.state-indicator {
position: absolute;
top: -999em;
left: -999em;
z-index: 1;
}
/* 小屏幕 */
@media all and (max-width: 1200px) {
.state-indicator {
z-index: 2;
}
}
/* 平板 */
@media all and (max-width: 1024px) {
.state-indicator {
z-index: 3;
}
}
/* 手機 */
@media all and (max-width: 768px) {
.state-indicator {
z-index: 4;
}
}
每種z-index都在告訴我們的JavaScript當前的用戶使用的是什么規(guī)格的屏幕。我們并不像知道用戶究竟使用的是什么設(shè)備,因為你可以將瀏覽器寬度拉的很窄,但我們需要就是可視寬度,這樣我們可以調(diào)整應(yīng)用的布局。
JavaScript代碼
也許你認為可以在DomContentLoaded時知道屏幕的大小,但我們需要實時知道屏幕的大小(因為用戶會調(diào)整瀏覽器窗口的大小),我們需要有個方法獲取當前窗口的屬性:
// 創(chuàng)建狀態(tài)指示元素
var indicator = document.createElement('div');
indicator.className = 'state-indicator';
document.body.appendChild(indicator);
// 獲取設(shè)備類別的方法
function getDeviceState() {
return parseInt(window.getComputedStyle(indicator).getPropertyValue('z-index'), 10);
}
使用這個方法,你就能檢測出頁面布局/js飾件中那些需要顯示,那些需要隱藏。
if(getDeviceState() < 3) { // 如果是桌面電腦后小屏幕電腦
// 顯示js飾件....
}
有人也許會認為這些數(shù)字太容易搞錯,讓代碼很難維護。其實我們可以用一個對象來處理這種事情:
var index = parseInt(window.getComputedStyle(indicator).getPropertyValue('z-index'), 10);
var states = {
2: 'small-desktop',
3: 'tablet',
4: 'phone'
};
return states[index] || 'desktop';
}
這樣,你就一個寫出更具可讀性的邏輯判斷:
// Do whatever
}
也許使用CSS的偽元素的content屬性是個更好的方法:
.state-indicator {
position: absolute;
top: -999em;
left: -999em;
}
.state-indicator:before { content: 'desktop'; }
/* 小屏幕桌面 */
@media all and (max-width: 1200px) {
.state-indicator:before { content: 'small-desktop'; }
}
/* 平板 */
@media all and (max-width: 1024px) {
.state-indicator:before { content: 'tablet'; }
}
/* 手機 */
@media all and (max-width: 768px) {
.state-indicator:before { content: 'mobile'; }
}
用下面的JavaScript方法獲取關(guān)鍵的內(nèi)容:
document.querySelector('.state-indicator'), ':before'
).getPropertyValue('content')
如何組織這些代碼全看你自己了。如果你有一個全局對象,例如window.config或window.app等,你可以把這些方法放到里面。我傾向于模塊化這些功能,你可以把它做成jQuery插件或JavaScript工具包。不管你如何實現(xiàn),它們都是你可以信賴的、簡單易用的檢測用戶設(shè)備的好方法。
更上一層樓
我們知道屏幕尺寸會發(fā)生變化——用戶手工調(diào)整瀏覽器大型或手機用戶調(diào)整了手機方向,所以,當這些事件發(fā)生時,我們需要讓系統(tǒng)告訴我們。下面這段簡單的代碼估計是你需要的:
window.addEventListener('resize', debounce(function() {
var state = getDeviceState();
if(state != lastDeviceState) {
// 保持當前的狀態(tài)
lastDeviceState = state;
// 宣告狀態(tài)變化,通過自定義的DOM事件或JS 消息發(fā)布/訂閱模式,
// 我喜歡后者,所有就假設(shè)使用了一個這樣的工具庫
publish('/device-state/change', [state]);
}
}, 20));
// 用法
subscribe('/device-state/change', function(state) {
if(state == 3) {
// or "tablet", if you used the object
}
});
注意,這里我使用了debounce方法來執(zhí)行resize事件發(fā)生時的動作——這對于性能來說非常重要。是使用自定義DOM事件還是使用發(fā)布/訂閱模式,你自由選擇,因為都很簡單。
我覺得這種方法非常的好。有人可能會指出使用matchMedia也可以有相同效果,但問題是你需要在CSS里和JavaScript里都使用媒體查詢,而有些媒體查詢語句可能會很復雜,甚至會成為你的噩夢,不如使用簡單的z-index。也有人會說可以使用 window.innerWidth來判斷,但這樣JS里獲取的屬性和CSS里的媒體查詢就需要相互轉(zhuǎn)換了,同樣也會成為你的惡魔。我的方法的好處就在于你可以用它判斷其他類型的媒體查詢屬性,例如檢查手機是橫向(landscape)還是豎向(portrait)。
不管怎樣,你可以試一下,告訴我你的感覺!
相關(guān)文章
詳解CSS3媒體查詢響應(yīng)式布局bootstrap 框架原理實戰(zhàn)(推薦)
這篇文章主要介紹了詳解CSS3媒體查詢響應(yīng)式布局bootstrap 框架原理實戰(zhàn)(推薦),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的2020-11-16css3媒體查詢中device-width和width的區(qū)別詳解
這篇文章主要介紹了css3媒體查詢中device-width和width的區(qū)別詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小2020-03-27- 這篇文章主要介紹了css3 響應(yīng)式媒體查詢的示例代碼,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-09-25
- 這篇文章主要介紹了css3中媒體查詢結(jié)合rem布局適配手機屏幕,需要的朋友可以參考下2019-06-10
- 這篇文章主要介紹了CSS3 Media Queries中媒體屬性的使用,文章中還以一個響應(yīng)式設(shè)計的例子作為補充講解,需要的朋友可以參考下2016-02-29
CSS3媒體查詢Media Queries基礎(chǔ)學習教程
這篇文章主要介紹了CSS3媒體查詢基本學習教程,包括基本的語法和邏輯操作符,以及媒體查詢可檢測的特性與利用viewport禁止用戶縮放等部分的內(nèi)容,需要的朋友可以參考下2016-02-29- 媒體類型:all 所有設(shè)備、screen 電腦顯示器等等;媒體特性共13種,可以說是一個類似CSS屬性的集合,感興趣的朋友可以了解下本文,希望對大家有所幫助2013-09-12
CSS3媒體查詢實現(xiàn)不同寬度的下不同內(nèi)容的展示功能
這篇文章主要介紹了CSS3媒體查詢實現(xiàn)不同寬度的下不同內(nèi)容的展示功能,本章節(jié)我們將為大家演示一些多媒體查詢實例,需要的朋友可以參考下2023-11-27