jQuery向上滑动线性宽松第一步什么也没做

时间:2013-09-27 02:40:57

标签: javascript jquery animation linear easing

所以,我正在开发一个手风琴插件,除了一个bug之外,它主要是完成的,对于slideUp / slideDown的前几个步骤,手风琴比它的意图高1px,造成视觉错误。我已经把它缩小到这样一个事实,即slideUp动画的第一步没有做任何事情,我无法弄清楚为什么。这是一个例子

HTML

<div style='height: 100px; background-color: red;' id='div1'>
</div>

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

JS

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

http://jsfiddle.net/hbh6U/

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

谢谢,Gareth

2 个答案:

答案 0 :(得分:1)

我不确切地知道这个问题来自哪里......星期天早上......没有太多时间去研究......但我找到了两种可能的解决方案,基于你的小提琴......

首先是将这两个DIV用overflow:hidden包装在另一个DIV中。

第二个......可能更合适的是只在其中一个div上调用“slide”函数,然后在回调中更新第二个的大小,类似:

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”......

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

答案 1 :(得分:1)

问题归结为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;
}

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

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

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