iphone/ipad triggering unexpected resize events
JavascriptJqueryIphoneCssMobileJavascript Problem Overview
I'm working on a mobile version of my site. I'm using media queries and CSS as much as possible, but I'm also using some javascript to, for example, turn my navigation into a collapse/expand list on smaller devices to save room.
To handle all of this, I was attempting to use the window.resize event. This allows the magic to happen on desktop browsers while they're resized, but I'm getting resize events on iPad/iPhone when I'm not expecting them.
On desktop browsers, I only get a resize event if I actually resize the window. On mobile browsers I get the resize event when I change orientation (expected), but I also get it when I toggle to expand/collapse something.
Here's a simple example:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<title>Resize test</title>
<style>
.box {height: 10000px; background: green; display: none;}
</style>
<script>
$(function(){
$(".opener").click(function(){
$(".box").slideToggle();
});
$(window).resize(function(){
alert("resized");
});
});
</script>
</head>
<body>
<a href="#" class="opener">Open/close me</a>
<div class="box"></div>
</body>
</html>
When you click the link on a desktop browser, no alert. Click the link on iPhone/iPad, you get the alert. What's the deal?
Javascript Solutions
Solution 1 - Javascript
Store the window width and check that it has actually changed before proceeding with your $(window).resize
function:
jQuery(document).ready(function($) {
// Store the window width
var windowWidth = $(window).width();
// Resize Event
$(window).resize(function(){
// Check window width has actually changed and it's not just iOS triggering a resize event on scroll
if ($(window).width() != windowWidth) {
// Update the window width for next time
windowWidth = $(window).width();
// Do stuff here
}
// Otherwise do nothing
});
});
Solution 2 - Javascript
Here's the vanilla javascript version of the accepted answer
document.addEventListener('DOMContentLoaded', function() {
// Store the window width
var windowWidth = window.innerWidth
// Resize Event
window.addEventListener("resize", function() {
// Check window width has actually changed and it's not just iOS triggering a resize event on scroll
if (window.innerWidth != windowWidth) {
// Update the window width for next time
windowWidth = window.innerWidth
// Do stuff here
}
// Otherwise do nothing
})
})
Solution 3 - Javascript
I needed to specify a width:
<meta name="viewport" content="width=1000, initial-scale=1.0, user-scalable=yes">
Styles:
html, body
{
height:100%;
width:100%;
overflow:auto;
}
Solution 4 - Javascript
I found out the answer in StackOverflow itself link of the solution. it's the answer by sidonaldson
that helped me solve an issue faced earlier like this. ty
the answer is:
var cachedWidth = $(window).width();
$(window).resize(function(){
var newWidth = $(window).width();
if(newWidth !== cachedWidth){
//DO RESIZE HERE
cachedWidth = newWidth;
}
});
Solution 5 - Javascript
Is the assumption wrong, that you only want to have the effect of the resize event on a non-touch device? If so you could just use Modernizr and do a check like:
$(window).resize(function(e){
if(Modernizr.touch) {
e.preventDefault();
}
});
Solution 6 - Javascript
Check if your explicitly scrolling the html body wrapper to hide the address bar when the page loads.
Solution 7 - Javascript
@3stripe has the correct answer.
This is just a slight modification which makes it more efficient by caching the window object rather than repeatedly instantiating jQuery (keep in mind the resize
event may be called rapidly on an actual resize).
jQuery(document).ready(function($) {
// Cached window jQuery object
var $window = $(window);
// Store the window width
var windowWidth = $window.width();
// Resize Event
$window.resize(function(){
// Check window width has actually changed and it's not just iOS triggering a resize event on scroll
if ($window.width() != windowWidth) {
// Update the window width for next time
windowWidth = $window.width();
// Do stuff here
}
// Otherwise do nothing
});
});
Solution 8 - Javascript
It feels hacky to check the window size to see if it's changed. Instead, use the resources jQuery provides you!
In the event handler, you can check the jQuery event's target
field, which is always set to the DOM element that originated the event. If the user resizes the window, target
will be the window. If the user resizes #someDiv
, target
will be the #someDiv
.
$(window).on('resize', function(event) {
if ($(event.target).is($(window))) {
doTheThing();
}
});