622

I would like to place a "please wait, loading" spinning circle animation on my site. How should I accomplish this using jQuery?

Shog9
  • 156,901
  • 35
  • 231
  • 235
thedp
  • 8,350
  • 16
  • 53
  • 95

20 Answers20

1290

You could do this various different ways. It could be a subtle as a small status on the page saying "Loading...", or as loud as an entire element graying out the page while the new data is loading. The approach I'm taking below will show you how to accomplish both methods.

The Setup

Let's start by getting us a nice "loading" animation from http://ajaxload.info I'll be using enter image description here

Let's create an element that we can show/hide anytime we're making an ajax request:

<div class="modal"><!-- Place at bottom of page --></div>

The CSS

Next let's give it some flair:

/* Start by setting display:none to make this hidden.
   Then we position it in relation to the viewport window
   with position:fixed. Width, height, top and left speak
   for themselves. Background we set to 80% white with
   our animation centered, and no-repeating */
.modal {
    display:    none;
    position:   fixed;
    z-index:    1000;
    top:        0;
    left:       0;
    height:     100%;
    width:      100%;
    background: rgba( 255, 255, 255, .8 ) 
                url('https://i.stack.imgur.com/FhHRx.gif') 
                50% 50% 
                no-repeat;
}

/* When the body has the loading class, we turn
   the scrollbar off with overflow:hidden */
body.loading .modal {
    overflow: hidden;   
}

/* Anytime the body has the loading class, our
   modal element will be visible */
body.loading .modal {
    display: block;
}

And finally, the jQuery

Alright, on to the jQuery. This next part is actually really simple:

$body = $("body");

$(document).on({
    ajaxStart: function() { $body.addClass("loading");    },
     ajaxStop: function() { $body.removeClass("loading"); }    
});

That's it! We're attaching some events to the body element anytime the ajaxStart or ajaxStop events are fired. When an ajax event starts, we add the "loading" class to the body. and when events are done, we remove the "loading" class from the body.

See it in action: http://jsfiddle.net/VpDUG/4952/

Community
  • 1
  • 1
Sampson
  • 265,109
  • 74
  • 539
  • 565
  • 9
    This is the most in depth solution although I'd recommend you use a centering plugin which centers the preloader around a page element (*i.e. body, #element, or .element*) – Corey Ballou Dec 27 '09 at 01:46
  • 2
    That would be a nice addition, cballou. I was merely trying to keep the information minimized - but as you point out, it certainly can be improved upon. – Sampson Dec 27 '09 at 02:02
  • Instead of using an additional div, it's also worth noting you can just make a class for one of the elements that is near the location you want to display the image, and use the same technique, sans an extra div. – Sneakyness Dec 27 '09 at 03:44
  • Nice, I've been using this solution and some minor js fixes to get it going smoothly. You can do something when AJAX post back ends using on body load function load()`Sys.WebForms.PageRequestManager.getInstance().add_endRequest(yourFunctionHere())`. You can use this to call `hideLoading()` – Junior Mayhé Nov 01 '10 at 23:26
  • I don't really know why does this not work with Google Chrome? It works perfectly with firefox. – simplfuzz Jun 14 '12 at 05:51
  • @dharm0us It works for me in Chrome. What version are you using? Any errors in the console output? – Sampson Jun 14 '12 at 06:36
  • @JonathanSampson I get this warning in my console : event.layerX and event.layerY are broken and deprecated in WebKit. They will be removed from the engine in the near future. Version : 19.0.1084.56 m. To be more precise, I see the loading screen only after completion of request, whereas in firefox I see the loading screen as soon as I send the request. – simplfuzz Jun 14 '12 at 10:15
  • @dharm0us Seems unrelated to the code above. This appears to be an issue with earlier versions of jQuery. See [this question](http://stackoverflow.com/questions/7825448/webkit-issues-with-event-layerx-and-event-layery), as well as the first item beneath [Removed Features](http://blog.jquery.com/2011/11/03/jquery-1-7-released/) on the jQuery blog for 1.7. – Sampson Jun 14 '12 at 15:09
  • 9
    I had to use .bind() instead of .on() as we are using jQuery 1.5.1! – renegadeMind Jul 10 '12 at 15:09
  • This doesn't work in case the jQuery AJAX events fire before the document is ready. Use this instead: $(document).on({ ajaxStart: function() { $(function() { $("#loading").show(); }) }, ajaxStop: function() { $(function() { $("#loading").hide(); }) } }); – Le Duc Duy Sep 12 '12 at 10:50
  • 45
    I'd recommend using the plugin that plugins to the plugins to make sure they're all plugged in. – contactmatt Sep 12 '12 at 21:25
  • 15
    **Note:** *As of jQuery 1.8, the `.ajaxStop()` and `.ajaxStart()` method should only be attached to document.* [docs](http://api.jquery.com/ajaxStop/) – balexandre Nov 21 '13 at 08:42
  • Great explanation. The only thing I don't like is how all the elements on your page "shift" to the right when the scrollbar is removed. As a user I would think that there was a bug. It's as if you would withdraw money from an ATM machine and suddenly after you press OK the keypad moves itself an inch. @JonathanSampson what is the reason behind the removal of the scrollbar? – PussInBoots Jan 06 '14 at 13:20
  • confused: your spinner div has class 'modal' but you attribute all the action to a class called 'loading'. You only connect the two through a css that says body.loading .modal. Does this mean that this css block somehow activates the modal class when the .loading class is active? Where does the .modal class get activated? thank you – slashdottir Mar 22 '14 at 16:24
  • @slashdottir You'll notice that initially `.modal` is `display: none`, meaning it's not visible. When it exists *within* a `.loading`, we switch its `display` property to `block`, making it visible. So we toggle the visibility of the modal by adding and removing the `.loading` class anywhere above it (such as on the `` element). – Sampson Mar 23 '14 at 01:43
  • When use Bootstrap and modal elements, need change the spinner class name "modal" by other name (Ej. modalLoading) because Bootstrapt have a class with the same name and modal elements don't show properly. I think changing z-index of "modal" can solve this, without change the name class. Very good script... congratulations. – Alex Abreu Mulet Jul 30 '15 at 21:17
  • 1
    My Implementation, your able to choose the div, `function showLoading(divId, name) {if ($("." + name + "_loading").length) {$("." + name +"_loading").css({ display: "block"});}else {$("
    ").css({position: "absolute",display: "block",width: "100%",height: "100%",top: 0,left: 0,background: "rgba( 255, 255, 255, .8 ) url('http://i.stack.imgur.com/FhHRx.gif') 50% 50% no-repeat","z-index": 10000}).appendTo($(divId).css("position", "relative"));}} function hideLoading(divId, name) {$("." + name + "_loading").css({display: "none"});}`
    – delmalki Aug 27 '15 at 23:00
  • Just wanted to add my experience to this thread. I don't deal with ajax on my particular page, but form submissions. This isn't my preferred solution, but what I'm stuck with at the moment. Because of this, IE halts the animation if the image is pre-loaded (as in your solution). To work around this, I use jquery to inject an with the spinner as the source. After some CSS work, you get the same visual effects as your solution, but it also works in IE with form submissions. – Anthony May 30 '17 at 13:12
  • 2
    http://ajaxload.info is not available. What will be the next best source? – Al Martins Jan 13 '22 at 21:37
  • One major annoyance is that if there's a runtime error in your ajax callback the ajaxStop event never happens – Matthew Lock Jun 26 '22 at 07:24
222

As far as the actual loading image, check out this site for a bunch of options.

As far as displaying a DIV with this image when a request begins, you have a few choices:

A) Manually show and hide the image:

$('#form').submit(function() {
    $('#wait').show();
    $.post('/whatever.php', function() {
        $('#wait').hide();
    });
    return false;
});

B) Use ajaxStart and ajaxComplete:

$('#wait').ajaxStart(function() {
    $(this).show();
}).ajaxComplete(function() {
    $(this).hide();
});

Using this the element will show/hide for any request. Could be good or bad, depending on the need.

C) Use individual callbacks for a particular request:

$('#form').submit(function() {
    $.ajax({
        url: '/whatever.php',
        beforeSend: function() { $('#wait').show(); },
        complete: function() { $('#wait').hide(); }
    });
    return false;
});
Paolo Bergantino
  • 480,997
  • 81
  • 517
  • 436
  • 4
    Something to note: if you cant modify the HTML to add the loading img element, you can do it as a background-image on the button using CSS e.g. input.loading-gif{background:url('images/loading.gif');} and then apply the class with jQuery e.g. $('#mybutton').addClass('loading-gif'); The only gotcha is that this will only request the gif when the submit button is clicked, which is normally too late, so you need to pre-cache it, which is easy with jQuery e.g. (new Image()).src = "images/loading.gif"; – jackocnr Feb 23 '11 at 16:27
  • 4
    This site has a larger and in my opinion nicer selection of loaders with more customization options http://www.preloaders.net/ – rorypicko Dec 22 '13 at 19:35
  • FYI: merged from http://stackoverflow.com/questions/750358/with-jquery-how-can-i-implement-a-page-loading-animation – Shog9 Jul 25 '14 at 19:55
  • Nice solution, but when i call [show() after hide() it's not working](https://stackoverflow.com/a/24841590/7786739). I found a solution that is switch show() and hide() to toggle(). Hoping it can help someone have same problem as my. Also, I tried solution C) and founded beforeSend not working in async. So, I suggested to call show() above $.ajax to work correctly. – 劉鎮瑲 Aug 16 '19 at 05:54
  • Thank you very much @Paolo. Personally, I liked your answer than the one accepted by most of the users. Hence, +1 to you from my side. – Ashok kumar Apr 23 '20 at 11:59
121

Along with what Jonathan and Samir suggested (both excellent answers btw!), jQuery has some built in events that it'll fire for you when making an ajax request.

There's the ajaxStart event

Show a loading message whenever an AJAX request starts (and none is already active).

...and it's brother, the ajaxStop event

Attach a function to be executed whenever all AJAX requests have ended. This is an Ajax Event.

Together, they make a fine way to show a progress message when any ajax activity is happening anywhere on the page.

HTML:

<div id="loading">
  <p><img src="loading.gif" /> Please Wait</p>
</div>

Script:

$(document).ajaxStart(function(){
    $('#loading').show();
 }).ajaxStop(function(){
    $('#loading').hide();
 });
Dan F
  • 11,958
  • 3
  • 48
  • 72
  • This is outdated, as of 1.8.0, `.ajaxStart` can only be attached to document, ie. `$(document).ajaxStart(function(){}).` – Jonno_FTW Apr 14 '14 at 03:10
  • 2
    @Jonno_FTW fixed. Ta. Old question and answer that's been superceded by Jonathan Sampson's edits to his question, but good to keep it up to date anyway – Dan F Apr 15 '14 at 22:06
  • 3
    Jonathan's answer was very in-dept, but this for me was the best for its simplicity. – Ojonugwa Jude Ochalifu May 13 '14 at 08:01
20

You can grab an animated GIF of a spinning circle from Ajaxload - stick that somewhere in your website file heirarchy. Then you just need to add an HTML element with the correct code, and remove it when you're done. This is fairly simple:

function showLoadingImage() {
    $('#yourParentElement').append('<div id="loading-image"><img src="path/to/loading.gif" alt="Loading..." /></div>');
}

function hideLoadingImage() {
    $('#loading-image').remove();
}

You then just need to use these methods in your AJAX call:

$.load(
     'http://example.com/myurl',
     { 'random': 'data': 1: 2, 'dwarfs': 7},
     function (responseText, textStatus, XMLHttpRequest) {
         hideLoadingImage();
     }
);

// this will be run immediately after the AJAX call has been made,
// not when it completes.
showLoadingImage();

This has a few caveats: first of all, if you have two or more places the loading image can be shown, you're going to need to kep track of how many calls are running at once somehow, and only hide when they're all done. This can be done using a simple counter, which should work for almost all cases.

Secondly, this will only hide the loading image on a successful AJAX call. To handle the error states, you'll need to look into $.ajax, which is more complex than $.load, $.get and the like, but a lot more flexible too.

Samir Talwar
  • 14,220
  • 3
  • 41
  • 65
  • 2
    Thanks for the reply. But tell me, why do I need to use AJAX at all? Can't I simply track down it all in the page itself? – thedp Dec 27 '09 at 23:18
  • What exactly do you want to track? Unless you're requesting information after the page has loaded (and AJAX is pretty much the only way to do that without using a plugin), why would you need a "loading" image at all? – Samir Talwar Dec 28 '09 at 02:39
  • Samir Talwar: A heavy JavaScript application actually. Thanks, I get the idea. – thedp Dec 28 '09 at 06:09
  • Understandable. In that case, just call `showLoadingImage` before you start and `hideLoadingImage` after you finish. Should be fairly simple. You may need to stick some sort of `setTimeout` call in to make sure the browser actually renders the new `` tag though - I've seen a couple of cases where it doesn't bother until the JavaScript has finished executing. – Samir Talwar Dec 28 '09 at 15:38
17

Jonathon's excellent solution breaks in IE8 (the animation does not show at all). To fix this, change the CSS to:

.modal {
display:    none;
position:   fixed;
z-index:    1000;
top:        0;
left:       0;
height:     100%;
width:      100%;
background: rgba( 255, 255, 255, .8 ) 
            url('https://i.stack.imgur.com/FhHRx.gif') 
            50% 50% 
            no-repeat;
opacity: 0.80;
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity = 80);
filter: alpha(opacity = 80)};
Maurice Flanagan
  • 5,179
  • 3
  • 30
  • 37
Ben Power
  • 1,786
  • 5
  • 27
  • 35
8

SVG animations are probably a better solution to this problem. You won't need to worry about writing CSS and compared to GIFs, you'll get better resolution and alpha transparency. Some very good SVG loading animations that you can use are here: http://samherbert.net/svg-loaders/

You can also use those animations directly through a service I built: https://svgbox.net/iconset/loaders. It allows you to customize the fill and direct usage (hotlinking) is permitted.

To accomplish what you want to do with jQuery, you probably should have a loading info element hidden and use .show() when you want to show the loader. For eg, this code shows the loader after one second:

setTimeout(function() {
  $("#load").show();
}, 1000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>

<div id="load" style="display:none">
    Please wait... 
    <img src="//s.svgbox.net/loaders.svg?fill=maroon&ic=tail-spin" 
         style="width:24px">
</div>
Shubham
  • 21,300
  • 18
  • 66
  • 89
7

If you are using Turbolinks With Rails this is my solution:

This is the CoffeeScript

$(window).on 'page:fetch', ->
  $('body').append("<div class='modal'></div>")
  $('body').addClass("loading")

$(window).on 'page:change', ->
  $('body').removeClass("loading")

This is the SASS CSS based on the first excellent answer from Jonathan Sampson

# loader.css.scss

.modal {
    display:    none;
    position:   fixed;
    z-index:    1000;
    top:        0;
    left:       0;
    height:     100%;
    width:      100%;
    background: rgba( 255, 255, 255, 0.4)
            asset-url('ajax-loader.gif', image)
            50% 50% 
            no-repeat;
}
body.loading {
    overflow: hidden;   
}

body.loading .modal {
    display: block;
}
Chris Edwards
  • 3,514
  • 2
  • 33
  • 40
Fred
  • 356
  • 1
  • 4
  • 4
7

jQuery provides event hooks for when AJAX requests start and end. You can hook into these to show your loader.

For example, create the following div:

<div id="spinner">
  <img src="images/spinner.gif" alt="Loading" />
</div>

Set it to display: none in your stylesheets. You can style it whatever way you want to. You can generate a nice loading image at Ajaxload.info, if you want to.

Then, you can use something like the following to make it be shown automatically when sending Ajax requests:

$(document).ready(function () {

    $('#spinner').bind("ajaxSend", function() {
        $(this).show();
    }).bind("ajaxComplete", function() {
        $(this).hide();
    });

});

Simply add this Javascript block to the end of your page before closing your body tag or wherever you see fit.

Now, whenever you send Ajax requests, the #spinner div will be shown. When the request is complete, it'll be hidden again.

Veeti
  • 5,270
  • 3
  • 31
  • 37
  • Can someone please explain what AJAX has to do with this? Can't I simply manage this all within the page without accessing the server with AJAX... Or am I missing here something? Thanks. – thedp Dec 27 '09 at 23:24
  • 4
    Ah - as I understood, you wanted a loading image to be shown whenever you were making AJAX requests. If you simply want a "please wait, loading..." animation to be shown until the page has fully loaded, you could have a loading div in the page and then hide it in your $(document).ready block. – Veeti Dec 27 '09 at 23:33
7

With all due respect to other posts, you have here a very simple solution, using CSS3 and jQuery, without using any further external resources nor files.

$('#submit').click(function(){
  $(this).addClass('button_loader').attr("value","");
  window.setTimeout(function(){
    $('#submit').removeClass('button_loader').attr("value","\u2713");
    $('#submit').prop('disabled', true);
  }, 3000);
});
#submit:focus{
  outline:none;
  outline-offset: none;
}

.button {
    display: inline-block;
    padding: 6px 12px;
    margin: 20px 8px;
    font-size: 14px;
    font-weight: 400;
    line-height: 1.42857143;
    text-align: center;
    white-space: nowrap;
    vertical-align: middle;
    -ms-touch-action: manipulation;
    cursor: pointer;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    background-image: none;
    border: 2px solid transparent;
    border-radius: 5px;
    color: #000;
    background-color: #b2b2b2;
    border-color: #969696;
}

.button_loader {
  background-color: transparent;
  border: 4px solid #f3f3f3;
  border-radius: 50%;
  border-top: 4px solid #969696;
  border-bottom: 4px solid #969696;
  width: 35px;
  height: 35px;
  -webkit-animation: spin 0.8s linear infinite;
  animation: spin 0.8s linear infinite;
}

@-webkit-keyframes spin {
  0% { -webkit-transform: rotate(0deg); }
  99% { -webkit-transform: rotate(360deg); }
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  99% { transform: rotate(360deg); }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="submit" class="button" type="submit" value="Submit" />
João Pimentel Ferreira
  • 14,289
  • 10
  • 80
  • 109
6

Like Mark H said the blockUI is the way.

Ex.:

<script type="text/javascript" src="javascript/jquery/jquery.blockUI.js"></script>
<script>
// unblock when ajax activity stops
$(document).ajaxStop($.unblockUI); 

$("#downloadButton").click(function() {

    $("#dialog").dialog({
        width:"390px",
        modal:true,
        buttons: {
            "OK, AGUARDO O E-MAIL!":  function() {
                $.blockUI({ message: '<img src="img/ajax-loader.gif" />' });
                send();
            }
        }
    });
});

function send() {
    $.ajax({
        url: "download-enviar.do",          
        type: "POST",
        blablabla
    });
}
</script>

Obs.: I got the ajax-loader.gif on http://www.ajaxload.info/

bpedroso
  • 4,617
  • 3
  • 29
  • 34
  • FYI: merged from http://stackoverflow.com/questions/750358/with-jquery-how-can-i-implement-a-page-loading-animation – Shog9 Jul 25 '14 at 19:55
5

Most of the solutions I have seen either expects us to design a loading overlay, keep it hidden and then unhide it when required, or, show a gif or image etc.

I wanted to develop a robust plugin, where with a simply jQuery call I can display the loading screen and tear it down when the task is completed.

Below is the code. It depends on Font awesome and jQuery:

/**
 * Raj: Used basic sources from here: http://jsfiddle.net/eys3d/741/
 **/


(function($){
    // Retain count concept: http://stackoverflow.com/a/2420247/260665
    // Callers should make sure that for every invocation of loadingSpinner method there has to be an equivalent invocation of removeLoadingSpinner
    var retainCount = 0;

    // http://stackoverflow.com/a/13992290/260665 difference between $.fn.extend and $.extend
    $.extend({
        loadingSpinner: function() {
            // add the overlay with loading image to the page
            var over = '<div id="custom-loading-overlay">' +
                '<i id="custom-loading" class="fa fa-spinner fa-spin fa-3x fa-fw" style="font-size:48px; color: #470A68;"></i>'+
                '</div>';
            if (0===retainCount) {
                $(over).appendTo('body');
            }
            retainCount++;
        },
        removeLoadingSpinner: function() {
            retainCount--;
            if (retainCount<=0) {
                $('#custom-loading-overlay').remove();
                retainCount = 0;
            }
        }
    });
}(jQuery)); 

Just put the above in a js file and include it throughout the project.

CSS addition:

#custom-loading-overlay {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    right: 0;
    background: #000;
    opacity: 0.8;
    filter: alpha(opacity=80);
}
#custom-loading {
    width: 50px;
    height: 57px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin: -28px 0 0 -25px;
}

Invocation:

$.loadingSpinner();
$.removeLoadingSpinner();
Raj Pawan Gumdal
  • 7,390
  • 10
  • 60
  • 92
5

This would make the buttons disappear, then an animation of "loading" would appear in their place and finally just display a success message.

$(function(){
    $('#submit').click(function(){
        $('#submit').hide();
        $("#form .buttons").append('<img src="assets/img/loading.gif" alt="Loading..." id="loading" />');
        $.post("sendmail.php",
                {emailFrom: nameVal, subject: subjectVal, message: messageVal},
                function(data){
                    jQuery("#form").slideUp("normal", function() {                 
                        $("#form").before('<h1>Success</h1><p>Your email was sent.</p>');
                    });
                }
        );
    });
});
VansFannel
  • 45,055
  • 107
  • 359
  • 626
Tsundoku
  • 9,104
  • 29
  • 93
  • 127
  • FYI: merged from http://stackoverflow.com/questions/750358/with-jquery-how-can-i-implement-a-page-loading-animation – Shog9 Jul 25 '14 at 19:55
3

Note that when using ASP.Net MVC, with using (Ajax.BeginForm(..., setting the ajaxStart will not work.

Use the AjaxOptions to overcome this issue:

(Ajax.BeginForm("ActionName", new AjaxOptions { OnBegin = "uiOfProccessingAjaxAction", OnComplete = "uiOfProccessingAjaxActionComplete" }))
phuzi
  • 12,078
  • 3
  • 26
  • 50
Rami Weiss
  • 39
  • 1
  • FYI: merged from http://stackoverflow.com/questions/750358/with-jquery-how-can-i-implement-a-page-loading-animation – Shog9 Jul 25 '14 at 19:55
2

I use CSS3 for animation

/************ CSS3 *************/
.icon-spin {
  font-size: 1.5em;
  display: inline-block;
  animation: spin1 2s infinite linear;
}

@keyframes spin1{
    0%{transform:rotate(0deg)}
    100%{transform:rotate(359deg)}
}

/************** CSS3 cross-platform ******************/

.icon-spin-cross-platform {
  font-size: 1.5em;
  display: inline-block;
  -moz-animation: spin 2s infinite linear;
  -o-animation: spin 2s infinite linear;
  -webkit-animation: spin 2s infinite linear;
  animation: spin2 2s infinite linear;
}

@keyframes spin2{
    0%{transform:rotate(0deg)}
    100%{transform:rotate(359deg)}
}
@-moz-keyframes spin2{
    0%{-moz-transform:rotate(0deg)}
    100%{-moz-transform:rotate(359deg)}
}
@-webkit-keyframes spin2{
    0%{-webkit-transform:rotate(0deg)}
    100%{-webkit-transform:rotate(359deg)}
}
@-o-keyframes spin2{
    0%{-o-transform:rotate(0deg)}
    100%{-o-transform:rotate(359deg)}
}
@-ms-keyframes spin2{
    0%{-ms-transform:rotate(0deg)}
    100%{-ms-transform:rotate(359deg)}
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>


<div class="row">
  <div class="col-md-6">
    Default CSS3
    <span class="glyphicon glyphicon-repeat icon-spin"></span>
  </div>
  <div class="col-md-6">
    Cross-Platform CSS3
    <span class="glyphicon glyphicon-repeat icon-spin-cross-platform"></span>
  </div>
</div>
Camille
  • 2,439
  • 1
  • 14
  • 32
2

Per https://www.w3schools.com/howto/howto_css_loader.asp, this is a 2-step process with no JS:

1.Add this HTML where you want the spinner: <div class="loader"></div>

2.Add this CSS to make the actual spinner:

.loader {
    border: 16px solid #f3f3f3; /* Light grey */
    border-top: 16px solid #3498db; /* Blue */
    border-radius: 50%;
    width: 120px;
    height: 120px;
    animation: spin 2s linear infinite;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}
hamx0r
  • 4,081
  • 1
  • 33
  • 46
  • Since the OP is using jQuery they can call `$("#loader").toggle();` before making the long running request to start the animation and make another call in the callback function of the request to hide it away. – Dima Chubarov Apr 13 '18 at 07:51
1

Fontawesome has a loading animation icon which can be used directly in your project without any extra data burden if you are already using font awesome.

<span id="loading" style="display:none"><i class="fa fa-spinner fa-pulse"></i> PLEASE WAIT </span>

Then is jquery you can use following code to show hide the element.

$(document).ajaxSend(function() {
    $('#loading').show();
});

$(document).ajaxComplete(function() {  
    $('#loading').hide();
});

$('button').click(function(){
    $('#loading').toggle();
});
<script src="https://code.jquery.com/jquery-3.6.4.slim.min.js" integrity="sha256-a2yjHM4jnF9f54xUQakjZGaqYs/V1CYvWpoqZzC2/Bw=" crossorigin="anonymous"></script>

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
<body>
<div class="m-5"> <span id="loading" style="display:none"><i class="fa fa-spinner fa-pulse"></i> PLEASE WAIT </span> </div> 
<button class="btn btn-primary"> Click me to start or stop Ajax </button>
</body>
Prakhar Gyawali
  • 527
  • 4
  • 18
  • This answer could do with a code demonstration of what it looks like when spinning. – Hashim Aziz Mar 01 '22 at 23:00
  • the only thing this answer brings to the table is using a different asset for the spinner. – Kevin B Apr 07 '23 at 20:44
  • if you see other answers where user have to use lots of div, external gif, and many more css, then it is a lot more easier and faster and also light on memory. the code bring performance improvement and less code to the table as well – Prakhar Gyawali Apr 07 '23 at 20:49
0

Place this code on your body tag

<div class="loader">
<div class="loader-centered">
    <div class="object square-one"></div>
    <div class="object square-two"></div>
    <div class="object square-three"></div>
</div>
</div>
<div class="container">
<div class="jumbotron">
    <h1 id="loading-text">Loading...</h1>
</div>
</div>

And use this jquery script

<script type="text/javascript">

jQuery(window).load(function() {
//$(".loader-centered").fadeOut();
//in production change 5000 to 400
$(".loader").delay(5000).fadeOut("slow");
$("#loading-text").addClass('text-success').html('page loaded');
});
</script>

See a full example working here.

http://bootdey.com/snippets/view/page-loader

Dey
  • 842
  • 9
  • 21
0

I have also found such a problem (challenge) to inform the user about some "info" during the DB response.

My solution is probably a little different than presented here, is it good or bad? I do not know, it was enough for me.

$.ajax({ 
    type: 'ajax',
    method: 'post',
    url: '<?php echo base_url()?>skargi/osluga_skarg',
    data: { full_date: full_date, head_title: head_title },
    //async: false,             
    dataType: 'json',
    beforeSend: function() { $body.addClass("loading"); },
    success: function(data) {   
        $body.removeClass("loading");
biberman
  • 5,606
  • 4
  • 11
  • 35
0

HTML

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js"></script>
<button type="button" id="btn-submit" class="btn btn-info">Submit</button>

  <div class="modal fade" id="loadingModal" tabindex="-1" role="dialog" aria-labelledby="loader" aria-hidden="true" data-keyboard="false" data-backdrop="static">
    <div class="modal-dialog" style="width:50px;padding-top: 15%;">
      <div class="modal-content text-center">
        <img src="https://i.gifer.com/ZZ5H.gif" />    
      </div>
    </div>
  </div>

jQuery

$(function() {
      $('#btn-submit').click(function() {
        $('#loadingModal').modal('show');
      });
    });
Josh Chang
  • 45
  • 2
  • 11
-1

It is very simple.

HTML

<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">

<body>

  <div id="cover"> <span class="glyphicon glyphicon-refresh w3-spin preloader-Icon"></span>Please Wait, Loading…</div>

  <h1>Dom Loaded</h1>
</body>

CSS

#cover {
  position: fixed;
  height: 100%;
  width: 100%;
  top: 0;
  left: 0;
  background: #141526;
  z-index: 9999;
  font-size: 65px;
  text-align: center;
  padding-top: 200px;
  color: #fff;
  font-family:tahoma;
}

JS - JQuery

$(window).on('load', function () {
  $("#cover").fadeOut(1750);
});
thedp
  • 8,350
  • 16
  • 53
  • 95
Skitty
  • 1,709
  • 18
  • 21