JQuery mobile show loader for custom loading process

cssjqueryjquery-mobilejquery-mobile-loadersetinterval

I'm building a web application that is rich in images and interactive elements. For these reasons I only want to display the page once all images are loaded:

$(document).on('pageinit', function(){
    $('.ui-content').hide();
    var imgs = $(".ui-content img").not(function() { return this.complete; });
    var count = imgs.length;
    if (count) {
        imgs.load(function() {
            count--;
            if (!count) {
                $(".ui-content").show()
            }
        });
    } else {
        $(".ui-content").show();
    }
});

I need to either a) remove the loader completely and replace it with my own, or b) have the loader stay up until the above function finishes.

How do I either remove the loader or keep it up until not needed?

Best Answer

jQuery Mobile custom loader

Solution:

Working jsFiddle: http://jsfiddle.net/Gajotres/vdgB5/

Mobileinit event must be initialized before jQuery Mobile is initialized and after jQuery. Also some additional changes to css must be done for this to work.

First of all, we need to override default ui-loader-default class because its opacity is to low and final spinner is hard to see. Change opacity value how ever you want.

.ui-loader-default {
    opacity: 1 !important;      
}

And this is our spinner.

.custom-spinner {
    width: 37px !important;
    height: 37px !important;
    background-image:url('http://pictures.reuters.com/ClientFiles/RTR/Images/ajax-loader.gif');
    display: block;
}

Here's a working example:

Code example

HTML:

<!DOCTYPE html>
<html>
    <head>
        <title>jQM Complex Demo</title>
        <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=no; target-densityDpi=device-dpi"/>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
        <style>

            .ui-loader-default {
                opacity: 1 !important;      
            }

            .custom-spinner {
                width: 37px !important;
                height: 37px !important;
                background-image:url('http://pictures.reuters.com/ClientFiles/RTR/Images/ajax-loader.gif');
                opacity: 1 !important;
                display: block;
            }
        </style>
        <script type="text/javascript" src="http://www.dragan-gaic.info/js/jquery-1.8.2.min.js"></script>
        <script>
            $( document ).bind( 'mobileinit', function(){
                $.mobile.loader.prototype.options.text = "loading";
                $.mobile.loader.prototype.options.textVisible = false;
                $.mobile.loader.prototype.options.theme = "a";
                $.mobile.loader.prototype.options.html = "<i class='custom-spinner'></i>";
            }); 
        </script>       
        <script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>    
        <script>
            $(document).on('pageshow', '#index', function(){        
                $.mobile.loading( 'show');          
            }); 
        </script>
    </head>
    <body>
        <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">

            </div>

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

            </div>
        </div> 
    </body>
</html>   

Programmatic execution of jQuery mobile ajax loader

Some browsers, including webkit browser like Chrome have a programmatic execution of jQuery mobile ajax loader. They can be executed manually with serinterval, like this:

$(document).on('pagebeforecreate', '#index', function(){     
    var interval = setInterval(function(){
        $.mobile.loading('show');
        clearInterval(interval);
    },1);    
});

$(document).on('pageshow', '#index', function(){  
    var interval = setInterval(function(){
        $.mobile.loading('hide');
        clearInterval(interval);
    },1);      
});