4

私はアコーディオン プラグインを開発していますが、slideUp/slideDown の最初の数ステップで、アコーディオンが本来の高さよりも 1 ピクセル高くなり、視覚的なバグが発生する 1 つのバグを除いて、ほとんど完了しています。私はそれを、slideUp アニメーションの最初のステップが何もしないという事実に絞り込みましたが、その理由がわかりません。次に例を示します。

console.log('Start');
var diff = 0;
var upNow = 100;
var downNow = 0;
$.fx.interval = 1000;
var duration = $.fx.interval * 100;
$("#div1").slideUp({
  easing: 'linear',
  duration: duration,
  step: function(now) {
    if (now != 0 && now > 90) {
      console.log("Slide Up: " + now);
      upNow = now;
    }
  }
});

$("#div2").slideDown({
  easing: 'linear',
  duration: duration,
  step: function(now) {
    if (now != 0 && now < 10) {
      downNow = now;
      diff = 100 - (upNow + downNow);
      console.log("Slide Down: " + now);
      console.log("Slide Difference:" + diff);
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style='height: 100px; background-color: red;' id='div1'>
</div>

<div style='height: 100px; background-color: blue; display: none;' id='div2'>
</div>

http://jsfiddle.net/hbh6U/

問題は、これらを同期する必要があることです。同期していない理由や、同期させる方法がわかりません。私が持っていたアイデアの 1 つは、slideDownアニメーションの最初のステップをスキップすることですが、その方法もわかりません。誰かアイデアを持っていますか、または以前にこのバグに直面しましたか?

4

2 に答える 2

1

問題は、jQuery の内部defaultPrefilterメソッドの次の行に帰着します。

tween.start = prop === "width" || prop === "height" ? 1 : 0;

これにより、2 番目の div (1px から 100px) のアニメーションが最初の div (0 から 100px) よりも短くなります。

これを解決するには、ステップ関数を次のように変更します。

function linearStep(now, animation){
    var animationStart = animation.start;
    if (animationStart === 1){
         animationStart = 0;   
    }
    animation.now = (animation.end - animationStart ) * animation.pos + animationStart;
}

1 ではなく 0 でnowある固定値を使用して同じ計算を行うことにより、計算値を上書きします。animationStart

アニメーションが実際に 1 で始まる場合、これは壊れますが、それを処理する他の方法があります。

サイドバイサイドフィドル: http://jsfiddle.net/Nd3w2/3/

于 2013-09-29T14:50:12.800 に答える
1

この問題がどこから来ているのか正確にはわかりません...日曜日の朝...調査する時間があまりありません...しかし、あなたのフィドルに基づいて2つの可能な解決策が見つかりました...

最初の 1 つは、overflow:hidden を使用して、これら 2 つの DIV を別の DIV にラップすることでした。

2番目...おそらくより適切なのは、divの1つでのみ「スライド」関数を呼び出してから、コールバックで2番目のサイズを更新することです。

console.log('Start');
var diff = 0;
var upNow = 100;
var downNow = 0;
$.fx.interval = 1000;
var duration = $.fx.interval * 100;
$("#div1").slideUp({ easing: 'linear', duration: duration, step: function(now)
{
    if(now != 0 && now > 90)
    {
        console.log("Slide Up: " + now);
        upNow = now;
    }

    $("#div2").height(100-  $("#div1").height());
}});

「disply:none」フォームの div2 スタイルも削除します...

それは問題を修正し、私の意見ではもう少しエレガントな解決策です.2つの別々のアニメーション関数を呼び出すと、同期の問題が発生する可能性があります..

于 2013-09-29T12:38:20.780 に答える