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,740
  • 10
  • 42
  • 76

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
  • 372,613
  • 87
  • 782
  • 758
2

Mandatory jQuery answer:

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

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

Example: jsFiddle

technophobia
  • 2,644
  • 1
  • 20
  • 29