CSS转换不会被解雇
我正在创建一个DOM元素(div),将其添加到DOM中,然后在javascript中快速更改其宽度。 这在理论上应该触发CSS3过渡,但结果直接从A到B,没有两者之间的过渡。
如果我通过单独的测试点击事件更改宽度,一切都按预期工作。
这是我的JS和CSS:
JS(jQuery):
var div = $('').addClass('trans').css('width', '20px'); $('#container').append(div); div.css('width', '200px');
CSS(只需mozilla):
.trans { -moz-transition-property: all; -moz-transition-duration: 5s; height: 20px; background-color: cyan; }
我在这里弄乱了,还是“一气呵成”并不是应该做的事情?
所有帮助都非常感谢。
不依赖于setTimeout的更简洁方法是在设置之前读取有问题的css属性:
var div = $('').addClass('trans'); $('#container').append(div); div.css('width');//add this line div.css('width', '200px');
在这里工作:
http://jsfiddle.net/FYPpt/144/
正如Lucero在下面的评论中所解释的那样,这样做是必要的,以迫使浏览器计算实际值而不是“自动”,“inheritance”或类似。 如果没有实际值,浏览器将不会知道新值是否与以前相比有所变化。
这有两种方法可以做到这一点。
1 – CSS转换
通过使用setTimeout
, addClass
方法将在之后运行,而不是与前面的脚本一起运行,以便触发transition
事件
示例jsfiddle
jQuery的:
var div = $(''); $('#container').append(div); // set the class change to run 1ms after adding the div setTimeout(function() {div.addClass('wide')}, 1);
CSS:
.trans { width: 20px; height: 20px; background-color: cyan; -webkit-transition: all 5s ease; -moz-transition: all 5s ease; -ie-transition: all 5s ease; -o-transition: all 5s ease; transition: all 5s ease; } .wide { width: 200px; }
2 – jQuery的.animate()
函数
示例jsfiddle
jQuery的:
var div = $(''); $('#container').append(div); div.animate({'width': '200px'}, 5000); // 5 sec animation
CSS:
.trans { width: 20px; height: 20px; background-color: cyan; }
尝试调用jQuery的.offset()
方法。
当浏览器获得偏移量时,它会触发回流/重绘/布局事件,从而允许转换工作。
看到这个小提琴: http : //jsfiddle.net/FYPpt/199/
另见 – http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html
为了回应赏金:
如果您不知道哪个属性正在转换,或者根本不认为强制使用setTimeout
来触发动画是一种好习惯,那么您可以用另一种方式强制重排。
setTimeout
首先起作用的原因是由于您在此期间导致完整文档重排,即使持续时间设置为0
。 这不是导致回流的唯一方法。
链接到一个小提琴
JavaScript的
for (x = Math.ceil(Math.random() * 10), i=0;i
使用这个JavaScript,我们随机添加1到10个div
元素,然后随机选择其中一个并添加wide
类。
你会注意到那里有一个奇怪的JavaScript行,即x[0].offsetHeight
。 这是整个行动的关键。 调用offsetHeight
会在不使用setTimeout或查询CSS值的情况下触发文档重排。
与DOM相关的回流是什么:
重排计算页面的布局。 元素上的重排会重新计算元素的维度和位置,并且还会触发该元素在DOM中出现的子元素,祖先和元素之后的进一步回流。 然后它调用最后的重绘。 回流非常昂贵,但遗憾的是它可以轻松触发。
因此,请谨慎使用这些function。 对于大多数现代浏览器来说并不是太过关注(因为jQuery因为多次回流而臭名昭着),但在你的网站上添加类似这个解决方案的东西之前还需要考虑一些事情。
重要说明:这不比 setTimeout
调用 更高效或更低效 。 这不是一个神奇的子弹解决方案,它在引擎盖下做同样的事情。
这是相应的CSS,供参考:
.trans { width: 20px; height: 20px; background-color: cyan; -webkit-transition: all 5s ease; -moz-transition: all 5s ease; -o-transition: all 5s ease; transition: all 5s ease; } .trans.wide { width: 200px; }
正如@onetrickpony所问,如果所有规则都在CSS文件中并且不应该添加到JS函数中,该怎么办?
基于Torin Finnemann的回答,只是略有改变:
添加一个定义规则的额外类: new-rules
var div = $(''); $('#container').append(div); var div = $('').addClass('trans'); $('#container').append(div); div.height(); div.addClass('new-rules');
在您的CSS中有预定义的类:
.trans.new-rules { width: 200px; background: yellow; }
现在,在更改CSS时不需要与JS混在一起。 在new-rules
的CSS文件中更改它:)
var div = $(''); $('#container').append(div); div.css('width', '20px').addClass('trans', function() { div.css('width', '200px') });
创建一个新的DIV元素,并将“trans”类添加到该元素,以便触发CSS转换