Will
Will

Reputation: 51

window.innerWidth incorrect in Chrome iOS 87.0.4280.77 after orientation change event

The window.innerWidth on Chrome iOS 87.0.4280.77 seems to be incorrect after orientation change event. When viewing on the iPhone, on initial load the innerWidth is 414px. After changing the phone orientation to landscape and then back to portrait, the innerWidth becomes 326px.

I've also checked the innerwidth using https://whatismyviewport.com and it shows the same innerwidth values as my code.

On initial load, before orientation change

After orientation change to landscape and back to portrait

<html>
<head>
   <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
</head>
<body>

<script type="text/javascript">
    alert("innerWidth1:"+window.innerWidth);  // initial innerwidth before orientation change

    window.addEventListener('orientationchange', function() {
        alert("innerWidth2:"+window.innerWidth);  // innerwidth after orientation change
    });

</script>

</body>
</html>

Has anyone else encountered this issue before?

Thank you

Upvotes: 5

Views: 2260

Answers (1)

A Haworth
A Haworth

Reputation: 36512

It seems the window.innerWidth reading has not changed when the orientationChange function is run, but if we set a timeout and read it again it has changed to its expected value.

Set the Pause in this snippet to see the effect. Note that (at least on Safari on IOS14.2 on iPad) a pause of 0ms is sufficient to force a reassessment of innerWidth.

I have tried to find official documentation of this behaviour but have so far failed, though there is quite a bit of discussion out there. It's as if the system has to 'repaint' the window and while doing so finds out the actual innerWidth. Anyway, a practical workaround seems to be to introduce the setTimeout, perhaps with 1ms pause 'just in case' rather than 0ms (I've seen Firefox not fire a repaint on 0ms on some systems in the past). Also, requestAnimationFrame did not result in getting the right width.

    <html>
    <head>
       <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
    </head>
    <body>
    <div id="info"></div>
    Pause: <button onclick="pause = 10000">10000</button>  <button onclick="pause = 10">10</button>  <button onclick="pause = 0">0</button>
    <script type="text/javascript">
        const info = document.getElementById('info');
        let pause = 10000; //number of ms to wait before read innerHTML again
        
        info.innerHTML = "innerWidth1:"+window.innerWidth;  // initial innerwidth before orientation change

        window.addEventListener('orientationchange', function() {
            info.style.color = 'red';
            info.innerHTML = "innerWidth on orientation change before pause:"+window.innerWidth;
            setTimeout(function() {info.style.color = 'blue';
                info.innerHTML = "innerWidth after orientation change and a pause of: " + pause + 'ms ' + window.innerWidth}, pause);  // innerwidth after orientation change
               });

    </script>

    </body>
    </html>

Upvotes: 4

Related Questions