1

I have a function showLoading() that shows a spinner by appending a class:

function showLoading(){
    //console.log("show loading");
    loading = true;
    $("body").addClass("loading");
}

I call it like this:

Function heavyCrunch(){
    showLoading();

    <heavy crunching>

    hideLoading();
}

Now whenever I call the function just before some heavy load which takes > 1 second, it should show the spinner immediately, but it does not. In fact, it doesn't show at all. Whenever I click a button that triggers the heavyCrunch() function, it just freezes for a second or 2 and then immediately show the result. The spinner never shows. Why does this happen?

Should I call the function in an .after callback or something?

Gooey
  • 4,620
  • 10
  • 41
  • 74

2 Answers2

5

The DOM isn't refreshed while your code is executing. It waits until the end.

If you want the change to be visible, you have to defer the execution:

function heavyCrunch(){
    showLoading();
    setTimeout(function(){

        <heavy crunching>

        hideLoading();
    }, 0);
}

Note that in some cases of heavy processing you might want to release the pressure on the browser and let it the time to really draw. In such a case you may use a timeout greater than 0.

Denys Séguret
  • 355,860
  • 83
  • 755
  • 726
2

Mandatory jQuery answer:

$.when(showLoading()).done(function () {
    heavyCrunch();
});

Ref: https://api.jquery.com/jquery.when/

Example: jsFiddle

technophobia
  • 2,586
  • 1
  • 19
  • 29