2

これが私のページです。要素の移動をテストするデモですが、いつかページを変更してここに戻った後、DIVがより速く移動するのはなぜですか?

私のcss:

   #box1 {
        width: 900px;
        height: 50px;
        background-color: #000;
        position: relative;
    }

    #box2 {
        width: 50px;
        height: 50px;
        background-color: #a00;
        position: absolute;
    }

私のHTML:

<div id="box1">
    <div id="box2"></div>
</div>

私のJs:

var box2 = document.getElementById("box2");
    var remove = setInterval(function () {
        box2.style.left = "0px";
        var move = setInterval(function () {
            var newLeft = Math.min(parseInt(box2.style.left) + 5, 850) + "px";
            box2.style.left = newLeft;
            if (newLeft == "850px") clearInterval(move)
        }, 20);
    }, 5000)
4

3 に答える 3

6

のレートはsetInterval信頼できません。タブがフォーカスされていない場合、ブラウザはそれを起動しない可能性があり、また必要以上に頻繁に起動する可能性があります。

WindowTimers動作は、インターフェイスの現在のHTML5ドラフトで標準化されています(これは、そのように実装されたことを意味するものではありません)。そこにメモがあります:

このAPIは、タイマーがスケジュールどおりに実行されることを保証するものではありません。CPU負荷、その他のタスクなどによる遅延が予想されます。

そして、さらに明確に:

9)必要に応じて、ユーザーエージェントが定義した時間だけ待機します。

注:これは、デバイスの電力使用量を最適化するために、ユーザーエージェントが必要に応じてタイムアウトを埋めることができるようにすることを目的としています。たとえば、一部のプロセッサには、タイマーの粒度が低下する低電力モードがあります。このようなプラットフォームでは、ユーザーエージェントは、プロセッサに、関連するより高い電力使用量を伴うより正確なモードを使用するように要求する代わりに、このスケジュールに合わせてタイマーを遅くすることができます。

WindowAnimationTimingドラフトもご覧になることをお勧めします。

setIntervalまた、 /setTimeoutをアニメーション/クロックなどで使用する場合は、常にDateオブジェクトを使用して実際に経過した時間を測定してください(例:経由Date.now())。

于 2012-12-20T03:22:20.467 に答える
3

一部のブラウザは、ウィンドウがフォーカスされていない場合にタイムアウト/間隔イベントを発生させません。ウィンドウがフォーカスを取り戻すと、一度にすべてが起動します。これはパフォーマンスの決定であり(ユーザーが気付かないのにミリ秒ごとにイベントを発生させるのはなぜですか?)、私の知る限り、この動作を変更する方法はありません。

于 2012-12-20T03:16:38.727 に答える
1

MozillaFirefoxとGoogleChromeはどちらも、タブが非アクティブのときのティックの速度を抑制します(出典:http://pivotallabs.com/users/mrushakoff/blog/articles/2035-chrome-and-firefox-throttle-settimeout- setinterval-in-inactive-tabshttps: //stackoverflow.com/a/6032591/1756941 )

したがって、この回答が示すように、日付をキャプチャして目盛りと照合し、正しく機能しているかどうかを確認します。そうでない場合は、欠落している時間を補います。

JS:

var tick = 20;
var newLeft=0;

var box2 = document.getElementById("box2");
var remove = setInterval(function() {
    box2.style.left = "0px";

 var now, before = new Date();
    var move = setInterval(function() {
        now = new Date();
        var elapsedTime = (now.getTime() - before.getTime());
        if (elapsedTime > tick) {
            console.log((Math.floor(elapsedTime / tick) * 5));
            newLeft = Math.min(parseInt(box2.style.left) + (Math.floor(elapsedTime / tick) * 5), 850) + "px";
        }
        else {
            newLeft = Math.min(parseInt(box2.style.left) + 5, 850) + "px";
        }
        box2.style.left = newLeft;
        before = new Date();
        if (newLeft == "850px"){clearInterval(move);}
    }, tick);

}, 5000);
​

JSFiddle: http: //jsfiddle.net/3jY8h/1/

于 2012-12-20T03:40:57.777 に答える