質問

最近、同じ関数について質問したところ、while ループを使用していたため問題が解決され、チュートリアルに誘導されました。つまり、関数はアニメーション化されず、フリーズしてサイズ変更されるだけでした。setTimeout を使用するこの新しい方法は機能するはずです。唯一のことは、アニメーション化するのではなく、新しいサイズにスナップするだけであるということです。Firebugによるとエラーはありません。これがアニメーションを管理するコードの現在のセクションです。

// Resize in timeframe
// Work out distance
var widthdiff = width - parseInt(element.style.width);
var heightdiff = height - parseInt(element.style.height);

// Work out how miliseconds per step (100 in total)
var steptime = timeframe / 100;

// Work out how many pixels it needs to move each step
var widthpps = widthdiff / 100; // ERROR?
var heightpps = heightdiff / 100;

// Set up original sizes
var origwidth = parseInt(element.style.width);
var origheight = parseInt(element.style.height);

// Loop through all 100 steps setting a time out resize each time
var timers = [];
for(var i = 0; i < 100; i++)
{
    timers[i] = setTimeout(function() { // ERROR?
        element.style.width = origwidth + (widthpps * i) + 'px';
        element.style.height = origheight + (heightpps * i) + 'px';
    }, i * steptime);
}

引数は問題なく渡されています。すべてをテストし、一度アニメーション化しましたが、ただ間違っていました。したがって、私の問題は「ERROR?」というコメントに近いものになります。私は信じます。助けていただきありがとうございます。

役に立ちましたか?

解決

問題は、変数「i」が次のようになることです。 共有 すべてのタイムアウト機能によって。

書くことができます 関数を使用してタイムアウト関数を構築することも、関数をインラインでラップすることもできます。

timers[i] = setTimeout((function(privateEye) {
    return function() { 
      element.style.width = origwidth + (widthpps * privateEye) + 'px';
      element.style.height = origheight + (heightpps * privateEye) + 'px';
    })(i), i * steptime);

「i」が「共有」されると言うとき、私が言いたいのは、ループ内で構築する各関数がそのループ変数を正しく参照するということです。しかし、その変数に何が起こっているのでしょうか?ループを繰り返すたびに変化します。関数が参照することを理解することが重要です。 本物 「i」変数。凍結されたコピーではありません。を使用することで、 2番 関数、上で行ったように、 コピー ループ内で使用される「i」の値。

他のヒント

コードを完全には監査していませんが、ここに症状と一致するエラーがあります。

timers[i] = setTimeout(function() { // ERROR?
    element.style.width = origwidth + (widthpps * i) + 'px';    // <== error
    element.style.height = origheight + (heightpps * i) + 'px'; // <== error
}, i * steptime);

問題は、関数が ライブリファレンスi, 、ループの反復時点での値のコピーではありません。それで彼らは皆見ます i 最後の値の時点で。

これは簡単に修正できます。

timers[i] = setTimeout(makeStepFunction(i), i * steptime);

// Anywhere in the surrounding function, not in the loop:
function makeStepFunction(step) {
    return function() {
        element.style.width = origwidth + (widthpps * step) + 'px';
        element.style.height = origheight + (heightpps * step) + 'px';
    };
}

さて、この関数は、 setTimeout will call は、に渡された引数を使用します。 makeStepFunction, 、 それよりも i.

あなた できる 名前付き関数を使用せずにこれを実行しますが、すぐに混乱してしまいます。

timers[i] = setTimeout((function(step) {
    return function() {
        element.style.width = origwidth + (widthpps * step) + 'px';
        element.style.height = origheight + (heightpps * step) + 'px';
    };
})(i), i * steptime);

これはすべて、クロージャ (データを「閉じる」関数) が JavaScript でどのように動作するかに関係しています。これらは非常に強力ですが、その仕組みを理解すれば、それほど複雑ではありません。FWIW、私のブログ投稿 クロージャは複雑ではありません 役立つかもしれません。それらがどのように機能するかを理解すると、その謎は失われます(そしてさらに便利になります)。

別の解決策は、setInterval を使用し、パスごとに更新されるグローバル i と setInterval i がキャンセルされたカットオフ値をメソッドで使用することです。

var i = 0;
var interval = setInterval(
    function() {
        element.style.width = origwidth + (widthpps * i) + 'px';
        element.style.height = origheight + (heightpps * i) + 'px';
        i++;
        if(i==100)
             clearInterval(interval);  //Stops executing
    }, stepTime);

setTimeout と setInterval がどのように機能するかについての説明を見つけて、どちらが目的に最適かを確認してください。http://ejohn.org/blog/how-javascript-timers-work/

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top