使用 JavaScript 在浏览器中检测 Android 手机的旋转
Posted
技术标签:
【中文标题】使用 JavaScript 在浏览器中检测 Android 手机的旋转【英文标题】:Detect rotation of Android phone in the browser with JavaScript 【发布时间】:2010-12-11 13:39:06 【问题描述】:我知道在 iPhone 上的 Safari 中,您可以通过侦听 onorientationchange
事件并查询 window.orientation
的角度来检测屏幕的方向和方向变化。
这可以在安卓手机的浏览器中实现吗?
为了清楚起见,我问的是 android 设备的旋转是否可以通过在标准网页上运行的 JavaScript 检测到。在 iPhone 上可以,我想知道是否可以在 Android 手机上实现。
【问题讨论】:
【参考方案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
上的 orientationchange
或 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 的情况)。
【讨论】:
这真的有效吗?我试过 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.innerWidth
和 window.InnerHeight
执行操作。
不要使用window.orientation
- 它在 iOS 上不是最新的。
如果您确实关心特定方向:
仅处理 Android 上的 resize
事件,仅处理 iOS 上的 orientationchange
事件。
在您的处理程序中,对window.orientation
(以及window.innerWidth
和window.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 上进行了测试)
【讨论】:
以上是关于使用 JavaScript 在浏览器中检测 Android 手机的旋转的主要内容,如果未能解决你的问题,请参考以下文章