Detect rotation of Android phone in the browser with JavaScript
I know that in Safari on an iPhone you can detect the screen's orientation and change of orientation by listening for the onorientationchange
event and querying window.orientation
for the angle.
Is this possible in the browser on Android phones?
To be clear, I am asking whether the rotation of an Android device can be detected by JavaScript running on a standard web page. It is possible on an iPhone, and I wondered whether it could be done for Android phones.
To detect an orientation change on an Android browser, attach a listener to the orientationchange
or resize
event on 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);
Check the window.orientation
property to figure out which way the device is oriented. With Android phones, screen.width
or screen.height
also updates as the device is rotated. (this is not the case with the iPhone).
The actual behavior across different devices is inconsistent . The resize and orientationChange events can fire in a different sequence with varying frequency. Also, some values (eg screen.width and window.orientation) don't always change when you expect. Avoid screen.width -- it doesn't change when rotating in iOS.
The reliable approach is to listen to both resize and orientationChange events (with some polling as a safety catch), and you'll eventually get a valid value for the orientation. In my testing, Android devices occasionally fail to fire events when rotating a full 180 degrees, so I've also included a setInterval to poll the orientation.
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);
Here are the results from the four devices that I've tested (sorry for the ASCII table, but it seemed like the easiest way to present the results). Aside from the consistency between the iOS devices, there is a lot of variety across devices. NOTE: The events are listed in the order that they fired.
|==============================================================================| | 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 | |----------------+-------------------+-------------+------------+--------------|
two-bit-fool's excellent answer provides all the background, but let me attempt a concise, pragmatic summary of how to handle orientation changes across iOS and Android :
resize
event only. window.innerWidth
and window.InnerHeight
only. window.orientation
- it won't be current on iOS. resize
event on Android, and only the orientationchange
event on iOS. window.orientation
(and window.innerWidth
and window.InnerHeight
) These approaches offer slight benefits over remembering the previous orientation and comparing:
window.orientation
is not available on desktop browsers). 上一篇: 检测WebP支持