在附加元素上触发CSS转换 [英] Trigger CSS transition on appended element

查看:132
本文介绍了在附加元素上触发CSS转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如这个问题所观察到的那样,附加元素以某种方式被忽略 - 转换的结束状态立即呈现。



例如,给定此CSS(此处忽略前缀):

  .box {
opacity:0;
转换:全部2s;
background-color:red;
height:100px;
width:100px;
}

.box.in {opacity:1; }

此元素的不透明度将立即设置为1:

  //不动画
var $ a = $('< div>')
.addClass('box a')
.appendTo('#wrapper');
$ a.addClass('in');

我已经看到几种触发过渡以获得预期行为的方法:

  //动画
var $ b = $('< div>')
.addClass('box b' )
.appendTo('#wrapper');

setTimeout(function(){
$('。b')。addClass('in');
},0);

//动画
var $ c = $('< div>')
.addClass('box c')
.appendTo('#包装');

$ c [0]。 offsetWidth = $ c [0] .offsetWidth
$ c.addClass('in');

//动画
var $ d = $('< div>')
.addClass('box d')
.appendTo('#包装');
$ d.focus()。addClass('in');

相同的方法适用于vanilla JS DOM操纵 - 这不是jQuery特定的行为。 >

编辑 - 我正在使用Chrome 35。



JSFiddle (包括香草JS示例)。




  • 为什么立即使用CSS动画附加元素被忽略?

  • 这些方法的工作原理和原因如何?

  • 是否有其他方法?

  • 哪个是首选解决方案?


解决方案

p>没有动画新添加的元素的原因是浏览器正在批量回流。



添加元素时,需要回流。同样适用于添加类。但是,当您在单个JavaScript回合中同时进行操作时,浏览器有机会优化第一个。在这种情况下,只有单个(初始和最终同时)样式值,所以没有转换将会发生。



setTimeout 技巧是因为它将类添加延迟到另一个JavaScript循环,所以有两个值存在于渲染引擎,需要计算,因为有时间点,当第一个被提供给用户。



批处理规则还有一个例外。浏览器需要计算即时值,如果您正在尝试访问它。其中一个值为 offsetWidth 。当您访问它时,触发回流。另外一个是在实际显示过程中单独完成的。再次,我们有两种不同的风格值,所以我们可以及时插入它们。



这是非常少的场合,当这种行为是可取的时候。大多数时间访问DOM修改之间的回流引起的属性可能会导致严重的减缓。



首选解决方案可能因人而异,但对我而言的 offsetWidth (或 getComputedStyle())是最好的。有些情况下,当 setTimeout 被触发时,不需要重新计算样式。这是罕见的情况,主要是在加载的网站,但它发生。那么你不会得到你的动画。通过访问任何计算的样式,您强制浏览器实际计算它。


As this question observes, immediate CSS transitions on newly-appended elements are somehow ignored - the end state of the transition is rendered immediately.

For example, given this CSS (prefixes omitted here):

.box { 
  opacity: 0;
  transition: all 2s;
  background-color: red;
  height: 100px;
  width: 100px;
}

.box.in { opacity: 1; }

The opacity of this element will be set immediately to 1:

// Does not animate
var $a = $('<div>')
    .addClass('box a')
    .appendTo('#wrapper');
$a.addClass('in');

I have seen several ways of triggering the transition to get the expected behaviour:

// Does animate
var $b = $('<div>')
    .addClass('box b')
    .appendTo('#wrapper');

setTimeout(function() {
    $('.b').addClass('in');
},0);

// Does animate
var $c = $('<div>')
    .addClass('box c')
    .appendTo('#wrapper');

$c[0]. offsetWidth = $c[0].offsetWidth
$c.addClass('in');

// Does animate
var $d = $('<div>')
    .addClass('box d')
    .appendTo('#wrapper');
$d.focus().addClass('in');

The same methods apply to vanilla JS DOM manipulation - this is not jQuery-specific behaviour.

Edit - I am using Chrome 35.

JSFiddle (includes vanilla JS example).

  • Why are immediate CSS animations on appended elements ignored?
  • How and why do these methods work?
  • Are there other ways of doing it
  • Which, if any, is the preferred solution?

解决方案

The cause of not animating the newly added element is batching reflows by browsers.

When element is added, reflow is needed. The same applies to adding the class. However when you do both in single javascript round, browser takes its chance to optimize out the first one. In that case, there is only single (initial and final at the same time) style value, so no transition is going to happen.

The setTimeout trick works, because it delays the class addition to another javascript round, so there are two values present to the rendering engine, that needs to be calculated, as there is point in time, when the first one is presented to the user.

There is another exception of the batching rule. Browser need to calculate the immediate value, if you are trying to access it. One of these values is offsetWidth. When you are accessing it, the reflow is triggered. Another one is done separately during the actual display. Again, we have two different style values, so we can interpolate them in time.

This is really one of very few occasion, when this behaviour is desirable. Most of the time accessing the reflow-causing properties in between DOM modifications can cause serious slowdown.

The preferred solution may vary from person to person, but for me, the access of offsetWidth (or getComputedStyle()) is the best. There are cases, when setTimeout is fired without styles recalculation in between. This is rare case, mostly on loaded sites, but it happens. Then you won't get your animation. By accessing any calculated style, you are forcing the browser to actually calculate it.

这篇关于在附加元素上触发CSS转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆