“This is the second day of my participation in the Gwen Challenge.

SetInterval is every n milliseconds; SetTimeOut sets the movement of small blocks, starting at the left, moving 10px to the right every 100 milliseconds, and finally moving 500px away from the start. SetInterval

var oDemo = document.getElementsByClassName('demo') [0];
var timer = setInterval(move, 100);
function move(){
    var l = oDemo.offsetLeft;
    if (l < 500){
        oDemo.style.left = l + 10 + 'px';
    }else {
        oDemo.style.left = '500px'; }}Copy the code

With setTimeOut:

var oDemo = document.getElementsByClassName('demo') [0];
var time2;
function move(){
    var l = oDemo.offsetLeft;
    if (l < 500){
        oDemo.style.left = l + 10 + 'px';
        setTimeout(move, 100);
    }else {
        oDemo.style.left = '500px';
    }
    
}
move();
Copy the code

The effect is consistent

The problems of timer animation are as follows: 1. When the current window no longer animates the page, the timer will continue to work. For example, when an animation is made, the user has already looked at other pages before the animation is finished, the animation will still continue, wasting CPU

For example, the above move function takes 200 milliseconds to execute. Set the move function to execute every 100 milliseconds. Before a move function is completed, another request has been sent, and the queuing situation occurs. If the previous move is completed, the next move can be executed. Too many lines can also cause browsers to crash

3. Set animation frequency high, excessive drawing, frame drop

The automatic refresh rate of the browser screen is about 16.7ms per second, 60 times per second, depending on device performance and CPU load

As the browser refreshed and the page was redrawn, we saw the animation

If the timer frequency is higher than the browser refresh frequency, even if the code is executed, the browser does not refresh, it is not displayed, and frames drop, not smooth

Here’s an example:

For example, if the square was originally on the far left, left was 0, set the timer to refresh every 10ms, the square moved forward 10px to the right, and the browser refreshed every 16.7ms

1. When the timer starts to work, at 0ms, the small box is displayed at 0 position,

2. At 10ms, the small square should be 10px, but the browser did not refresh, the small square is still 0;

3. At 16.7ms, the browser refreshed, and the small box was displayed at 10px, moving from 0 to 10px;

4. At 20ms, the small box should have been 20px, but the browser did not refresh, and the small box was displayed at 10px;

5. At 30ms, the small square should be at 30, but the browser did not refresh, and the small square was at 10px;

6. At 16.7*2ms, the browser refreshed and the box moved from 10px to 30px, skipping 20px and dropping frames



Originally set by timer, the black font 123 will display a small square

But because the browser doesn’t refresh as often, only the red 12 position is displayed

The timer is executed one more time and is not displayed

Html5 provides a requestAnimationFrame to solve this problem

RequestAnimationFrame advantage:

1. Stop working when the current window is not on the animation page

2. The interval is automatically executed when the browser refreshes the screen

3. The method is optimized internally in the browser and the timer is not optimized

SetTimeOut is the same as setTimeOut, but this n milliseconds, automatically set to the browser refresh frequency, the browser refresh once, do not need to manually set; The browser doesn’t refresh, it doesn’t execute, there’s no queuing to drop frames

RequestAnimationFrame use:

1.req = requestAnimationFrame(cb); The callback function cb is executed each time the screen is drawn

2.cancelAnimationFrame(req);

<div class="demo"></div>
<button id="stop">stop</button>
<script>
    var oDemo = document.getElementsByClassName('demo') [0],
        oStop = document.getElementById('stop');
    var req;
    function move(){
        var l = oDemo.offsetLeft;
        if (l < 1000){
            oDemo.style.left = l + 5 + 'px';
            req = requestAnimationFrame(move);// Execute next time when the page refreshes
        }else {
            oDemo.style.left = '1000px';
        }
        
    }
    move();
    oStop.onclick = function(){
        cancelAnimationFrame(req);
    }// Clear req when clicked
</script>
Copy the code



Some browsers are not compatible with requestAnimationFrame.

window.requestAnimationFrame = (function (callbask) {
    return window.requestAnimationFrame ||
        window.WebKitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function () {
            window.setTimeout(callback, 1000 / 60)}}) ();// Execute immediately
Copy the code

If no browser supports it, use setTimeOut

The corresponding clear timer is written compatibility:

window.cancelAnimationFrame = (function (timer) {
    return window.cancelAnimationFrame ||
        window.WebKitCancelAnimationFrame ||
        window.mozCancelAnimationFrame ||
        window.oCancelAnimationFrame ||
        window.msCancelAnimationFrame ||
        function () {
            window.clearTimeout(timer)
        }
})();
Copy the code