Detect iOS Device Orientation with JavaScript

by William Malone
IOS Device Rotated

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.

iPhone-orientation

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

iPhone orientation 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

References

Related Articles

Share this Article