0

I have a function that takes a little while to run, so I'm trying to set the display value of a div (that basically says "please wait") to "block" at the start of the function and then to "none" when the function is complete to alert the user that the function is running.

The display setting is being set properly and I can see the changes in the console log; however, I cannot get it to redraw until after the function is complete. After hours of scouring forum answers to similar questions, it seems like my best option is to call window.getComputedStyle or element.offsetHeight, but these don't seem to be working.

Here is my code:

function renumber(){
    notif = document.getElementByID("notification");  //this is my div
    notif.style.display = "block";
    window.getComputedStyle(notif, null).height; //I've tried this as well as...
    notif.offsetHeight;  //trying this seperately

    /////////big loop that takes a long time to run/////////

    notif.style.display = "none";
}

I have also tried setting the CSS instead, and then using window.getComputedStyle and element.offsetHeight:

doc = document.styleSheets[6].cssRules[0].style;
disp = doc.setProperty('display','block');
window.getComputedStyle(notif, null).height; //I've tried this as well as...
notif.offsetHeight;  //trying this seperately

And, I have even tried abandoning my notification div and using setTimeout() and alert(), but even that doesn't display until the function is complete (it doesn't matter how much time I put in):

function renumber(){
    setTimeout(function() { alert("my message"); }, 50);

    ////big loop that takes a long time to run////
}

So with all of that, my question is why is window.getComputedStyle and element.offsetHeight not redrawing and making my div display the way the values are set within the function? Everything I've seen online sounds like simply calling one of those should force a redraw, so I'm confused why I'm not seeing a redraw. Is there a better way I should be doing this?

Ryan
  • 23
  • 4

1 Answers1

0

Would tell problem is JS is single threaded, you block UI by your slow operation.

Do not know if there is a process events signal to UI common in frameworks like Qt, etc., but setTimeout can help here (may not work perfect here in snippet, slow part takes around 6s in my Chrome):

function renumber(){
    notif = document.getElementById("notification");  //this is my div
    notif.style.display = "block";

    setTimeout(long, 0, notif);
}
renumber();
function long(notif) {
    console.log("Long starts", new Date());
    for(var a=0;a<1000000000;a++) if(a % 10) a++; else a += 0.1;
    console.log("Long end", new Date());
    notif.style.display = "none";
}
<div id="notification" style="display: none;">
    Wait please !
</div>
Jan
  • 2,178
  • 3
  • 14
  • 26
  • 2 explanations nice video https://www.youtube.com/watch?v=8aGhZQkoFbQ and some long description here https://stackoverflow.com/questions/779379/why-is-settimeoutfn-0-sometimes-useful – Jan Apr 15 '20 at 17:59