我感到惊讶的是,在基于jQuery的CSS属性更改后,通过jQuery 应用的CSS3转换规则实际上为此属性更改设置了动画。请查看http://jsfiddle.net/zwatf/3/:
最初,div由两个类设置样式,并且由于这两个类的默认CSS属性而具有一定的高度(200px)。然后通过删除一个类来使用jQuery修改高度:
$('.container').removeClass('active');
这会将高度从200px降低到15px。
之后,通过添加类来将转换规则应用于容器:
$('.container').addClass('all-transition');
正在发生的事情是高度的降低变得生动(至少在Firefox和Chrome上)。在我的世界中,如果指令的顺序有任何意义,就不会发生这种情况。
我想这个行为可以很好地解释。为什么会这样?我该如何预防呢?
这就是我想要实现的目标:
(1)和(2)应该尽快发生,所以我不喜欢任意延迟。
答案 0 :(得分:4)
运行脚本时,浏览器通常会将DOM更改推迟到最后,以防止不必要的绘制。您可以通过读/写某些属性来强制重排:
var container = $('.container').removeClass('active');
var foo = container[0].offsetWidth; //offsetWidth makes the browser recalculate
container.addClass('all-transition');
或者您可以使用短暂的setTimeout
,这通过让浏览器自动重排,然后添加类来实现基本相同的事情。
答案 1 :(得分:3)
为什么会这样?
我猜是因为DOM看到它们一起应用;立即连续的动作通常被缓存而不是一个接一个地应用。
我该如何预防?
(非常小的)超时应该执行:http://jsfiddle.net/zwatf/4/
(来自评论)手动触发重排也有助于:http://jsfiddle.net/zwatf/9/
我不喜欢处理任意延迟。
然后我认为唯一可能的另一种方法是从动画css属性中删除height
,即你需要明确说明你想要制作哪些动画:http://jsfiddle.net/zwatf/5/
答案 2 :(得分: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
});