9

令我惊讶的是,在基于 jQuery 的 CSS 属性更改之后通过 jQuery 应用的 CSS3 转换规则实际上会为该属性更改设置动画。请查看http://jsfiddle.net/zwatf/3/

最初,一个 div 由两个类设置样式,并且由于这两个类的默认 CSS 属性而具有一定的高度(200px)。然后使用 jQuery 通过删除一个类来修改高度:

$('.container').removeClass('active');

这会将高度从 200 像素降低到 15 像素。

之后,通过添加一个类将转换规则应用于容器:

$('.container').addClass('all-transition');

正在发生的事情是高度的减少变成了动画(至少在 Firefox 和 Chrome 上)。在我的世界里,如果指令的顺序有任何意义,这不应该发生。

我想这种行为可以很好地解释。为什么会这样?我该如何预防?

这就是我想要实现的目标:

  1. 使用 jQuery 修改默认样式(不是由 CSS3 过渡动画!)
  2. 使用 jQuery 应用转换规则
  3. 使用 jQuery 更改属性(由 CSS3 过渡动画)

(1) 和 (2) 应该尽快发生,所以我不喜欢随意拖延。

4

3 回答 3

5

为什么会这样?

我猜是因为 DOM 看到它们一起应用;立即连续的动作通常被缓存而不是一个接一个地应用。

我该如何预防?

一个(非常小的)超时应该这样做:http: //jsfiddle.net/zwatf/4/

(来自评论)手动触发回流也有帮助:http: //jsfiddle.net/zwatf/9/

我不喜欢任意拖延。

然后我认为唯一可能的方法是height从动画css属性中删除 ,即您需要明确说明您想要动画的那些:http: //jsfiddle.net/zwatf/5/

于 2013-03-03T14:11:05.317 回答
5

运行脚本时,浏览器通常会将 DOM 更改推迟到最后,以防止不必要的绘制。您可以通过读取/写入某些属性来强制回流:

var container = $('.container').removeClass('active');
var foo = container[0].offsetWidth;  //offsetWidth makes the browser recalculate
container.addClass('all-transition');

jsFiddle

或者您可以使用setTimeout较短的持续时间,它通过让浏览器自动重排然后添加类来完成基本相同的事情。

于 2013-03-03T14:22:16.500 回答
1

我想,它发生得太快了。如果你这样做:

$('.container').toggleClass('active',function() {
    $('.container').addClass('all-transition');
});

它会像您预期的那样运行,对吗?

好的,好的,我测试了它,但我没有意识到它没有按预期工作。这里有一个替代方案:

$('.container').removeClass('active').promise().done(function(){
    $('.container').addClass('all-transition');

    $('.container').css('height','300'); //to see the easing
});
于 2013-03-03T13:45:24.220 回答