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>



50 comments

      • Bas

        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?

        • Piotr

          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.

  1. J Haag

    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.

  2. Fritz

    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!

  3. Thomas Anderson

    Works great for me! I’m just fighting with padding while using ScrollView 4, but I think I can get it figured out!

  4. Panit

    This workaround really fixed the transition problem but introduced another problem at the scrolling performance. the long pages never scroll smoothly.

  5. Alex

    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

  6. Tuomas

    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; “

  7. John

    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?

    • John

      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

  8. Alex

    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

  9. Pingback: Kamran – HTML5: The hype and reality
  10. Alex

    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?

  11. Rodrigo

    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

  12. amarjt

    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?

  13. randy

    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

  14. Per Quested Aronsson

    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.

  15. Deviator

    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

  16. Daniel Thompson

    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.

  17. Pingback: Fixing flickers of jquerymobile page slide transition | 我们的博客
  18. wedgberto

    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';

https://outof.me

Post a comment

You may use the following HTML:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>