非常简单的JavaScript/jQuery示例:意外的评估指令顺序

Jan*_*cke 8 javascript jquery css3 css-transitions

我很惊讶基于jQuery的CSS属性更改通过jQuery应用的CSS3转换规则实际上动画了此属性更改.请看http://jsfiddle.net/zwatf/3/:

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

$('.container').removeClass('active');
Run Code Online (Sandbox Code Playgroud)

这将高度从200px降低到15px.

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

$('.container').addClass('all-transition');
Run Code Online (Sandbox Code Playgroud)

发生的事情是高度的降低变得生动(至少在Firefox和Chrome上).在我的世界中,如果指令的顺序有任何意义,这不应该发生.

我想这种行为可以很好地解释.为什么会这样?我该怎样预防呢?

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

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

(1)和(2)应该尽快发生,所以我不喜欢任意延迟.

Ber*_*rgi 5

为什么会发生这种情况?

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

我该如何预防?

(非常小的)超时应该可以做到:http://jsfiddle.net/zwatf/4/

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

我不喜欢随意拖延工作。

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


Den*_*nis 5

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

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

jsFiddle

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