成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

更靠譜的移動端橫豎屏檢測方法

移動開發 移動應用
前不久,做了一個H5項目,需要在橫豎屏變化時,做一些處理。毫無疑問,需要使用orientationchange來監聽橫豎屏的變化。

[[171604]]

前不久,做了一個H5項目,需要在橫豎屏變化時,做一些處理。毫無疑問,需要使用orientationchange來監聽橫豎屏的變化。

方案一:

  1. // 監聽 orientation changes 
  2. window.addEventListener("orientationchange"function(event) { 
  3.     // 根據event.orientation|screen.orientation.angle等于0|180、90|-90度來判斷橫豎屏 
  4. }, false);  

代碼添加上后,就各種兼容性問題。這里兼容性問題出現在兩個地方:

  • orientationchange
  • event.orientation|screen.orientation.angle

如下是orientationchange事件的兼容性:

 如下是screen.orientation的兼容性:

 方案二:

上述方案不行,只能另行他法了。google一下,了解到可以通過resize配合(window.inner/outerWidth, window.inner/outerHeight)來實現:

  1. window.addEventListener("resize"function(event) { 
  2.     var orientation=(window.innerWidth > window.innerHeight)? "landscape":"portrait"
  3.     if(oritentation === 'portrait'){ 
  4.         // do something …… 
  5.     } else { 
  6.         // do something else …… 
  7.     } 
  8. }, false);  

這種方案基本滿足大部分項目的需求,但是還是有些不足之處:

  • 只要window的size變化,就會不斷觸發觸發resize事件。可以使用setTimeout來優化一下
  • 如果有多個地方需要監聽橫豎屏,就需要注冊多個window.addEventListener("resize", function(event) {……})。能不能通過訂閱與發布模式來改進一下,只注冊一個resize負責監聽橫豎屏變化,只要橫豎發生變化就發布通知訂閱的對象。其他需要監聽橫豎屏的地方只需訂閱一下即可。

關鍵代碼如下:

  1. var resizeCB = function(){ 
  2.      if(win.innerWidth > win.innerHeight){//初始化判斷 
  3.        meta.init = 'landscape'
  4.        meta.current = 'landscape'
  5.      } else { 
  6.        meta.init = 'portrait'
  7.        meta.current = 'portrait'
  8.      } 
  9.      return function(){ 
  10.        if(win.innerWidth > win.innerHeight){ 
  11.          if(meta.current !== 'landscape'){ 
  12.            meta.current = 'landscape'
  13.            event.trigger('__orientationChange__', meta); 
  14.          } 
  15.        } else { 
  16.          if(meta.current !== 'portrait'){ 
  17.            meta.current = 'portrait'
  18.            event.trigger('__orientationChange__', meta); 
  19.          } 
  20.        } 
  21.      } 
  22.    }();  

完整代碼猛擊這里

方案三:

不過個人覺得通過window.innerWidth > window.innerHeight來實現的是一種偽檢測,有點不可靠。 可不可以通過瀏覽器來實現檢測?如基于CSS3@media媒體查詢來實現。

如下@media兼容性:

 如上上圖所示,移動端瀏覽器都支持CSS3 media。

實現思路:

  • 創建包含標識橫豎屏狀態的特定css樣式
  • 通過JS向頁面中注入CSS代碼
  • resize回調函數中獲取橫豎屏的狀態

這里我選擇<html></html>的節點font-family作為檢測樣式屬性。理由如下:

  • 選擇<html></html>主要為了避免reflow和repaint
  • 選擇font-family樣式,主要是因為font-family有如下特性:

1.優先使用排在前面的字體。

2.如果找不到該種字體,或者該種字體不包括所要渲染的文字,則使用下一種字體。

3.如果所列出的字體,都無法滿足需要,則讓操作系統自行決定使用哪種字體。

這樣我們就可以指定特定標識來標識橫豎屏的狀態,不過需要將指定的標識放置在其他字體的前面,這樣就不會引起hmtl字體的變化。

關鍵代碼如下:

  1. // callback 
  2.     var resizeCB = function() { 
  3.         var hstyle = win.getComputedStyle(html, null), 
  4.             ffstr = hstyle['font-family'], 
  5.             pstr = "portrait, " + ffstr, 
  6.             lstr = "landscape, " + ffstr, 
  7.             // 拼接css 
  8.             cssstr = '@media (orientation: portrait) { .orientation{font-family:' + pstr + ';} } @media (orientation: landscape) {  .orientation{font-family:' + lstr + ';}}'
  9.         // 載入樣式         
  10.         loadStyleString(cssstr); 
  11.         // 添加類 
  12.         html.className = 'orientation' + html.className; 
  13.         if (hstyle['font-family'] === pstr) { //初始化判斷 
  14.             meta.init = 'portrait'
  15.             meta.current = 'portrait'
  16.         } else { 
  17.             meta.init = 'landscape'
  18.             meta.current = 'landscape'
  19.         } 
  20.         return function() { 
  21.             if (hstyle['font-family'] === pstr) { 
  22.                 if (meta.current !== 'portrait') { 
  23.                     meta.current = 'portrait'
  24.                     event.trigger('__orientationChange__', meta); 
  25.                 } 
  26.             } else { 
  27.                 if (meta.current !== 'landscape') { 
  28.                     meta.current = 'landscape'
  29.                     event.trigger('__orientationChange__', meta); 
  30.                 } 
  31.             } 
  32.         } 
  33.     }();  

完整代碼猛擊這里

測試效果

  • portrait效果:

 

  • landscape效果:

 

方案四:

可以再改進一下,在支持orientationchange時,就使用原生的orientationchange,不支持則使用方案三。

關鍵代碼如下:

  1. // 是否支持orientationchange事件 
  2. var isOrientation = ('orientation' in window && 'onorientationchange' in window); 
  3. // callback 
  4. var orientationCB = function(e) { 
  5.     if (win.orientation === 180 || win.orientation === 0) { 
  6.         meta.init = 'portrait'
  7.         meta.current = 'portrait'
  8.     } 
  9.     if (win.orientation === 90 || win.orientation === -90) { 
  10.         meta.init = 'landscape'
  11.         meta.current = 'landscape'
  12.     } 
  13.     return function() { 
  14.         if (win.orientation === 180 || win.orientation === 0) { 
  15.             meta.current = 'portrait'
  16.         } 
  17.         if (win.orientation === 90 || win.orientation === -90) { 
  18.             meta.current = 'landscape'
  19.         } 
  20.         event.trigger(eventType, meta); 
  21.     } 
  22. }; 
  23. var callback = isOrientation ? orientationCB() : (function() { 
  24.     resizeCB(); 
  25.     return function() { 
  26.         timer && win.clearTimeout(timer); 
  27.         timer = win.setTimeout(resizeCB, 300); 
  28.     } 
  29. })(); 
  30. // 監聽 
  31. win.addEventListener(isOrientation ? eventType : 'resize', callback, false);  

完整代碼猛擊這里

方案五:

目前,上述幾種方案都是通過自定制的訂閱與發布事件模式來實現的。這里可以基于瀏覽器的事件機制,來模擬orientationchange。即對orientationchange的不兼容進行修復。

關鍵代碼如下:

  1. var eventType = 'orientationchange'
  2. // 觸發原生orientationchange 
  3. var fire = function() { 
  4.     var e; 
  5.     if (document.createEvent) { 
  6.         e = document.createEvent('HTMLEvents'); 
  7.         e.initEvent(eventType, truefalse); 
  8.         win.dispatchEvent(e); 
  9.     } else { 
  10.         e = document.createEventObject(); 
  11.         e.eventType = eventType; 
  12.         if (win[eventType]) { 
  13.             win[eventType](); 
  14.         } else if (win['on' + eventType]) { 
  15.             win['on' + eventType](); 
  16.         } else { 
  17.             win.fireEvent(eventType, e); 
  18.         } 
  19.     } 
  20.  

完整代碼猛擊這里

通過上述5種方案,自己對移動端橫豎屏檢測有了更進一步的認識,有些東西只有自己親身經歷過才知道為什么要這么寫,自己也把其中緣由記錄在文章中,希望對大家有幫助。經過5種方案的演變得到了最終orientationchange-fix,github地址:https://github.com/zhansingsong/orientationchange-fix

責任編輯:龐桂玉 來源: segmentfault
相關推薦

2013-01-18 10:16:42

2015-11-09 16:45:14

尼泊爾地震

2015-07-23 14:25:04

宕機云主機云智慧

2018-06-01 16:06:29

PR靠譜Code Review

2025-04-17 08:23:55

DataStore本地存儲

2012-10-22 11:14:05

SDNOpenFlow網絡管理

2021-04-01 14:35:08

XDR微步在線

2020-12-22 06:18:47

Windows 10Windows操作系統

2025-06-10 08:30:50

2022-10-18 16:03:38

JS判斷數組面試

2022-12-01 08:30:10

JavaScript構造函數

2018-01-25 16:00:31

2012-06-06 09:07:46

云計算微軟

2014-07-29 09:33:17

公司郵箱

2013-05-23 10:51:28

Android開發移動開發橫豎屏切換

2017-10-31 11:27:14

寬帶百兆光纖移動

2014-02-19 10:49:55

Windows 9

2011-12-22 09:32:34

虛擬化桌面虛擬化云計算

2020-06-22 11:30:38

密碼數據泄露黑客

2014-10-21 10:29:54

TIOBEPyPI
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 午夜精品在线 | 国产精品久久福利 | 日本不卡一区二区三区 | 三级视频久久 | 久久久久九九九九 | 色精品视频 | 伊人伊人| 亚洲精品片 | 成人看片在线观看 | 北条麻妃99精品青青久久主播 | 欧美国产精品一区二区三区 | 91精品国产91久久久久久不卞 | 欧美 日韩 视频 | 99久久婷婷国产综合精品电影 | h网站在线观看 | 国产日韩精品视频 | 中文字幕第十页 | 成人免费看片 | 亚洲精品一区国产精品 | 国产91网站在线观看 | 97精品超碰一区二区三区 | 国产视频精品免费 | 亚洲福利一区 | 亚洲444eee在线观看 | 日韩国产在线 | 久久精品视频亚洲 | 日韩h| 日日骚av | 亚洲日韩中文字幕一区 | 伊人精品久久久久77777 | 欧美色专区 | 欧美国产精品一区二区三区 | 91电影 | 四虎最新 | 国产成人综合一区二区三区 | 精品视频一区二区 | 视频羞羞 | 久久久久国产精品 | 久久久久久久国产精品影院 | 美女视频黄色的 | 欧美伦理一区 |