使用jQuery动画addClass/removeClass

我正在使用jQuery和jQuery-ui,并希望在各种对象上动画各种属性。

为了解释这个问题,我将它简化为一个div,当用户将鼠标放在上面时,它会从蓝色变成红色。

当使用animate()时,我能够获得我想要的行为,然而,当这样做时,我正在动画的样式必须在动画代码中,因此与我的样式表分开。(见示例1)

另一种方法是使用addClass()removeClass(),但我无法重新创建与animate()相同的行为。(见示例2)


示例1

让我们看一下使用animate()的代码:

$('#someDiv')
.mouseover(function(){
$(this).stop().animate( {backgroundColor:'blue'}, {duration:500});
})
.mouseout(function(){
$(this).stop().animate( {backgroundColor:'red'}, {duration:500});
});

它显示了我正在寻找的所有行为:

  1. 动画在红色和蓝色之间平滑。
  2. 当用户快速移动鼠标进出div时,没有动画'overqueue-ing'。
  3. 如果用户在动画仍在播放时将鼠标移出/移进,它将在当前的“中途”状态和新的“目标”状态之间正确地缓解。

但是由于样式更改是在animate()中定义的,我必须更改那里的样式值,并且不能只是让它指向我的样式表。这种风格定义的“碎片化”是真正困扰我的事情。


示例2

这是我目前使用addClass()removeClass的最佳尝试(注意,为了使动画工作,你需要jQuery-ui):

//assume classes 'red' and 'blue' are defined


$('#someDiv')
.addClass('blue')
.mouseover(function(){
$(this).stop(true,false).removeAttr('style').addClass('red', {duration:500});
})
.mouseout(function(){
$(this).stop(true,false).removeAttr('style').removeClass('red', {duration:500});
});

这体现了性质1。和2。我原来的要求,然而,3不工作。

我理解其中的原因:

在制作addClass()removeClass()动画时,jQuery为元素添加一个临时样式,然后将适当的值递增,直到它们达到所提供的类的值,然后才真正添加/删除类。

因此,我必须删除样式属性,否则如果动画中途停止,样式属性将保留并永久覆盖任何类值,因为标签中的样式属性比类样式更重要。

然而,当动画完成一半的时候,它还没有添加新的类,所以有了这个解决方案,当用户在动画完成之前移动鼠标时,颜色就会跳到之前的颜色。


理想情况下,我想做的事情是这样的:

$('#someDiv')
.mouseover(function(){
$(this).stop().animate( getClassContent('blue'), {duration:500});
})
.mouseout(function(){
$(this).stop().animate( getClassContent('red'), {duration:500});
});

其中getClassContent只返回所提供类的内容。关键的一点是,这样我就不必把样式定义保存在各处,而是可以将它们保存在样式表中的类中。

384018 次浏览

既然你不担心IE,为什么不只是使用css过渡来提供动画和jQuery来改变类。实例:http://jsfiddle.net/tw16/JfK6N/

#someDiv{
-webkit-transition: all 0.5s ease;
-moz-transition: all 0.5s ease;
-o-transition: all 0.5s ease;
transition: all 0.5s ease;
}

另一个解决方案(但它需要jQueryUI正如Richard Neil Ilagan在评论中指出的那样):-

addClass, removeClass和toggleClass也接受第二个参数;从一种状态到另一种状态所需的时间。

$(this).addClass('abc',1000);

参见jsfiddle:- http://jsfiddle.net/6hvZT/1/

你只需要jQuery UI特效核心 (13KB),来启用添加的持续时间(就像它指出的Omar Tariq)

你可以使用jquery ui的switchClass,这里有一个例子:

$( "selector" ).switchClass( "oldClass", "newClass", 1000, "easeInOutQuad" );

或者看到这个jsfiddle

虽然这个问题已经很老了,但我在这里添加了其他答案中没有的信息。

OP使用stop()在事件完成后立即停止当前动画。但是,在函数中使用正确的参数组合应该会有所帮助。如。Stop (true,true)或Stop (true,false),因为这会很好地影响排队动画。

下面的链接演示了stop()中可用的不同参数,以及它们与finish()的区别。

http://api.jquery.com/finish/

虽然OP使用JqueryUI没有问题,但这是为其他可能遇到类似场景但不能使用JqueryUI/也需要支持IE7和8的用户准备的。

我正在研究这个,但想要有一个不同的转换率的进出。

这就是我最后做的:

//css
.addedClass {
background: #5eb4fc;
}


// js
function setParentTransition(id, prop, delay, style, callback) {
$(id).css({'-webkit-transition' : prop + ' ' + delay + ' ' + style});
$(id).css({'-moz-transition' : prop + ' ' + delay + ' ' + style});
$(id).css({'-o-transition' : prop + ' ' + delay + ' ' + style});
$(id).css({'transition' : prop + ' ' + delay + ' ' + style});
callback();
}
setParentTransition(id, 'background', '0s', 'ease', function() {
$('#elementID').addClass('addedClass');
});


setTimeout(function() {
setParentTransition(id, 'background', '2s', 'ease', function() {
$('#elementID').removeClass('addedClass');
});
});

这将立即将背景色变为#5eb4fc,然后在2秒内慢慢淡出到正常状态。

这是一个小提琴