Reputation: 51
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
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