自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

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

[[171604]]

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

方案一:

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

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

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

如下是orientationchange事件的兼容性:

 如下是screen.orientation的兼容性:

 方案二:

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

  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變化,就會不斷觸發(fā)觸發(fā)resize事件??梢允褂胹etTimeout來優(yōu)化一下
  • 如果有多個地方需要監(jiān)聽橫豎屏,就需要注冊多個window.addEventListener("resize", function(event) {……})。能不能通過訂閱與發(fā)布模式來改進一下,只注冊一個resize負責監(jiān)聽橫豎屏變化,只要橫豎發(fā)生變化就發(fā)布通知訂閱的對象。其他需要監(jiān)聽橫豎屏的地方只需訂閱一下即可。

關(guān)鍵代碼如下:

  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來實現(xiàn)的是一種偽檢測,有點不可靠。 可不可以通過瀏覽器來實現(xiàn)檢測?如基于CSS3@media媒體查詢來實現(xiàn)。

如下@media兼容性:

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

實現(xiàn)思路:

  • 創(chuàng)建包含標識橫豎屏狀態(tài)的特定css樣式
  • 通過JS向頁面中注入CSS代碼
  • resize回調(diào)函數(shù)中獲取橫豎屏的狀態(tài)

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

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

1.優(yōu)先使用排在前面的字體。

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

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

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

關(guān)鍵代碼如下:

  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,不支持則使用方案三。

關(guān)鍵代碼如下:

  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. // 監(jiān)聽 
  31. win.addEventListener(isOrientation ? eventType : 'resize', callback, false);  

完整代碼猛擊這里

方案五:

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

關(guān)鍵代碼如下:

  1. var eventType = 'orientationchange'
  2. // 觸發(fā)原生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種方案,自己對移動端橫豎屏檢測有了更進一步的認識,有些東西只有自己親身經(jīng)歷過才知道為什么要這么寫,自己也把其中緣由記錄在文章中,希望對大家有幫助。經(jīng)過5種方案的演變得到了最終orientationchange-fix,github地址:https://github.com/zhansingsong/orientationchange-fix

責任編輯:龐桂玉 來源: segmentfault
相關(guān)推薦

2015-07-23 14:25:04

宕機云主機云智慧

2015-11-09 16:45:14

尼泊爾地震

2013-01-18 10:16:42

2018-06-01 16:06:29

PR靠譜Code Review

2025-04-17 08:23:55

DataStore本地存儲

2021-04-01 14:35:08

XDR微步在線

2012-10-22 11:14:05

SDNOpenFlow網(wǎng)絡(luò)管理

2020-12-22 06:18:47

Windows 10Windows操作系統(tǒng)

2022-10-18 16:03:38

JS判斷數(shù)組面試

2022-12-01 08:30:10

JavaScript構(gòu)造函數(shù)

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開發(fā)移動開發(fā)橫豎屏切換

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

密碼數(shù)據(jù)泄露黑客

2014-10-21 10:29:54

TIOBEPyPI

2017-09-05 14:23:22

人工智能機器翻譯神經(jīng)網(wǎng)絡(luò)
點贊
收藏

51CTO技術(shù)棧公眾號