JavaScript function and UI updates

前端 未结 1 738
轮回少年
轮回少年 2021-01-21 07:48

I have a following function which slides a relatively positioned element 1000px off of where it is now.

for (var i = 0; i < 1000; i++) {
    $(\'.my-element\'         


        
相关标签:
1条回答
  • 2021-01-21 08:06

    This is probably the best way to think about it. The browser can do one of two things. Either it runs your javascript or it renders the webapge, it cannot do both.

    This is because javascript code is 100% blocking, meaning it will never give up control until the browser has executed all blocking code.

    You first example contains only blocking code so the browser is never given the opportunity to render until the element is already where it needs to be.

    Your second example contains blocking code that uses setTimeout (delayed blocking code) which queues a bunch of blocking code to be executed later (after all other blocking code has completed) at the browsers discretion (between its rending and javascript running cycles).

    So the second example the loop will completely execute, queuing 1000 functions to execute at some point in time but as close to 0ms as possible. Now that the blocking code has completed one or more setTimeout may execute or the browser may render, its pretty random what actually happens though. But it will weave back and forth between rendering and executing javascript.

    Take this code for example.

    setTimeout(function () { //this makes it so the page loads and sits for a second
        var delay = 100, //delay between animations
            distance = 25, //total distance moved
            sync = false; //should this use blocking code
    
        if (sync) {
            var i = 0,
                elapsed = 0,
                last = new Date();
            while (i < distance) {
                var now = new Date();
                elapsed += (now - last);
                last = now;
                if (elapsed >= delay) {
                    move(i++);
                    elapsed -= delay;
                }
            }
        } else {
            for (var i = 0; i < distance; i++) {
                assyncMove(i, delay * i);
            }
        }
    
        function assyncMove(position, delay) {
            setTimeout(function () {
                move(position);
            }, delay);
        }
    
        function move(position) {
            $("div").css("left", position);
        }
    }, 1000);
    

    You can change the delay, distance, and sync variables. Both loops wait to move the element delay milliseconds between each animation. They will both move a div a total of distance pixels. However one (setTimeout) will have a visible animation while the other will just shoot over. If you make the delay or distance too long for the sync method you will actually freeze the browser, the assync solution will not have that issue!

    http://jsfiddle.net/j79s4o4w/3/

    0 讨论(0)
提交回复
热议问题