Detect iOS Device Orientation with JavaScript
JavaScript gives us a way to determine the current orientation of iOS devices (iPhone, iPad, iPod). When the device is rotated a property of the window object is updated and an event dispatched.
Read Device Orientation
The window
object in JavaScript on iOS devices has an orientation
property that can be used to determine the rotation of the device. The following shows the values window.orientation
for iOS devices (e.g. iPhone, iPad, iPod) at different orientations.
Values of 0 and 180 represent a landscape orientation. Values of -90 and 90 represent portrait.
Let's create a function called readDeviceOrientation
which will determine the device's current orientation.
function readDeviceOrientation() { switch (window.orientation) { case 0: // Portrait break; case 180: // Portrait (Upside-down) break; case -90: // Landscape (Clockwise) break; case 90: // Landscape (Counterclockwise) break; } }
We can simplify this using an if statement if we only care if the device is portrait or landscape and not clockwise, counterclockwise etc.
function readDeviceOrientation() { if (Math.abs(window.orientation) === 90) { // Landscape } else { // Portrait } }
Listen for Device Orientation Change
An event is dispatched when the device is rotated. We set the onorientationchange
property to the function we just made. It will be invoked when the device is rotated.
window.onorientationchange = readDeviceOrientation;
Demo
Let's build a quick demo that updates a message when an iOS device is rotated.
The markup:
<html> <head> <title>iOS Orientation Demo</title> </head> <body> <p id="orientation">Rotate device to determine orientation</p> <script src="iOS-orientation-demo.js"></script> </body> </html>
The JavaScript:
function readDeviceOrientation() { if (Math.abs(window.orientation) === 90) { // Landscape document.getElementById("orientation").innerHTML = "LANDSCAPE"; } else { // Portrait document.getElementById("orientation").innerHTML = "PORTRAIT"; } } window.onorientationchange = readDeviceOrientation;
Now we can launch the demo on an iOS device and then rotate to see "Portrait" or "Landscape".
Initial Orientation Read
If we want to know the orientation before it is rotated we can invoke the readDeviceOrientation
function directly. I have run into an issue doing this with the iPhone as we will see in a second.
readDeviceOrientation();
IPhone Initial Read Issue
Attempting to access window.orientation
before the iPhone is rotated has produced unexpected results when launching a document in a new tab.
I wrote a test to reproduce the behavior. The demo displays the value and time of the first orientation reported. When the orientation value changes it displays that new value and time. The document onload time is also displayed.
The markup:
<html> <head> <title>iOS Orientation Test</title> </head> <body> <dl> <dt>First Orientation</dt> <dt id="first">?</dt> <dt>Second Orientation</dt> <dt id="second">?</dt> <dt>Document Load Time</dt> <dt id="loadTime">?</dt> </dl> <script src="iOS-orientation-demo.js"></script> </body> </html>
The JavaScript:
var numOrientationChanges = 0, lastOrientation, startTime = + new Date(), timer; function readDeviceOrientation() { var orientationLabel, curTime = + new Date() - startTime; if (Math.abs(window.orientation) === 90) { // Landscape orientationLabel = "LANDSCAPE " + window.orientation; } else { // Portrait orientationLabel = "PORTRAIT " + window.orientation; } if (lastOrientation !== window.orientation) { if (numOrientationChanges === 0) { document.getElementById("first").innerHTML = orientationLabel + " (" + curTime + " ms)"; } else if (numOrientationChanges === 1) { document.getElementById("second").innerHTML = orientationLabel + " (" + curTime + " ms)"; clearInterval(timer); } lastOrientation = window.orientation; numOrientationChanges += 1; } } window.onorientationchange = readDeviceOrientation; window.onload = function () { readDeviceOrientation(); document.getElementById("onLoad").innerHTML = (+ new Date() - startTime) + " ms"; }; readDeviceOrientation(); timer = setInterval(readDeviceOrientation, 1/60);
To reproduce the issue launch the test on an iPhone 4 in landscape mode. The value of window.orientation
will start with "0", which is incorrect (portrait not landscape). After a period of time (my tests have averaged about 400 ms) it will update to the correct orientation.
Download Source Code
- Download Simple iOS Orientation Demo (HTML, JavaScript)
- Download iOS Orientation Test (HTML, JavaScript)