2009-10-30 32 views
174

我知道,在iPhone上的Safari中,您可以通过侦听onorientationchange事件并查询window.orientation角度来检测屏幕的方向和方向更改。使用JavaScript检测Android手机在浏览器中的旋转情况

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

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

回答

203

为了检测在Android浏览器的方向变化,附加一个监听器orientationchangeresize事件上window

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

+0

这似乎不适用于Nexus One – Jeremy 2010-03-05 16:50:47

+0

更新了nexus one – 2010-03-05 23:53:24

+0

的代码是否确实有效?我试过jquery $(window).bind(“orientationchange”,fn);但它没有工作,我必须使用上面的表单吗?我在窗口中尝试了“onorientationchange”,它回复错误 – Ayyash 2010-08-16 01:19:59

12

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

+0

这是个好主意,我我会尝试(并要求我的朋友用Android手机来测试!) – philnash 2009-10-30 18:01:17

+0

我刚刚意识到,这种方法并不能给我手机的方向。我会知道它是纵向还是横向,但不是如果它是颠倒的,或者已经转向左侧或右侧。 还有其他想法? – philnash 2009-11-03 11:44:52

+0

我不确定它可能如何可能很重要...为什么你需要知道手机是否颠倒了?手机的浏览器有一个顶部,网页将面向浏览器的顶部。任何拥有两个脑细胞的用户,如果他们想要正确看到网页,他们就会翻转手机。 – 2009-11-03 18:54:12

211

跨不同设备的实际行为不一致。调整大小和orientationChange事件可以以不同的频率以不同的顺序发射。此外,某些值(例如screen.width和window.orientation)在您期望时并不总是变化。 避免screen.width - 在iOS中旋转时不会改变。

可靠的方法是侦听调整大小和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   | 
|----------------+-------------------+-------------+------------+--------------| 
+6

谢谢你的回答! – RichieHindle 2011-09-19 15:28:47

+0

这太棒了。 – ThinkingStiff 2012-04-17 08:22:16

+0

在iOS5仿真器中,如果在横向刷新然后旋转,则此代码不会触发。 – worked 2012-05-26 14:23:39

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

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

+4

这个事件实际上更多地用于访问运动传感器,尽管我认为它也可以用来检测方向变化。 – 2011-08-21 20:46:05

+0

在我的Android Galaxy S2上,它不支持股票浏览器和海豚浏览器。但与移动firefox很好。 – Eduardo 2012-01-27 22:55:17

-1

两个位傻瓜的回答一点贡献:

作为DROID手机放在桌子上描述的“orientationchange”事件被早于炒“调整”事件从而阻断下一个调整大小调用(因为如果声明)。宽度属性仍未设置。

尽管可能不是一个完美的解决方法,但可能不会触发“orientationchange”事件。这可以通过包装“orientationchange”事件绑定归档“如果”声明:

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

希望它可以帮助

(测试在Nexus S的完成)

0

值得一提的是,在我的4G的史诗触摸我必须在任何JavaScript android调用工作之前设置webview以使用WebChromeClient。

webView.setWebChromeClient(new WebChromeClient()); 
0

另一种疑难杂症 - 一些Android平板电脑(在摩托罗拉XOOM,我相信和低端Elonex一个我做了一些测试上,可能其他人也)有自己的加速度计设置,使window.orientation == 0在景观模式下,不是人像!

37

存储双比特的傻瓜的出色答卷提供所有的背景,但让我尝试如何处理跨iOS和Android方向变化的简洁,务实总结:

  • 如果你只在乎窗口尺寸(典型场景) - 而不是关于特定方向:
    • 仅处理resize事件。
    • 在您的处理程序中,仅对window.innerWidthwindow.InnerHeight采取行动。
    • 请勿使用window.orientation - 它不会在iOS上使用。
  • 如果你不关心特定方向
    • 手柄 Android上的resize事件,只有orientationchange事件iOS上。
    • 在您的处理程序,作用于window.orientation(和window.innerWidthwindow.InnerHeight

这些方法提供了在回忆以前的定位和比较轻微的好处:

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

问题是,当调整大小或方向事件触发window.innerWidth报告错误和Droid设备 – albanx 2015-12-16 17:25:09

2

我有同样的问题。我正在使用Phonegap和Jquery mobile,用于Adroid设备。 要正确调整,我不得不设置超时:

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

跨浏览器的方式

$(window).on('resize orientationchange webkitfullscreenchange mozfullscreenchange fullscreenchange', function(){ 
//code here 
}); 
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"); 
      } 
     }); 
    } 
+0

这是最适合我的解决方案,我知道它不是100%准确,但您可以使用此检测水平与垂直: var screenWidth = $(window).width(); var screenHeight = $(window).height(); if(screenWidth> screenHeight){doSomething(); } – math0ne 2015-09-04 19:17:47

+0

这是我在一款糟糕的Android平板电脑上的解决方案。 window.onresize,attachevent和addeventlistener在多个事件(调整大小,onresize,orientationchange,deviceorientation)上失败。只有jquery $(window).on()工作。 – Lego 2016-03-09 18:15:29

0

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

以下是orientationchange兼容性图: compatibility因此 ,我创作一个orientaionchange填充工具,它是一个基于@media属性来解决orientationchange实用library-- orientationchange-fix

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