6

I've got a Phonegap & jQuery Mobile app that works nicely on Android and web. On iOS I am getting unexpected results, which seem to be caused by the fact that the document.pageinit event to which I bind the handler for most of the app's processes is fired twice.

No, I didn't bind it twice. No, I didn't use document.ready. Yes, I did bind it to the document, early on in the script and not inside any other function.

$(document).on('pageinit',function(event){
    alert(' Pageinit on document');
    //Some more code
})

The first time it fires, the splash screen is still showing. At this point, while testing on a MacBook Pro with XCode, the console is not even avaiable: the above message didn't show up in the console when I used console.log.

Second time around, the fires shortly after jQueryMobile has created the first page.

What is causing this double firing and what can I do about it?

EDIT: I noticed later on that pageinit doesn't just fire a second time, but every time I open a new data-role='page' div. See my answer below.

Wytze
  • 7,844
  • 8
  • 49
  • 62

4 Answers4

15

I appreciate Zoltans answer and it may be relevant in some cases, but that was not the cause.

$(document).on('pageinit') will fire for every page transition used in your jQuery Mobile app. This will happen both with HTML links and when using $.mobile.changePage();.

Shockingly, the docs don't mention this anywhere: they advise you to use it without mentioning that it will fire for every subsequent page.

I can't believe that they are framing this problematic example as a valid equivalent of $(document).ready().

They should be advising you to bind using .one() instead of .bind() or on() to avoid multiple code execution.

raoul_dev
  • 1,396
  • 12
  • 16
Wytze
  • 7,844
  • 8
  • 49
  • 62
  • Thaaaaank you! I was looking for solution for the last several minutes, Google gives nothing for "pageinit called twice", and your `.one()` is ideal solution. I would upvote by ten if I could :) – PiotrK Apr 13 '13 at 00:15
  • Somewhat surprisingly, I've seen this behavior when using my app's code in desktop browsers (IE10 and Chrome/Windows) and not in iOS. This suggested fix helped those cases, too. Great suggestion. Thanks! – JA_251 Sep 04 '13 at 20:15
2

It happens because i think you use jquery and jquery mobile together. But the solution is simple. Try

$(document:not(.processed)).addClass('processed').on('pageinit',function(event)

This should solve it

Zoltan Varadi
  • 2,468
  • 2
  • 34
  • 51
2

Edit body to <body data-role="page"> should solve the problem.

gfreezy
  • 98
  • 7
0

I was struggling with that problem too long to not share with others. And I think it is not only problem under iOS but under Android as well (it caused flickering in my case).

"pageinit" event was called twice each time a request has been made. First one was the proper one to get data for provided url, another one was called after new page was loaded into DOM (jQueryMobile page dynamically injected into document). I think there are more solutions to solve this problem, here goes mine:

$(document).ready(function(){
    $(this).delegate("#page-selector", "pageinit", function(ev, data){}); 
    // I don't know why the line has to be present, but otherwise does not work
});

And my HTML document looks like:

<html>
<head>...here goes scripts...</head>
<body>
   <div id="#page-selector"> <!-- just wrapper -->
       <div data-role="page">
        ... content...
       </div>
   </div>
</body>
</html>

I hope it will spare precious time for others!

Piotr Czyż
  • 2,702
  • 2
  • 21
  • 15