简体   繁体   中英

How can I continue to play my GIF during JavaScript processing (as it freezes)?

My GIF image freezes after 5 seconds while my JavaScript code is doing some work. It unfreezes when procesing is finished.

Is there a solution to animate my GIF while the code is executing?

Here's my JavaScript code:

var play = function() {
    var image = document.getElementById('img');
    image.style.display="block";

    window.setTimeout(function(){
        for ( var i =0; i < 2000000000; i++ )
        {
            //Do nothing, in example
        }
    }, 5000);
};

var stop = function() {
    var image = document.getElementById('img');
    image.style.display="none";
};

HTML code:

<img id="img" src="loader.gif" style="display: none;"/>
<button id="Start" onclick="play()">Play</button>
<button id="Stop" onclick="stop()">Stop</button>

I think that in this case you should use webworker elements . They allow you to do some asynchronous operation in the background of the UI elements.

One example

<p>Value passed by the worker: <output id="result"></output></p>
<script>
    var worker = new Worker('worker.js');

    worker.onmessage = function (event) {
        document.getElementById('result').textContent = event.data;
    };
</script>

In a separate file (worker.js):

var n = 1;
search: while (true) {
    n += 1;

    for (var i = 2; i <= Math.sqrt(n); i += 1)
        if (n % i == 0)
            continue search;

    // Found a prime!
    postMessage(n);
}

Every time that you call postMessage you send some data from the background (that fires onmessage event of the worker element ) to the main thread.

Have a look at Using jQuery UI progress bar with MVVM, Knockout and web workers for your case:

In this post I would like to explore:

  • How to use the jQuery UI progress bar with KnockoutJS and MVVM pattern, as a simple example of reusing existing JavaScript UI components.
  • How to use web workers to execute long running task asynchronously and notify view model about the results and progress.

Use yield as in this working example with minor mod's to your own code...

 var play = function() { //'-----------------------------------Insert Handler.. var obj = myfuncGen.next(); //'start it if (obj.done == false) { setTimeout(play, 150); //'adjust for the amount of time you wish to yield (depends how much screen drawing is required or etc) } } var myfuncGen = myfuncSurrogate(); //'creates a "Generator" out of next. function* myfuncSurrogate() { //'This the original function repackaged! Note asterisk. //'-------------------------------------End Insert var image = document.getElementById('img'); image.style.display="block"; //window.setTimeout(function(){ console.log("start"); for ( var i =0; i < 20000000; i++ ) { if ((i % 1000000) == 0) { //a yield set to go off every 1,000,000 loops (if the yield is called too often it will needlessly slowe down yor loop) console.log("yielding ", i / 1000000); yield; } } console.log("done"); //}, 500); }; play() 
 <img id='img' src='http://bestanimations.com/Earth&Space/Earth/earth-spinning-rotating-animation-52.gif' /> 

..I had to edit out window.setTimeout() as it created a detached function which causes an error with Yield. To restore your original intent, I would call play() from such a timeout.

If the link becomes broken to the random gif I chose, I am sure you could substitute another :-).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM