Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
486 views
in Technique[技术] by (71.8m points)

javascript - jQuery hide() and show() not immediately run when reversed later in the function

I'm using jQuery's .hide() and .show() functions to show a loading message while a potentially long synchronous webservice call executes.

When clicking the button in the below snippet, I would expect the text "Some data" to be immediately replaced with "Loading..." and then go back to "Some other data" after 5 seconds.

As you can see, that is not what happens:

function run_test() {
    $('#test1').hide();
    $('#test2').show();
    
    long_synchronous_function_call()
    
    $('#test2').hide();
    $('#test1').show();
}

function long_synchronous_function_call() {
    $('#test1').html('<p>Some other data</p>');
    var date = new Date();
while ((new Date()) - date <= 5000) {}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<div id="test1">
    <p>Some data</p>
</div>

<div id="test2" style="display:none">
    <p>Loading...</p>
</div>

<button onclick="run_test()">Call a long synchronous function!</button>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The screen won't be rendered until your code stops execution. This is almost always the desired behavior, as it prevents the rendering of the DOM in an inconsistent state.

Supposing you really need to run a long synchronous task, and you can fix that or defer it to a webworker, then a solution is to use setTimeout:

function run_test() {
    $('#test1').hide();
    $('#test2').show();
    
    setTimeout(function(){
       long_synchronous_function_call()
    
       $('#test2').hide();
       $('#test1').show();
    },0);
}

function long_synchronous_function_call() {
    $('#test1').html('<p>Some other data</p>');
    var date = new Date();
while ((new Date()) - date <= 5000) {}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<div id="test1">
    <p>Some data</p>
</div>

<div id="test2" style="display:none">
    <p>Loading...</p>
</div>

<button onclick="run_test()">Call a long synchronous function!</button>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...