### CSS Media Queries
通過媒體查詢的方式我們根據橫豎屏來適配不同的樣式
1.內聯樣式
```css
@media screen and (orientation:portrait) {
//豎屏
}
@media screen and (orientation:landscape) {
//橫屏
}
```
<!--more-->
2.外聯樣式
```css
<!-- 豎屏 -->
<link rel="stylesheet" media="all and (orientation:portrait)" href="..." />
<!-- 橫屏 -->
<link rel="stylesheet" media="all and (orientation:landscape)" href="..." />
```
### window.matchMedia()
除此之外,[CSS Object Model(CSSOM)Views](https://www.w3.org/TR/cssom-view-1/#dom-window-matchmedia) 規范增加了對 JavaScript 操作 CSS Media Queries 的原生支持,它在 window 對象下增加了 matchMedia() 方法,讓我們能夠通過腳本的方式來實現媒體查詢。
window.matchMedia() 方法接受一個 Media Queries 語句的字符串作為參數,返回一個 MediaQueryList 對象。該對象有 media 和 matches 兩個屬性:
* media:返回所查詢的 Media Queries 語句字符串
* matches:返回一個布爾值,表示當前環境是否匹配查詢語句
同時,它還包含了兩個方法,用來監聽事件:
* addListener(callback):綁定回調 callback 函數
* removeListener(callback):注銷回調 callback 函數
那么,通過 window.matchMedia() 的方法,我們可以這樣判斷橫豎屏:
```js
var mql = window.matchMedia("(orientation: portrait)");
function onMatchMeidaChange(mql){
if(mql.matches) {
// 豎屏
}else {
// 橫屏
}
}
onMatchMeidaChange(mql);
mql.addListener(onMatchMeidaChange);
```
### window.innerHeight/window.innerWidth
在 CSS Media Queries 中,Orientation 屬性有兩個值:
* portrait,指的是當 height 大于等于 width 的情況
* landscape,指的是當 height 小于 width 的情況
所以,還有一種最為常見的方法是通過比較頁面的寬高,當頁面的高大于等于寬時則認為是豎屏,反之則為橫屏。
```js
function detectOrient(){
if(window.innerHeight >= window.innerWidth) {
// 豎屏
}else {
// 橫屏
}
}
detectOrient();
window.addEventListener('resize',detectOrient);
```
### window.orientation
在 iOS 平臺以及大部分 Android 手機都有支持 `window.orientation` 這個屬性,它返回一個與默認屏幕方向偏離的角度值:
* 0:代表此時是默認屏幕方向
* 90:代表順時針偏離默認屏幕方向90度
* -90:代表逆時針偏離默認屏幕方向90度
* 180:代表偏離默認屏幕方向180度
```js
switch(window.orientation) {
case 0:
displayStr += "Portrait";
break;
case -90:
displayStr += "Landscape (right, screen turned clockwise)";
break;
case 90:
displayStr += "Landscape (left, screen turned counterclockwise)";
break;
case 180:
displayStr += "Portrait (upside-down portrait)";
break;
}
```

在實際應用中,對于 iPhone 和大部分 Android 是沒有180度的手機豎屏翻轉的情況的,但是 iPad 是存在的。所以,簡化下代碼,我們可以綁定orientationchange事件來判斷橫豎屏:
```js
function detectOrient(){
if (Math.abs(window.orientation) === 90) {
// 橫屏
} else {
// 豎屏
}
}
detectOrient();
window.addEventListener('orientationchange',detectOrient);
```
### 影響判斷的問題
* window.orientation屬性值不一致(IOS相同,Android不一定一致哦)
* 軟鍵盤的彈出(Android情況下,軟件盤的彈出會引起頁面的收縮)
### 最佳實現方式
假如屏幕分辨率固定值為:screen.width 和 screen.height(需要注意,這里很重要的一點是:在移動端,屏幕翻轉時,screen.width 和 screen.height 的值依然是不變的)
* 若獲取 當前頁面的寬(document.documentElement.clientWidth),等于屏幕分辨率的寬(screen.width),則可認定當前屬于豎屏。
* 若獲取 當前頁面的寬(document.documentElement.clientWidth),等于屏幕分辨率的高(screen.height),則可認定當前屬于橫屏。
```js
function detectOrient() {
var storage = localStorage;
var data = storage.getItem('J-recordOrientX');
var w = document.documentElement.clientWidth,
h = document.documentElement.clientHeight;
var _Width = 0,
_Height = 0;
if(!data) {
_Width = window.screen.width;
_Height = window.screen.height;
storage.setItem('J-recordOrientX',_Width + ',' + _Height);
}else {
var str = data.split(',');
_Width = str[0];
_Height = str[1];
}
if(w == _Width) {
// 豎屏
return;
}
if(w == _Height){
// 橫屏
return;
}
}
detectOrient();
window.addEventListener('resize',detectOrient);
```
### 參考
- [凹凸實驗室](https://aotu.io/notes/2017/01/31/detect-orientation/)
- [W3](https://www.w3.org/TR/screen-orientation/)
<p class="over">Over!</p>
- 前端
- C1-Javascript
- H5圖片分塊和斷點續傳
- JavascriptPatterns[Stoyanstefanov]
- macotask和microtask
- 前端代碼生成器
- 跨域
- 頁面回到頂部滾動按鈕實現
- C2-CSS
- 瀏覽器的一些單位
- 盒模型
- 移動端判斷橫豎屏
- C3-框架
- ReactNative
- 開發環境搭建(安卓篇)
- Vue
- vue+pdfjs使用
- vue+typescript使用實踐
- vue+webpack3.x集成typescript
- Vue源碼3
- vue源碼分析1
- vue源碼分析2
- vue筆記
- C4-工具
- git
- Gitlab-CICD
- mock規則
- vscode-settings
- webpack自定義命令,切換代理地址
- 正則表達式
- 深入淺出webpack
- C5-Node
- express
- express源碼閱讀
- nightmare使用指南
- 爬蟲1.0
- C6-微信
- 微信
- C7-Canvas
- 基礎API
- 前端隨筆筆記
- 后端
- C1-Java
- shiro
- C2-Linux
- ffmpeg
- ITerm
- Linux
- MongoDB安裝
- MySql安裝
- Ngnix反向代理
- 常見錯誤
- 備忘
- mac
- 備忘-Work
- 備忘Link
- 服務器資源
- 教程
- Hexo個人博客搭建筆錄
- 文檔
- CSS編碼規范
- 前端編碼規范
- 隨筆
- 整理
- 正則
- 鏈接收藏
- 面試
- CodeWars題庫
- CodeWars題庫(二)
- Java社招面試題
- Java面試
- Web面試
- 前端筆試題
- 筆試題