Show message while javascript is running

2019-08-08 08:21发布

I know that most probably such question has been requested several times but I have a need to show a popup or message or whatelse when a javascript function is triggered and hide it at the end.

See this simple js fiddle

That's the HTML code:

<div id='message'>Default message</div>
<input type='button' onclick='Run();' value='start'>

the div 'message' has to contain a simple text like "running" or "please wait" or ...

That's the JS function that took (delay) 3 seconds:

function Run() {
    var delay = 3000;   //-- 3 seconds
    $( '#message' ).text('Please wait ' + delay + ' seconds...');
    var start = new Date().getTime();
    while (true) {
        current = new Date().getTime();
        if ( (start + delay) < current) {
            break;
        }
    }
    $( '#message' ).text('Done');
}

The expected behaviour is that the '#message' div contains "Please wait 3 seconds..." before to enter in the loop and "Done" string only at the end.

But that's not. Can anyone explain me (most probably "again") why or suggest a link where to find an answer?

4条回答
Bombasti
2楼-- · 2019-08-08 08:53

The browser's display is only updated when the function completely finishes running. You can run the second lot of code asynchronously by using setTimeout.

function Run() {

    $('#message').text('Please wait 3 seconds...');
    setTimeout(

    function () {
        var start = new Date().getTime();
        while (true) {

            current = new Date().getTime();
            if ((start + 3000) < current) {
                break;
            }
        }
        $('#message').text('Done');
    },0);
}
查看更多
叼着烟拽天下
3楼-- · 2019-08-08 09:10

Try this http://jsfiddle.net/aamir/23ZFY/11/

function Run() {
    var secs = 3;
    $('#message').text('Please wait '+ secs +' seconds...');
    var timer = setInterval(function () {
        if (secs == 1) {
            clearTimeout(timer);
            $('#message').text('Done');
            return;
        }
        secs--;
        $('#message').text('Please wait ' + secs + ' seconds...');
    }, 1000);
}
查看更多
做自己的国王
4楼-- · 2019-08-08 09:11

You have a very tight loop (while(true)...) which doesn't allow the UI to update at all. What you can do instead is this:

function Run() {
    var delay = 3000; //-- 3 seconds    
    $('#message').text('Please wait ' + (delay/1000) + ' seconds...');
    setTimeout(function () {
          $('#message').text('Done');       
    }, delay);
}

Basically, set the "wait message" initially and use the setTimeout function to update the message again after 3 seconds.

Updated fiddle.

查看更多
霸刀☆藐视天下
5楼-- · 2019-08-08 09:12

The JS event loop is too busy running while (true) {} to handle a DOM repaint.

Use setInterval, setTimeout, or requestAnimationFrame to trigger the next test of the time instead of a loop.

function Run() {
    var delay = 3000;   //-- 3 seconds
    $( '#message' ).text('Please wait ' + delay + ' seconds...');
    var start = new Date().getTime();
    setTimeout(whenDelayIsOver, 50);

    function whenDelayIsOver() {
        if ( (start + delay) < current) {
            $( '#message' ).text('Done');
        } else {
            setTimeout(whenDelayIsOver, 50);
        }
    }
}

… or just use setTimeout in the first place.

function Run() {
    var delay = 3000;   //-- 3 seconds
    $( '#message' ).text('Please wait ' + delay + ' seconds...');
    setTimeout(whenDelayIsOver, delay);

    function whenDelayIsOver() {
        $( '#message' ).text('Done');
    }
}
查看更多
登录 后发表回答