用JavaScript在浏览器中检测Android手机的旋转

我知道,在iPhone上的Safari,你可以通过听取onorientationchange事件和查询window.orientationangular度来检测屏幕的方向和方向的变化。

这是可能的Android手机浏览器?

为了清楚起见,我问一个Android设备的旋转是否可以通过在标准网页上运行的JavaScript检测到。 这是可能在iPhone上,我想知道是否可以为Android手机完成。

要在Android浏览器上检测方向更改,请将侦听器附加到orientationchange或在windowresize事件resize

 // Detect whether device supports orientationchange event, otherwise fall back to // the resize event. var supportsOrientationChange = "onorientationchange" in window, orientationEvent = supportsOrientationChange ? "orientationchange" : "resize"; window.addEventListener(orientationEvent, function() { alert('HOLY ROTATING SCREENS BATMAN:' + window.orientation + " " + screen.width); }, false); 

检查window.orientation属性以确定设备面向哪个方向。 随着Android手机, screen.widthscreen.height也随着设备的旋转而更新。 (这不是iPhone的情况)。

不同设备之间的实际行为不一致 。 resize和orientationChange事件可以以不同的频率以不同的顺序发射。 另外,某些值(例如,screen.width和window.orientation)并不总是随着您的预期而改变。 避免screen.width – 在iOS中旋转时不会改变。

可靠的方法是听取resize和orientationChange事件 (用一些轮询作为安全措施),最终你会得到一个有效的方向值。 在我的testing中,Android设备有时无法在旋转180度时触发事件,所以我还包括一个setInterval来轮询方向。

 var previousOrientation = window.orientation; var checkOrientation = function(){ if(window.orientation !== previousOrientation){ previousOrientation = window.orientation; // orientation changed, do your magic here } }; window.addEventListener("resize", checkOrientation, false); window.addEventListener("orientationchange", checkOrientation, false); // (optional) Android doesn't always fire orientationChange on 180 degree turns setInterval(checkOrientation, 2000); 

下面是我testing过的四个设备的结果(对于ASCII表格,感到抱歉,但它似乎是展示结果的最简单的方式)。 除了iOS设备之间的一致性之外,各种设备还有很多种类。 注:事件按照它们的顺序列出。

 | ================================================= ============================= |
 | 设备| 事件发生| 定位|  innerWidth |  screen.width |
 | ================================================= ============================= |
 |  iPad 2 | 调整|  0 |  1024 |  768 |
 |  (景观)|  orientationchange |  90 |  1024 |  768 |
 | ---------------- + ------------------- + ------------ -  + ------------ + -------------- |
 |  iPad 2 | 调整|  90 |  768 |  768 |
 |  (肖像)|  orientationchange |  0 |  768 |  768 |
 | ---------------- + ------------------- + ------------ -  + ------------ + -------------- |
 |  iPhone 4 | 调整|  0 |  480 |  320 |
 |  (景观)|  orientationchange |  90 |  480 |  320 |
 | ---------------- + ------------------- + ------------ -  + ------------ + -------------- |
 |  iPhone 4 | 调整|  90 |  320 |  320 |
 |  (肖像)|  orientationchange |  0 |  320 |  320 |
 | ---------------- + ------------------- + ------------ -  + ------------ + -------------- |
 |  Droid电话|  orientationchange |  90 |  320 |  320 |
 |  (景观)| 调整|  90 |  569 |  569 |
 | ---------------- + ------------------- + ------------ -  + ------------ + -------------- |
 |  Droid电话|  orientationchange |  0 |  569 |  569 |
 |  (肖像)| 调整|  0 |  320 |  320 |
 | ---------------- + ------------------- + ------------ -  + ------------ + -------------- |
 | 三星Galaxy |  orientationchange |  0 |  400 |  400 |
 | 平板电脑|  orientationchange |  90 |  400 |  400 |
 |  (景观)|  orientationchange |  90 |  400 |  400 |
 |  | 调整|  90 |  683 |  683 |
 |  |  orientationchange |  90 |  683 |  683 |
 | ---------------- + ------------------- + ------------ -  + ------------ + -------------- |
 | 三星Galaxy |  orientationchange |  90 |  683 |  683 |
 | 平板电脑|  orientationchange |  0 |  683 |  683 |
 |  (肖像)|  orientationchange |  0 |  683 |  683 |
 |  | 调整|  0 |  400 |  400 |
 |  |  orientationchange |  0 |  400 |  400 |
 | ---------------- + ------------------- + ------------ -  + ------------ + -------------- |

两位傻瓜的优秀答案提供了所有的背景知识,但是让我尝试一下如何在iOS和Android上处理方向变化简明实用总结

  • 如果您只关心窗口尺寸 (典型场景) – 而不关注具体方向:
    • 只处理resize事件。
    • 在你的处理程序中,只对window.innerWidthwindow.InnerHeight起作用。
    • 不要使用window.orientation – 它不会在iOS上最新。
  • 如果你关心具体的方向
    • 在Android上处理resize事件,而在iOS上处理orientationchange事件。
    • 在你的处理程序中,对window.orientation (和window.innerWidthwindow.InnerHeight

这些方法比记住以前的方向和比较略有好处:

  • 仅在维度上的方法也可以在桌面浏览器上进行开发,否则就可以模拟移动设备,例如Chrome 23.( window.orientation在桌面浏览器上不可用)。
  • 不需要全局/匿名文件级别的函数包装器级variables。

您可以随时倾听窗口大小调整事件。 如果在这种情况下,窗户从高到宽,从高到低(反之亦然),您可以确定手机的方向刚刚改变。

这是可能的HTML5。
您可以在这里阅读更多(并尝试现场演示): http : //slides.html5rocks.com/#slide-orientation 。

 window.addEventListener('deviceorientation', function(event) { var a = event.alpha; var b = event.beta; var g = event.gamma; }, false); 

它也支持桌面浏览器,但它将始终返回相同的值。

我有同样的问题。 我正在使用Phonegap和JQuery的手机,为Adroid设备。 要正确resize,我必须设置超时:

 $(window).bind('orientationchange',function(e) { fixOrientation(); }); $(window).bind('resize',function(e) { fixOrientation(); }); function fixOrientation() { setTimeout(function() { var windowWidth = window.innerWidth; $('div[data-role="page"]').width(windowWidth); $('div[data-role="header"]').width(windowWidth); $('div[data-role="content"]').width(windowWidth-30); $('div[data-role="footer"]').width(windowWidth); },500); } 

这是解决scheme:

 var isMobile = { Android: function() { return /Android/i.test(navigator.userAgent); }, iOS: function() { return /iPhone|iPad|iPod/i.test(navigator.userAgent); } }; if(isMobile.Android()) { var previousWidth=$(window).width(); $(window).on({ resize: function(e) { var YourFunction=(function(){ var screenWidth=$(window).width(); if(previousWidth!=screenWidth) { previousWidth=screenWidth; alert("oreientation changed"); } })(); } }); } else//mainly for ios { $(window).on({ orientationchange: function(e) { alert("orientation changed"); } }); } 

值得注意的是,在我的史诗4G触摸,我不得不build立webview使用WebChromeClient之前的任何JavaScript的Android调用工作。

 webView.setWebChromeClient(new WebChromeClient()); 

另一个问题 – 一些Android平板电脑(我相信摩托罗拉Xoom和一个我正在进行一些testing的低端Elonex,可能还有其他一些平台)将加速度计设置为使得window.orientation == 0处于LANDSCAPE模式,而不是纵向!

跨浏览器的方式

 $(window).on('resize orientationchange webkitfullscreenchange mozfullscreenchange fullscreenchange', function(){ //code here }); 

您可以尝试解决scheme,与所有浏览器兼容。

以下是orientationchange兼容性图片: 兼容性 因此,我创作了一个orientaionchange ,它是一个基于@media属性来修复orientationchange实用库 – orientationchange-fix

 window.addEventListener('orientationchange', function(){ if(window.neworientation.current === 'portrait|landscape'){ // do something…… } else { // do something…… } }, false); 

对这个两位傻瓜的答案有一点贡献:

正如在droid手机表上所描述的,“orientationchange”事件比“resize”事件被触发,从而阻塞下一个resize调用(因为if语句)。 宽度属性仍未设置。

一个解决方法虽然也许不是一个完美的可能是不会触发“orientationchange”事件。 这可以通过在“if”语句中包装“orientationchange”事件绑定来存档:

 if (!navigator.userAgent.match(/android/i)) { window.addEventListener("orientationchange", checkOrientation, false); } 

希望它有帮助

(testing在Nexus S上完成)