Javascript jQuery';s stop()似乎阻止了';我还没有排队

Javascript jQuery';s stop()似乎阻止了';我还没有排队,javascript,jquery,animation,Javascript,Jquery,Animation,jQuery的stop()实际上是如何工作的 如果你看,当你在主蓝色框上悬停时,它应该淡入红色,当你离开时,它应该淡入红色。问题是,即使在第一次淡出完成之前鼠标已悬停,它也会完全淡出为红色(然后再回到蓝色)。通过滑动效果可以更清楚地看到问题。将鼠标悬停在幻灯片“按钮”上,主框将滑至蓝色,将鼠标悬停在关闭位置,主框将滑回。但是,在第一个动画完成之前,尝试打开和关闭、打开和关闭鼠标悬停。您将看到所有四个动画都已执行。我在这里包括了这两个例子,以表明这不仅仅是一个有一种效果的问题 我认为这可以通过在动

jQuery的
stop()
实际上是如何工作的

如果你看,当你在主蓝色框上悬停时,它应该淡入红色,当你离开时,它应该淡入红色。问题是,即使在第一次淡出完成之前鼠标已悬停,它也会完全淡出为红色(然后再回到蓝色)。通过滑动效果可以更清楚地看到问题。将鼠标悬停在幻灯片“按钮”上,主框将滑至蓝色,将鼠标悬停在关闭位置,主框将滑回。但是,在第一个动画完成之前,尝试打开和关闭、打开和关闭鼠标悬停。您将看到所有四个动画都已执行。我在这里包括了这两个例子,以表明这不仅仅是一个有一种效果的问题

我认为这可以通过在动画之前添加一个
stop
来轻松解决,如代码中注释的那样。但是,如果我这样做,当前动画将停止,而后续动画将永远不会开始。几乎就好像
stop
正在阻止调用
stop
后发生的动画一样

我错过了什么


谢谢

您缺少接受两个参数的
.stop()
。均为布尔值,表示:

- clearQueue (first)
- jumpToEnd (second)
因此,通过调用
$('#foo').stop(true,true).doSomeOtherStuff()
您应该可以实现您想要的目标


参考:

您可以将stop()选项设置为(true,true),以便取消cue中的所有事件并跳到上一个动画的末尾。看看小提琴:http://jsfiddle.net/hWTT6/4/

可以通过以下不同方式调用stop方法:

.stop(true); 
//Same as:
.stop(true, false); //Empty the animation queue only


//Or
.stop(true,true); // Empties the animation queue AND jumps to the end


//Default
.stop()

//Same as

.stop(false,false);
可能有更好的方法使用。动画:

这样,动画将在需要时停止,并仍运行下一个动画


执行
.stop
然后
slideUp/slideDown
fadeIn/fadeOut
的问题是动画可能过早结束,并保持不正确的高度/不透明度。

问题是CSS在任意点停止会弄糟

fadeIn()
fadeOut()
slideUp()
slideDown()
从当前状态移动到新状态,然后恢复到该状态-而不是原始CSS

在.stop()之后,您需要将CSS修复回可用状态以继续,或者更清楚地指定动画目标

正如其他人所说,通过确保停止动画时,它跳到动画的末尾,而不是将所有内容都保持在任意状态,可以将CSS放置到正确的位置

更新:

请查看此演示更新中的代码:

这可能不完全是您希望它执行的方式,但如果您不希望动画按其路线运行,那么关键在于将动画恢复到可以按您希望的方式继续的状态

$(function() {
    $('#fade')
    .mouseenter(function() {
        $('#fg_fade').stop().animate({ 'opacity': 0 }, 'slow', function() {
            $('#fg_fade').css('height', '100%');
        });
    })
    .mouseleave(function() {
        $('#fg_fade').stop().animate({ 'opacity': 1, 'height': '100%' }, 'slow');
    });

    $('#slide_fire')
    .mouseenter(function() {
        $('#fg_fade').stop().animate({ 'height': 0 }, 'slow', function() {
            $('#fg_fade').css('opacity', 1);
        });
    })  
    .mouseleave(function() {
        $('#fg_fade').stop().animate({ 'height': '100%' }, 'slow', function() {
            $('#fg_fade').css('opacity', 1);
        });
    });
});

问题是由
fadeIn
fadeOut
等工作方式引起的。您可能期望它们在0和1之间衰减。然而,实际上,它们在0和“基线”不透明度之间衰减。你可以在这里看到:

您会注意到我将初始不透明度设置为
.5
。现在,当我调用
fadeIn
时,它不会一直消失到
1
中,而是消失到我的基线
.5
。当过早停止动画时,问题就会出现,“基线”将变为停止时的不透明度。现在,当您在
mouseleave
上调用
fadeIn
时,它会尝试淡入这个新的基线,并发现它已经存在。您可以在这里看到这一点:

(原件,但带有
.stop

如果你将鼠标放在<代码>幻灯片上,然后通过动画将其移除,它将在中间停止。现在将鼠标放回幻灯片上,等待动画完成。如果现在移除鼠标,您将看到它滑回到第一个动画停止的位置。这是因为这是新的“基线”

解决此问题的方法实际上是用更明确的动画替换
fadeIn
fadeOut
,等等。例如,使用
fadeTo
告诉它在
0
1
之间淡入淡出:


请注意,由于我告诉它淡入
0
1
,所以一切正常。使用
animate

可以做类似的事情来替换
slideUp
slideDown
,我一直认为
stop()
会杀死队列。是的,这在我第一次使用它时也咬了我一口。似乎
stop()
的标准用例实际上应该是行为
stop(true,true)
而不是它的默认行为,但我没有编写库;)。谢谢,我知道这两个bool需要时间,但我误解了它们的工作原理。这使我更接近期望的结果,但实际上我不想跳到第一个动画的结尾,我希望它停在原地,然后从那里继续下一个动画。我尝试了
(true,false)
,但这仍然阻止第二个动画运行。也许单靠
stop
是无法做到这一点的。@tjm:正如我在回答中所说的,如果你不想完成动画,你需要在某个时候将状态恢复到可行的状态,并以非切换的方式指定动画的目标。看我的更新。谢谢你。这就解决了这个问题,并很好地解释了内置动画与原始css的关系。如果我用稍微不同的措辞回答这个问题,你肯定会得到“滴答声”,但由于我专注于
stop
,我不知道该怎么办。我会想一想,然后再回来。但是谢谢你,这很有帮助。@tjm:是的,我看到了问题——解决潜在问题
$(function() {
    $('#fade')
    .mouseenter(function() {
        $('#fg_fade').stop().animate({ 'opacity': 0 }, 'slow', function() {
            $('#fg_fade').css('height', '100%');
        });
    })
    .mouseleave(function() {
        $('#fg_fade').stop().animate({ 'opacity': 1, 'height': '100%' }, 'slow');
    });

    $('#slide_fire')
    .mouseenter(function() {
        $('#fg_fade').stop().animate({ 'height': 0 }, 'slow', function() {
            $('#fg_fade').css('opacity', 1);
        });
    })  
    .mouseleave(function() {
        $('#fg_fade').stop().animate({ 'height': '100%' }, 'slow', function() {
            $('#fg_fade').css('opacity', 1);
        });
    });
});