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

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

这在 Android 手机的浏览器中可行吗?

为了明确起见,我想知道在标准网页上运行的 JavaScript能否检测到 Android 设备的旋转。这在 iPhone 上是可行的,我想知道是否可以在 Android 手机上实现。

167775 次浏览

您总是可以监听窗口大小调整事件。如果,在那个事件中,窗口从高于宽到宽于高(或反之亦然) ,你可以很肯定的是,手机方向刚刚改变。

要检测 Android 浏览器上的方向变化,请将侦听器附加到 window上的 orientationchangeresize事件:

// 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 的情况并非如此)。

真正的 不同设备之间的行为是不一致的。调整大小和方向 Change 事件可以以不同的频率以不同的顺序触发。此外,一些值(例如 screen. width 和 window.location)并不总是在您预期的时候发生变化。避免屏幕宽度——它在 iOS 中旋转时不会改变。

可靠的方法是同时侦听 resize 和 oriationChange 事件 (使用一些轮询作为安全捕获) ,最终将得到方向的有效值。在我的测试中,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);

下面是我所测试的四个设备的结果(对于 ASCII 表,我很抱歉,但它似乎是展示结果最简单的方法)。除了 iOS 设备之间的一致性之外,还有很多不同设备之间的差异。注意: 事件按其触发的顺序列出。

|==============================================================================|
|     Device     | Events Fired      | orientation | innerWidth | screen.width |
|==============================================================================|
| iPad 2         | resize            | 0           | 1024       | 768          |
| (to landscape) | orientationchange | 90          | 1024       | 768          |
|----------------+-------------------+-------------+------------+--------------|
| iPad 2         | resize            | 90          | 768        | 768          |
| (to portrait)  | orientationchange | 0           | 768        | 768          |
|----------------+-------------------+-------------+------------+--------------|
| iPhone 4       | resize            | 0           | 480        | 320          |
| (to landscape) | orientationchange | 90          | 480        | 320          |
|----------------+-------------------+-------------+------------+--------------|
| iPhone 4       | resize            | 90          | 320        | 320          |
| (to portrait)  | orientationchange | 0           | 320        | 320          |
|----------------+-------------------+-------------+------------+--------------|
| Droid phone    | orientationchange | 90          | 320        | 320          |
| (to landscape) | resize            | 90          | 569        | 569          |
|----------------+-------------------+-------------+------------+--------------|
| Droid phone    | orientationchange | 0           | 569        | 569          |
| (to portrait)  | resize            | 0           | 320        | 320          |
|----------------+-------------------+-------------+------------+--------------|
| Samsung Galaxy | orientationchange | 0           | 400        | 400          |
| Tablet         | orientationchange | 90          | 400        | 400          |
| (to landscape) | orientationchange | 90          | 400        | 400          |
|                | resize            | 90          | 683        | 683          |
|                | orientationchange | 90          | 683        | 683          |
|----------------+-------------------+-------------+------------+--------------|
| Samsung Galaxy | orientationchange | 90          | 683        | 683          |
| Tablet         | orientationchange | 0           | 683        | 683          |
| (to portrait)  | orientationchange | 0           | 683        | 683          |
|                | resize            | 0           | 400        | 400          |
|                | orientationchange | 0           | 400        | 400          |
|----------------+-------------------+-------------+------------+--------------|

这在 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);

它也支持桌面浏览器,但它总是返回相同的值。

一个小小的贡献对于这个二流的傻瓜的回答:

正如在 droid 手机的桌面上所描述的,“ oriationchange”事件比“ resize”事件更早被触发,因此阻塞了下一个 resize 调用(因为 if 语句)。仍未设置 Width 属性。

一个解决方案,虽然可能不是一个完美的,可以是不发射“方向改变”事件。这可以通过在“ if”语句中包装“ oriationchange”事件绑定来归档:

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

希望能有帮助

(测试是在 Nexus S 上完成的)

值得注意的是,在我的 Epic 4G Touch 上,我必须在任何 javascript android 调用工作之前设置 webview 来使用 WebChromeClient。

webView.setWebChromeClient(new WebChromeClient());

还有一个问题——一些安卓平板电脑(我相信是摩托罗拉的 Xoom 和我正在测试的低端 Elonex,可能还有其他的)设置了加速度计,以便在 LANDSCAPE 模式下,window. = 0,而不是肖像模式!

二流傻瓜的出色答案提供了所有的背景知识,但让我尝试一下 简明实用的概述如何处理 iOS 和 Android 系统的方向变化:

  • 如果你只关心 窗户尺寸(典型的场景) ——而不关心具体的方向:
    • 仅处理 resize事件。
    • 在您的处理程序中,仅对 window.innerWidthwindow.InnerHeight进行操作。
    • 不要使用 window.orientation-它不会是当前的 iOS。
  • 如果你确实关心 特定的方向 :
    • 在 Android 上处理 只有事件,在 iOS 上处理 orientationchange事件。
    • 在您的处理程序中,操作 window.orientation(以及 window.innerWidthwindow.InnerHeight)

这些方法相对于记住以前的方向和进行比较而言略有好处:

  • 在开发桌面浏览器的同时,这种仅限于尺寸的方法也可以用来模拟移动设备,例如 Chrome23。(window.orientation在桌面浏览器上不可用)。
  • 不需要全局/匿名文件级别函数包装器级别变量。

我也遇到了同样的问题,我正在使用 Phonegap 和 Jquery 手机,用于 Android 设备。 为了适当调整大小,我不得不设置一个超时:

$(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);
}

跨浏览器的方式

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

解决办法如下:

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");
}
});
}

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

以下是 orientationchange兼容图片: compatibility 因此,我编写了一个 orientaionchange填充函数,它是一个基于@media 属性来修复取向改变实用程序库ーー < a href = “ https://github.com/zhansingsong/ 取向改变-修复”rel = “ nofollow norefrer”> 取向改变-修复

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