向上滑动线性缓动的第一步没有任何作用

Slide Up Linear Easing First Step Does Nothing

本文关键字:任何 作用 第一步 线性      更新时间:2023-09-26

我正在开发一个手风琴插件,除了一个错误之外,它大部分都完成了,在slideUp/slideDown的前几步中,手风琴比它应该高1px,导致视觉错误。我将其缩小到这样一个事实,即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/

问题是我需要这些同步,但我无法弄清楚为什么它们不同步,或者如何让它们同步。我的一个想法是跳过slideDown动画的第一步,但我也不确定该怎么做。以前有没有人有任何想法或遇到过这个错误?

问题归结为 jQuery 内部defaultPrefilter方法中的这一行:

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

这会导致第二个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;
}

它通过使用固定animationStart执行相同的计算来覆盖计算now值,该是 0 而不是 1。

如果动画实际上从 1 开始,这将中断,但届时还有其他方法可以处理它。

并排小提琴:http://jsfiddle.net/Nd3w2/3/

我不知道这个问题是从哪里来的......星期天早上...没有太多时间去调查...但是我根据您的小提琴找到了两种可能的解决方案......

第一个是将这两个 DIV 包装在另一个带有溢出:隐藏的 DIV 中。

第二个...可能更合适的是仅在其中一个div上调用"slide"函数,然后在回调中更新第二个div的大小,如下所示:

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());
}});

同时删除div2 样式中的"disply:none"...

它解决了这个问题,在我看来是一个更优雅的解决方案......调用两个单独的动画函数可能会导致可能的同步问题...希望有帮助...