Fixing flickers & jumps of jQuery Mobile transitions in PhoneGap apps
Recently I have been working on a mobile app that uses jQuery Mobile 1.1.0 as a UI framework. In general I’ve had really good experience with jQuery Mobile except it gave me some headaches when it came to page transitions. Some really weird flickers and jumps started to popup when I deployed it on the iOS 5.x platform as a PhoneGap app. This was something I didn’t experience when the same code was running in a device browser. After a few hours of digging into the issue I came up with a workaround that I didn’t find anywhere else and that solved all my problems I actually have seen all kinds of fixes to similar issues but I think this one is least invasive, because it doesn’t involve any framework code tweaks.
Ok, so what worked for me was instead of using s body tag as a page container I used an absolutely positioned div inside of a body (this approach was okay for me as I used the -webkit-overflow-scrolling: touch;
CSS property for scrolling pages content). I know this may not be the ideal solution for everyone but I think it is really good one when working with PhoneGap or other UIWebView based containers.
UPDATE 13.07.2012: I’m still using this with just released jQuery Mobile 1.1.1 version, which unfortunately didn’t solve all the transition quirks I’ve experienced.
UPDATE 04.10.2012: You may also want to read this post about native scrolling with this approach.
Below is a template of my index.html that does the trick:
<!DOCTYPE html> <html> <head> <title>jQuery Mobile transitions flickers & jumps workaround</title> <meta charset="utf-8"> <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"> <link rel="stylesheet" href="scripts/libs/jquery.mobile/jquery.mobile-1.1.0.css"/> <style type="text/css"> body { /* Setting body margins to 0 to have proper positioning of #container div */ margin: 0; } /* #container div with absolute position and 100% width and height so it takes up whole window */ #container { position: absolute; width: 100%; height: 100%; } </style> <script type="text/javascript" src="scripts/libs/jquery/jquery-1.7.1.js"></script> <script type="text/javascript"> $(document).one("mobileinit", function () { // Setting #container div as a jqm pageContainer $.mobile.pageContainer = $('#container'); // Setting default page transition to slide $.mobile.defaultPageTransition = 'slide'; }); </script> <script type="text/javascript" src="scripts/libs/jquery.mobile/jquery.mobile-1.1.0.js"></script> </head> <body> <!-- jqm pages container --> <div id="container"/> </body> </html>
What are the issues resolved with 1.1.1 related to Flickers & Jumps in your page
For jQM 1.1.1 it solves issue of showing/blinking a page that transition is navigating to before transition actually ends.
I still have this problem on the iPad, but only if the page is started from the home screen in full screen. It shows the next page before transition begins. Any solutions?
Sorry, I didn’t do anything with jQM and iPad yet so I don’t have a solution. For sure if I find something I will post it here.
p.
I tried this on android 2.3 and it worked nicely for improving the flicker. However, on long pages it prevents scrolling down (swiping down) for some reason.
Try using native scrolling that works with this approach.
Thanks! That really helped.
I searched for several hours and found this:
.ui-page {
-webkit-backface-visibility: hidden;
}
which didn’t worked!
your solution works fine for me!
thank you sooooo much man!
Works great for me! I’m just fighting with padding while using ScrollView 4, but I think I can get it figured out!
I don’t get it, how do I go on from here? Do i append the div? (Yes I am new to this)
This workaround really fixed the transition problem but introduced another problem at the scrolling performance. the long pages never scroll smoothly.
Hi this is great, except what class / id to I apply -webkit-overflow-scrolling: touch; too to fix the scrolling style.
I have tried, .ui-content but no luck there.
Thanks
Check this out, about native scrolling.
Hey Piotr, have you tried this when you have more than one page element in a single html doc? Or are you using multiple html pages?
This has been only trick that worked for me. But now scrolling is much harder. It doesn’t go as smooth as earlier and when you go bottom of the page and try to go up it pumps the top of the page all the time like showing that it’s already in the top of the page.
Is there something to do with this declaration what is mentioned also in this post: “-webkit-overflow-scrolling: touch; “
Take a look at native scrolling.
YES. Thank you. I tried almost everything I could find but this is the only thing that worked.
JQM 1.1.1 is awesome.. so many issues solved
Tried this with iscrollview saw a slight improvement.
I now have the the problem that after a number of page changes – where you call changepage, it bounces to the new page and then back to the previous page, so not just ugly but difficult to change page. Originally thought this was a back button issue but happens on changePage too.
Get’s steadily worse the more you flick between pages.
All pages are internal (phonegap) and more are dynamically injected, is this the same issue or something else, thanks for any help?
I don’t think it’s a problem of this solution, I would expect either iScroll thing or jQM.
p.
Answering my own question – but might be useful to others.
Basically (possibly due to iscrollview – which is great) events are firing twice or more. (adding console.log statements to the below, I could see multiple events firing. But only afterward multiple documents loaded) eg
$(document).delegate(‘#block’+i , ‘swiperight’,function(event){
var pageTo=$(this).attr(‘id’);
pageTo=pageTo.substring(pageTo.indexOf(‘block’)+5);
pageTo=’#block’+(parseInt(pageTo-1));
if ($(this).attr(‘id’) == $.mobile.activePage.data(‘url’)) { //// added this and sorted the problem
$.mobile.changePage(pageTo, {
transition: “slide” });
}
});
Annoyingly the problem seems to get worse the more pages are flipped, but this will keep me happy till jqm 1.2 is release I guess
It works for me! ^^great thanks to you~
Hi,
Please can you let us know how you fix the scrolling style with technique, I have tried adding -webkit-overflow-scrolling: touch; to an array of selectors but none work at all.
I have also tried adding a container around and applying -webkit-overflow-scrolling: touch; to the surrounding div but still no joy.
You mention it in your post, how do you fix the scrolling style? Please help, using just jQueryMobile
Here is an intro how to make native scrolling work with this approach.
+1 to this definitely, have put this in to my app and it’s running like a charm now!
Great advice, thanks for sharing!
That is, without a doubt, the best solution for this. Worked great!
Thank You!
This is great and its working beautifully on iOS now. I just noticed though its not working on Android 4.0.4 I still get the flickered page transition, so frustrating…
Should this fix work on Android as well or is it just for iOS?
I am using jQM 1.1.1 with PhoneGap 2.1, and this WORKS! Thank you very much!
I am using jQM 1.1.1 with PhoneGap 2.1, and it works also for me.
But I only need to set “user-scalable=no” in the viewport-line:
That’s all.
You are a life saver.
I spent my saturday trying to solve this issue and your post was the one that helped me.
thanks a lot
By the way, im using jquery 1.2.0 and phonegap 2.1.0
didn’t work for me, can you share your code.
is it works for Android too?
Yes, it works for me with Android. I tested it with 4.0.
Just set into the section:
”
meta name=”viewport” content=”user-scalable=no, width=device-width, initial-scale=1″
It works for me only for 4.1 and does not work for 2.3.4. or 4.03. I tried with JQM 1.1.1/1.2 and phoneGap 1.2. Haag mentoned, it works for him. do we need some other setting for 2.3.4?
thank you, this really helped me!
hi there, i have still an issue about this flicker. It shows some flicker when transition from one page to another page. the flicker shows about 1/10 sec, but still annoying. how to fix this issue? ( using samsung galaxy tab 7+, android 3.2)
thanks
FYI, I just downloaded the jQM 1.3 beta and the flickering has improved exponentially. It’s still not perfect, but it’s much better…
Thanks. It does improve page transition on jqm 1.3 and phonegap 2.3
This worked for me,
$(function() {
$.mobile.defaultHomeScroll = 0;
});
Thank you! This saved me many, many hours of debugging. It transformed a completely dysfunctional UI into a smooth and functional one. I am very surprised that such a popular framework as Jquery Mobile works so poorly in Phonegap. I’m using 1.2.0.
Hey used this solution with JQM 1.2 & own packaging framework not Phonegap.
But performance issues with larger scrolling pages.
Also when i try doing $(window).ScrollTop() there is flickering experienced
Hi I try with this solution and it works for android 4.x, jqm 1.3.1 and cordova 2.5.0, but I have a strange behavior when I touch a html select dropdown, the transition is flickers again after navigate with the others html.
Whoa, thanks!
With Cordova 2.4.0 and JQM 1.3.1 I found that $.mobile.pageContainer = $(‘#container’); caused text inputs and text areas to behave oddly (at least in android). My number inputs would not honour the “pattern” attribute and triggered the alphanumeric keypad. After removing the #container div from my main html and commenting out $.mobile.pageContainer = $(‘#container’); my input controls started to behave as expected. I tried changing $.mobile.pageContainer to try to fix the flickery page transitions but I gave up on that and resigned myself to $.mobile.defaultPageTransition = ‘none';
Thanks!!