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

时间:2009-10-30 10:43:20

标签: javascript android webkit

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

这可以在Android手机上的浏览器中使用吗?

要说清楚,我问的是,在标准网页上运行的 JavaScript 是否可以检测到Android设备的轮播。它可以在iPhone上使用,我想知道它是否可以用于Android手机。

12 个答案:

答案 0 :(得分:222)

不同设备的实际行为不一致。 resize和orientationChange事件可以以不同的频率以不同的顺序触发。此外,某些值(例如screen.width和window.orientation)并不总是在您预期时更改。 避免使用screen.width - 在iOS中旋转时不会改变。

可靠的方法是同时监听resize和orientationChange事件(将某些轮询作为安全捕获),并且最终会获得有效的方向值。在我的测试中,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          |
|----------------+-------------------+-------------+------------+--------------|

答案 1 :(得分:208)

要在Android浏览器上检测方向更改,请在orientationchange上附加resizewindow事件的监听器:

// 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的情况)。

答案 2 :(得分:39)

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

  • 如果您只关心窗口尺寸(典型情况) - 而不是特定方向:
    • 仅处理resize事件。
    • 在您的处理程序中,仅对window.innerWidthwindow.InnerHeight采取行动。
    • 请勿使用window.orientation - 它在iOS上不会是最新的。
  • 如果您关心特定方向
    • 仅在Android上处理 resize事件,在iOS上仅处理 orientationchange事件。
    • 在您的处理程序中,对window.orientation(以及window.innerWidthwindow.InnerHeight
    • 采取行动

这些方法比记住以前的方向和比较提供了一些好处:

  • 尺寸专用方法在桌面浏览器上进行开发时也能正常工作,这些浏览器可以模拟移动设备,例如Chrome 23.(window.orientation在桌面浏览器上不可用。)
  • 不需要全局/匿名文件级函数包装级变量。

答案 3 :(得分:12)

您可以随时收听窗口调整大小事件。如果在那个事件中,窗口从高宽度变宽到宽度高(反之亦然),那么你可以非常确定手机方向刚刚改变。

答案 4 :(得分:3)

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

它还支持deskop浏览器,但它总是会返回相同的值。

答案 5 :(得分:3)

我遇到了同样的问题。我正在使用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);
}

答案 6 :(得分:2)

以下是解决方案:

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

答案 7 :(得分:1)

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

答案 8 :(得分:1)

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

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

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

答案 9 :(得分:0)

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

webView.setWebChromeClient(new WebChromeClient());

答案 10 :(得分:0)

跨浏览器方式

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

答案 11 :(得分:-1)

对两位傻瓜的回答有点贡献:

如droid手机上的表所述,“orientationchange”事件比“resize”事件更早被触发,从而阻止了下一次调整大小调用(因为if语句)。宽度属性仍未设置。

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

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

希望有所帮助

(在Nexus S上进行测试)