I'm working on a mobile web app, and in my page I have a div
element with its width set to 100%.
I need to set the height of this div
so that the height is correct for a set aspect ratio. So for example, if the screen was sized to 300 pixels wide and the ratio was 3:2, my script should grab the width of the div
(which at this point should be 300px) and set the height to 200px.
On first load, this works perfectly. However, if I rotate the screen of my phone to landscape, the width of the div
obviously changes, so I need to reset its height in order to keep the correct ratio.
My problem is that I can't find an event which fires after the elements are resized. There is an orientationchange
event built into jQuery Mobile, which helpfully fires when the screen is rotated from portrait to landscape and vice-versa:
$(window).bind('orientationchange', function (e) {
// Correctly alerts 'landscape' or 'portrait' when orientation is changed
alert(e.orientation);
// Set height of div
var div = $('#div');
var width = div.width();
// Shows the *old* width, i.e the div's width before the rotation
alert(width);
// Set the height of the div (wrongly, because width is incorrect at this stage)
div.css({ height: Math.ceil(width / ratio) });
});
But this event seems to fire before any of the elements in the page have resized to fit the new layout, which means (as mentioned in the comments) I can only get the pre-rotation width of the div
, which is not what I need.
Does anyone know how I can get the div
's new width, after things have resized themselves?
A few methods for you to try:
(1) Set a timeout inside your orientationchange
event handler so the DOM can update itself and the browser can draw all the changes before you poll for the new dimension:
$(window).bind('orientationchange', function (e) {
setTimeout(function () {
// Get height of div
var div = $('#div'),
width = div.width();
// Set the height of the div
div.css({ height: Math.ceil(width / ratio) });
}, 500);
});
It won't make too big of a difference but note that Math.ceil
takes a lot longer to complete (relatively) than Math.floor
since the latter only has to drop everything after the decimal point. I generally just pass the browser the un-touched float number and let it round where it wants to.
(2) Use the window.resize
event instead to see if that updated fast enough for you:
$(window).bind('resize', function (e) {
// Get height of div
var div = $('#div'),
width = div.width();
// Set the height of the div
div.css({ height: Math.ceil(width / ratio) });
});
On a mobile device this will fire when the orientation changes since the size of the browser view-port will also change.
(3) If you are updating the size of this <div>
element because it holds an image, just apply some CSS to the image to make it always be full-width and the correct aspect ratio:
.my-image-class {
width : 100%;
height : auto;
}