13

I'm using jquery mobile and I'd like to reproduce this code:

$(document).ready(function () {
    $.mobile.loading('show');
});

it shows the spinner until I decide to hide it using in other functions

$.mobile.loading( 'hide' );

Now I see that document.ready() is deprecated in jquery mobile 1.2, so they suggest to replace it with $(document).on('pageinit')

But If I replace my code with the suggested one the spinner autohide... why? This is the new code:

 $(document).on('pageinit',function(){
     $.mobile.loading( 'show' );
 });
user1903894
  • 169
  • 1
  • 1
  • 6
  • Have a look at this question and its accepted answer: http://stackoverflow.com/questions/7544023/how-to-initialize-pages-in-jquery-mobile-pageinit-not-firing Seems it works when you bind the event to the actual page, not to the document. – Alejo Dec 14 '12 at 14:51

4 Answers4

11

Related:

This article can also be found as a part of my blog HERE.

Solution

First off all you need to understand jQM page events and their flow .

$(document).on('pageinit',function(){
    $.mobile.loading( 'show' );
});

is indeed a replacement for:

$(document).ready(function () {
    $.mobile.loading('show');
});

but jQM page consists from few phases. In your case, to be able to show a spinner you need to use pageshow event. Page must be shown to be able to show spinner. I have created an example for you: http://jsfiddle.net/Gajotres/Nncem/. In it go to next page to see a spinner. You can also replace pageshow with pageinit to see a difference.

You should use this code:

$(document).live('pageshow', function (e, data) {
    $.mobile.loading('show');
});  

But even this is not a correct way, best jQM way is to use this syntax:

$('div[data-role="page"]').live('pageshow', function (e, data) {
    $.mobile.loading('show');
});    

Or if you want to bind it to a single page use this:

$('#pageID').live('pageshow', function (e, data) {
    $.mobile.loading('show');
});  

Where pageID is an ID of your page.

$(document).on('pageinit') vs $(document).ready()

The first thing you learn in jQuery is to call code inside the $(document).ready() function so everything will execute as soon as the DOM is loaded. However, in jQuery Mobile, Ajax is used to load the contents of each page into the DOM as you navigate. Because of this $(document).ready() will trigger before your first page is loaded and every code intended for page manipulation will be executed after a page refresh. This can be a very subtle bug. On some systems it may appear that it works fine, but on others it may cause erratic, difficult to repeat weirdness to occur.

Classic jQuery syntax:

$(document).ready() { 

});

To solve this problem (and trust me this is a problem) jQuery Mobile developers created page events. In a nutshell page events are events triggered in a particular point of page execution. One of those page events is a pageinit event and we can use it like this:

$(document).on('pageinit', function(){

});

We can go even further and use a page id instead of document selector. Lets say we have jQuery Mobile page with an id index:

<div data-role="page" id="index">
    <div data-theme="a" data-role="header">
        <h3>
            First Page
        </h3>
        <a href="#second" class="ui-btn-right">Next</a>
    </div>

    <div data-role="content">
        <a href="#" data-role="button" id="test-button">Test button</a>
    </div>

    <div data-theme="a" data-role="footer" data-position="fixed">

    </div>
</div>

To execute a code that will only available to the index page we could use this syntax:

$('#index').on('pageinit', function(){

});

Pageinit event will be executed every time page is about be be loaded and shown for the first time. It will not trigger again unless page is manually refreshed or ajax page loading is turned off. In case you want code to execute every time you visit a page it is better to use pagebeforeshow event.

Here's a working example : http://jsfiddle.net/Gajotres/Q3Usv/ to demonstrate this problem.

Few more notes on this question. No matter if you are using 1 html multiple pages or multiple html files paradigm it is advised to separate all of your custom javascript page handling into a single separate js file. This will note make your code any better but you will have much better code overview, especially while creating a jQuery Mobile application.

There's also another special jQuery Mobile event and it is called mobileinit.When jQuery Mobile starts, it triggers a mobileinit event on the document object. To override default settings, bind them to mobileinit. One of a good examples of mobileinit usage is turning off ajax page loading, or changing default ajax loader behavior.

$(document).on("mobileinit", function(){
  //apply overrides here
});
Community
  • 1
  • 1
Gajotres
  • 57,309
  • 16
  • 102
  • 130
3

The

$(document).on('pageinit')

method is for jquery mobile to trigger after a dynamically page load occurs.

$(document).ready()

won't behave like

$(document).on('pageinit')

because it only trigger once when the page loads.

Licson
  • 155
  • 2
  • ok, but why here http://jquerymobile.com/test/docs/api/events.html the say to replace document.ready with document.on('pageinit') if the behaviuor is not the same? – user1903894 Dec 14 '12 at 12:16
  • It is because this matches jquery mobile's behaviour the most. Also, it'll trigger every time a page loads via jquery mobile. – Licson Dec 14 '12 at 12:24
  • please check the added link into my answer – Rohan Patil Dec 14 '12 at 12:38
  • Of course I've checked that. Jquery mobile uses ajax to load pages and it'll trigger every time when a page loads using ajax but the document has never refreshed so $(document).ready() will only trigger once. This is different than the way we except so it's recommend to use $(document).on('pageinit'). – Licson Dec 14 '12 at 12:45
  • so, I'd like to solve my problem, that is to continue to show the spinner until I decide to stop (using click, or other events), without using document.ready... – user1903894 Dec 14 '12 at 13:29
1

Try

for show

$.mobile.showPageLoadingMsg();

for hide

$.mobile.hidePageLoadingMsg();

you must hide the spinner if you dynamically appending the content

check this one

Rohan Patil
  • 1,865
  • 1
  • 23
  • 36
  • 1
    $.mobile.showPageLoadingMsg(); and $.mobile.hidePageLoadingMsg(); are deprecated in jquery mobile 1.2. I'd like to use only code not deprecated – user1903894 Dec 14 '12 at 12:14
  • @user1903894 whats the exact problem can you explain you want to hide spinner or its hiding automatically ? – Rohan Patil Dec 14 '12 at 12:21
  • please check the added link into my answer – Rohan Patil Dec 14 '12 at 12:36
  • I'd like to show the spinner when the page is loaded without hiding it, until I execute an operation (click, or other). Your link is the same i posted before in one of the answers – user1903894 Dec 14 '12 at 13:27
1

pageinit is not used when a dynamic page load occurs. That is not the case. The reason is because document.ready() will only get called once. This means if you have multiple pages where you want to do something when it is ready, you can't do so.

So, document.ready() will work one time only, but pageinit will work any time a page is initialized.

Miz
  • 51
  • 1