用JavaScript在浏览器中检测Android手机的旋转
我知道,在iPhone上的Safari,你可以通过听取onorientationchange
事件和查询window.orientation
angular度来检测屏幕的方向和方向的变化。
这是可能的Android手机浏览器?
为了清楚起见,我问一个Android设备的旋转是否可以通过在标准网页上运行的JavaScript检测到。 这是可能在iPhone上,我想知道是否可以为Android手机完成。
要在Android浏览器上检测方向更改,请将侦听器附加到orientationchange
或在window
上resize
事件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.width
或screen.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.innerWidth
和window.InnerHeight
起作用。 - 不要使用
window.orientation
– 它不会在iOS上最新。
- 只处理
- 如果你关心具体的方向 :
- 在Android上只处理
resize
事件,而在iOS上只处理orientationchange
事件。 - 在你的处理程序中,对
window.orientation
(和window.innerWidth
和window.InnerHeight
)
- 在Android上只处理
这些方法比记住以前的方向和比较略有好处:
- 仅在维度上的方法也可以在桌面浏览器上进行开发,否则就可以模拟移动设备,例如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上完成)