0

私はこれがいくつかの場所に尋ねられているのを見ていますが、ほとんどは回避策を提供するか、その人のコードは要点を証明していません. jQuery .animate() を使用して、1 ピクセルあたり 1 ミリ秒ですべてのピクセルを下にスクロールするつもりはありませんが、問題を示すために、ここに私のコードを示します。

window.stopscrolling = 0;

function scrollMore(id) {
   stopscrolling++;
   if (stopscrolling < 100) {
      var y = $(window).scrollTop();
      if ($("#"+id).offset().top != y){
         //console.log(y);
         if ($("#"+id).offset().top > y) {
             $('html, body').animate({
                scrollTop: y+1
             }, 1, "linear", function(){scrollMore(id);});
         }
         else {
             $('html, body').animate({
                scrollTop: y-1
             }, 1, "linear", function(){scrollMore(id);});
         }
      }
   }
}

これをコピーして Chrome コンソールに貼り付け、scrollMore("#itemId") のように実行すると、ウィンドウは約 5 ピクセルしか下にスクロールしませんが、100 ピクセル下にスクロールする必要があります。

console.log のコメントを外すと、次のように実行されていることがわかります。ピクセル 0 が 1 回、ピクセル 1 が 4 回、2 が 8 回、3 が 16 回、4 回が 32 回、5 回が 37 回。通算98回。

if でこの構文も試してみましたが、同じ結果が得られました。

if ($("#"+id).offset().top > y) {
     $('html, body').animate({
        scrollTop: y+1
     },
     {
        duration : 1,
        easing: "linear",
        complete: function(){scrollMore(id)}
    });
 } 

次のコードを使用して ID でアイテムにスクロールできることを認識していますが、アイテムがスクロールすると間違った場所にスクロールしてしまいます。

$('html, body').animate({
    scrollTop: $("#"+id).offset().top
    }, 2000);

問題は、ドキュメントに後で実行されると明示的に記載されているのに、アニメーションが完了する前に jQuery が「完了」関数を実行するのはなぜですか? そしてもちろん、私はそれについて何ができますか?

4

1 に答える 1

3

数週間前に同様の問題に遭遇しました。jQuery のような構文を使用して複数の要素をアニメーション化しようとすると、$('html, body').animate();実際には両方の要素のアニメーション関数が別々に起動されます。つまり、追加したコールバック パラメータfunction(){scrollMore(id)}は、実際には 2 回呼び出されます。つまり、 のアニメーションが終了すると、 のアニメーションが終了htmlする前に のコールバックが起動されbody、その後、bodyのコールバックも同様に起動されます。これらの複数の予期しないコンソール ログは、そこから来ていると思います。

これを回避するにはいくつかの方法がありますが、最も簡単なのは、コールバックが起動されたかどうかをコールバックに伝える変数を作成することです。何かのようなもの:

var animated = false;

$('html, body').animate({
       scrollTop: y+1
    },
    {
       duration : 1,
       easing: "linear",
       complete: function(){

          if (!animated) {
              animated = true;
              scrollMore(id);
          }

       }
    }
);
于 2013-08-29T15:03:39.740 に答える