【问题标题】:Detect rotation of Android phone in the browser with JavaScript使用 JavaScript 在浏览器中检测 Android 手机的旋转
【发布时间】:2010-12-11 13:39:06
【问题描述】:

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

这可以在安卓手机的浏览器中实现吗?

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

【问题讨论】:

    标签: javascript android webkit


    【解决方案1】:

    实际不同设备间的行为不一致。 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 设备之间的一致性之外,设备之间还有很多差异。注意:事件按照它们触发的顺序列出。

    |=================================================== ==============================| |设备 |事件触发 |方向 |内宽 |屏幕宽度 | |=================================================== ==============================| | iPad 2 |调整大小 | 0 | 1024 |第768章 | (到风景) |方向改变 | 90 | 1024 |第768章 |----------------+-------------------+------------ -+------------+--------------| | iPad 2 |调整大小 | 90 |第768章第768章 | (肖像) |方向改变 | 0 |第768章第768章 |----------------+-------------------+------------ -+------------+--------------| | iPhone 4 |调整大小 | 0 | 480 | 320 | | (到风景) |方向改变 | 90 | 480 | 320 | |----------------+-------------------+------------ -+------------+--------------| | iPhone 4 |调整大小 | 90 | 320 | 320 | | (肖像) |方向改变 | 0 | 320 | 320 | |----------------+-------------------+------------ -+------------+--------------| |机器人手机 |方向改变 | 90 | 320 | 320 | | (到风景) |调整大小 | 90 |第569章第569章 |----------------+-------------------+------------ -+------------+--------------| |机器人手机 |方向改变 | 0 |第569章第569章 | (肖像) |调整大小 | 0 | 320 | 320 | |----------------+-------------------+------------ -+------------+--------------| |三星盖乐世 |方向改变 | 0 | 400 | 400 | |平板电脑 |方向改变 | 90 | 400 | 400 | | (到风景) |方向改变 | 90 | 400 | 400 | | |调整大小 | 90 |第683章第683章 | |方向改变 | 90 |第683章第683章 |----------------+-------------------+------------ -+------------+--------------| |三星盖乐世 |方向改变 | 90 |第683章第683章 |平板电脑 |方向改变 | 0 |第683章第683章 | (肖像) |方向改变 | 0 |第683章第683章 | |调整大小 | 0 | 400 | 400 | | |方向改变 | 0 | 400 | 400 | |----------------+-------------------+------------ -+------------+--------------|

    【讨论】:

    • 在iOS5模拟器中,如果横向刷新然后旋转,这段代码不会触发。
    • 很好的答案。 previousOrientation 应该用当时的方向初始化:var previousOrientation = window.orientation; 如果你想忽略 180 度旋转,即你不需要区分左右横向和上下颠倒或 -不是变体,将以下内容作为第一行添加到checkOrientation()if (0 === (previousOrientation + window.orientation) % 180) return; 但是,如果没有额外的setTimeout 技巧,您只会在 iOS 上受益,其中快速 180 度旋转只会创建一个 orientationchange 事件。
    • 感谢@mklement,我调整了代码以初始化previousOrientation。
    • 为伟大的信息干杯。这让我很头疼,因为当您使用科尔多瓦时,Windows Phone 8.1 没有调整大小或方向更改事件。求助于使用 setInterval 以及故障保护。
    • @mklement0 到今天,window.orientation 在 windows phone 8.1 上始终是未定义的。
    【解决方案2】:

    要检测 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 的情况)。

    【讨论】:

    • 这真的有效吗?我试过 jquery $(window).bind("orientationchange",fn);但它没有用,我必须使用上面的表格吗?我在窗口中尝试了“onorientationchange”,它返回错误
    • 效果很好。 Ayyash - 这里的重点是,当“orientationchange”不受支持时,它将退回到“resize”
    • 在 Droid 上,这完全是疯了。当手机在横向模式下旋转时它会提醒 screen.width 为 320,当手机在纵向模式下旋转时它会检测到 screen.width 569!怎么来的??
    • 澄清一下:那些寻找也适用于 iOS 的解决方案的人应该看看两位傻瓜或我的答案。
    • iOS 无需使用 2bit-fool 的 hack。只需在 Android 上使用 screen.width 和 screen.height,在 iOS 上使用 window.innerWidth 和 window.innerHeight。
    【解决方案3】:

    两位傻瓜的出色答案提供了所有背景,但让我尝试简明实用地总结一下如何处理 iOS 和 Android 之间的方向变化

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

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

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

    【讨论】:

    • 问题是当resize或者orientation事件触发window.innerWidth报错并且Droid设备
    • @albanx 在 ios 上的 chrome 中仍然是一个问题:/ safari 很好
    • 这很有用!这让我意识到我不在乎方向,这让事情变得容易多了。
    【解决方案4】:

    您可以随时收听窗口调整大小事件。如果在那次事件中,窗口从比它高到比它高(反之亦然),你可以很确定手机的方向只是改变了。

    【讨论】:

    • 这是个好主意,我会试试(并请我的Android手机朋友测试!)
    • 我刚刚意识到这种方法并不能告诉我手机的方向。我会知道它是纵向还是横向,但不知道它是颠倒的还是向左或向右转动。还有什么想法吗?
    • 我不确定这有什么关系...为什么您需要知道手机是否倒置?手机的浏览器有一个顶部,网页将定向到浏览器的顶部。任何有两个脑细胞相互摩擦的用户,如果他们想看网页是正面朝上的,他们只会把手机转过来
    • 这有点苛刻。我很想知道,这样我就可以根据屏幕的方向显示不同的内容,这可能是多达 4 个不同的页面,需要浏览器知道它是否已经旋转了 0、90、180 和 270 度。这一切都是可能的,在 JavaScript 中,在 iPhone 上,这就是我问的原因。
    • 我仍然很难想象当网页在其上呈现的设备旋转 270 度时,它可以做什么不同的有用的事情,但如果你说你有一个有效的用例,我不会狡辩。在这种情况下:对不起,我不知道 Android 浏览器是否提供了这种详细程度。
    【解决方案5】:

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

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

    【讨论】:

    • 这个事件实际上更多是为了访问运动传感器,虽然我想它也可以用来检测方向变化。
    • 在我的 Android Galaxy S2 上,股票浏览器和 Dolphin 浏览器都不支持它。但适用于移动版 Firefox。
    【解决方案6】:

    我遇到了同样的问题。我正在为 Adroid 设备使用 Phonegap 和 Jquery mobile。 为了正确调整大小,我必须设置一个超时:

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

    【讨论】:

      【解决方案7】:

      解决办法如下:

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

      【讨论】:

      • 这是最适合我的解决方案,我知道它不是 100% 准确,但您可以使用以下方法检测水平与垂直: var screenWidth=$(window).width(); var screenHeight=$(window).height(); if(screenWidth > screenHeight) { doSomething(); }
      • 这个是我在蹩脚的 Android 平板电脑上的解决方案。 window.onresize、attachevent 和 addeventlistener 在多个事件(resize、onresize、orientationchange、deviceorientation)上失败。只有 Jquery $(window).on() 有效。
      【解决方案8】:

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

      【讨论】:

        【解决方案9】:

        你可以试试这个解决方案,兼容所有浏览器。

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

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

        【讨论】:

          【解决方案10】:

          值得注意的是,在我的 Epic 4G Touch 上,我必须先设置 webview 以使用 WebChromeClient,然后才能使用任何 javascript android 调用。

          webView.setWebChromeClient(new WebChromeClient());
          

          【讨论】:

            【解决方案11】:

            跨浏览器方式

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

            【讨论】:

              【解决方案12】:

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

              如 droid 手机表中所述,“orientationchange”事件比“resize”事件更早触发,因此阻止了下一个 resize 调用(因为 if 语句)。宽度属性仍未设置。

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

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

              希望对你有帮助

              (在 Nexus S 上进行了测试)

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2012-01-15
                • 2012-07-20
                • 2017-06-27
                • 2012-01-24
                • 2012-09-24
                • 1970-01-01
                • 2016-01-01
                • 1970-01-01
                相关资源
                最近更新 更多