开发者

Show Page Loading Spinner on Ajax Call in jQuery Mobile

开发者 https://www.devze.com 2023-03-30 21:02 出处:网络
I\'m using $.ajax() to populate a list in my mobile web app. What I\'d like to do is have the jQuery mobile loading spinner appears while this call is being performed and disappear once the list popul

I'm using $.ajax() to populate a list in my mobile web app. What I'd like to do is have the jQuery mobile loading spinner appears while this call is being performed and disappear once the list populates. The current version of JQM uses $.mobile.showPageLoadingMsg() and $.mobile.hidePageLoadingMsg() to show and hide the loading spinner, respectively. I can't figure out where exactly to place these statements to get the correct result. This seems like it should be a fairly easy thing to accomplish, I just haven't been able to find anything about this exact scenario.

Here's the ajax call inside the pagecreate function:

$('#main').live('pagecreate', function(event) {
        $.ajax({
            url: //url
            dataType: 'json',
            headers: //headers
            success: function(data) {
                for(i = 0; i < data.length; i++) {
                    $('#courses').append('<li>' + data[i].name + '<ul id="course' + data[i].id + '"></ul>' + '<span class="ui-li-count">' + data[i].evaluatedUserIds.length + '</span></li>');
                    $('#course' + data[i].id).listview();
                    for(j = 0; j < data[i].evaluatedUserIds.length; j++) {
                        $('#course' + data[i].id).append('<li><a hre开发者_运维知识库f="">' + data[i].evaluatedUserIds[j] + '</a></li>');
                    }
                    $('#course' + data[i].id).listview('refresh');
                }
                $('#courses').listview('refresh');
            }
        });
    });


You can use the beforeSend and complete events of $.ajax to call $.mobile.showPageLoadingMsg and $.mobile.hidePageLoadingMsg. Would look like this:

$('#main').live('pagecreate', function(event) {
        $.ajax({
            beforeSend: function() { $.mobile.showPageLoadingMsg(); }, //Show spinner
            complete: function() { $.mobile.hidePageLoadingMsg() }, //Hide spinner
            url: //url
            dataType: 'json',
            headers: //headers
            success: function(data) {
                //...
            }
        });
    });


Before JQM 1.2:

$(document).ajaxStart(function() {
    $.mobile.showPageLoadingMsg();
});

$(document).ajaxStop(function() {
    $.mobile.hidePageLoadingMsg();
});

Since JQM 1.2:

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

$(document).ajaxStop(function() {
    $.mobile.loading('hide');
});

http://api.jquerymobile.com/page-loading/


A few people have asked about the workaround I ended up implementing, so I figured I'd share it. It's nothing particularly elegant or complicated, but it did seem to work. I haven't used the framework since the official 1.0 was released, so this may have been solved in the update. Essentially, I put the $.mobile.showPageLoadingMsg() call into the pageshow function, but wrapped it in an if clause that only fires the first time the page is shown:

var mainloaded = false;

$('#main').live('pageshow', function(event) {   //Workaround to show page loading on initial page load
    if(!mainloaded) {
    $.mobile.showPageLoadingMsg();
    }
});

$('#main').live('pagecreate', function(event) { 
    $.ajax({
        url: //url
        dataType: //datatype,
        headers: //headers
        success: function(data) {
            //
            //...loading stuff
            //
            $.mobile.hidePageLoadingMsg();
            mainloaded = true;
        }
        //
        //...handle error, etc.
        //
    });
});


This is a bit late...but you need to:

  1. Call $.mobile.showPageLoadingMsg() before the AJAX call.
  2. Make the AJAX call. The call needs to be sent asynchronously (put async: true in your call).
  3. Add $.mobile.hidePageLoadingMsg() in your success() function.


$(document).ajaxSend(function() {
    $.mobile.loading( 'show');
});
$(document).ajaxComplete(function() {
    $.mobile.loading( 'hide');
});


You should do $.mobile.showPageLoadingMsg() just before the ajax call, and $.mobile.hidePageLoadingMsg() in the success (or fail) block so it goes away once a result comes back.

I've never used jQuery mobile, but it should operate the same as showing/hiding a regular ol' spinning image.


Or, the simplest way is to put it globally as a separation of concern -

Put below code into your master/layout view

   <script type="text/javascript">

    $(document).bind('mobileinit', function () {
        //Loader settings
        $.mobile.loader.prototype.options.text = "Loading..";
        $.mobile.loader.prototype.options.textVisible = true;
        $.mobile.loader.prototype.options.theme = "b";
        $.mobile.loader.prototype.options.textonly = false; 
    }); 

    $(document).on({
        ajaxSend: function () { $.mobile.showPageLoadingMsg(); },
        ajaxStart: function () { $.mobile.showPageLoadingMsg(); },
        ajaxStop: function () { $.mobile.hidePageLoadingMsg(); },
        ajaxError: function () { $.mobile.hidePageLoadingMsg(); }
    });

</script> 

Edit: Please use instead if you are targeting latest version of JQM (>1.2):

  • $.mobile.loading('show');
  • $.mobile.loading('hide');


The problem here is that the call to $.ajax() happens within the control flow of the event handler (the caller).

A very simple way to decouple the ajax request from this control flow is to let setTimeout() invoke this function for you, like so:

setTimeout(function(){$.ajax( ... )}, 1);

You can then use the 'beforeSend' and 'complete' events of $.ajax() as stated before and be sure, that your spinner is showing up.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号