我正在创建一个DOM元素(div),将其添加到DOM中,然后在javascript中快速更改其宽度。这在理论上应该触发CSS3过渡,但结果直接从A到B,没有两者之间的过渡。
如果我通过单独的测试点击事件更改宽度,一切都按预期工作。
这是我的JS和CSS:
JS(jQuery):
var div = $('<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;
}
我在这里弄得一团糟,还是“一气呵成”并不是应该做的事情?
非常感谢所有帮助。
答案 0 :(得分:43)
不依赖于setTimeout的更简洁方法是在设置之前读取有问题的css属性:
var div = $('<div />').addClass('trans');
$('#container').append(div);
div.css('width');//add this line
div.css('width', '200px');
在这里工作:
http://jsfiddle.net/FYPpt/144/
正如Lucero在下面的评论中所解释的那样,这样做是必要的,以迫使浏览器计算实际值而不是“自动”,“继承”或类似。如果没有实际值,浏览器将不会知道新值是否与以前相比有所改变。
答案 1 :(得分:21)
这有两种方法可以做到这一点。
1 - CSS过渡
使用setTimeout
addClass
方法将运行而不是与前面的脚本一起运行,以便transition
事件将触发
jQuery的:
var div = $('<div class="trans" />');
$('#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()
功能
jQuery的:
var div = $('<div class="trans" />');
$('#container').append(div);
div.animate({'width': '200px'}, 5000); // 5 sec animation
CSS:
.trans {
width: 20px;
height: 20px;
background-color: cyan;
}
答案 2 :(得分:5)
尝试调用jQuery&#39; .offset()
方法。
当浏览器获得偏移时,它会触发回流/重绘/布局事件,从而允许转换工作。
看到这个小提琴:http://jsfiddle.net/FYPpt/199/
另见 - http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html
答案 3 :(得分:3)
回应赏金:
如果您不知道哪些房产正在转型,或者根本不认为迫使setTimeout
获取动画,这是一种很好的做法,你可以用另一种方式强制回流。
setTimeout
首先起作用的原因是由于您在此期间导致完整文档重排,即使持续时间设置为0
。这不是引起回流的唯一方法。
<强>的JavaScript 强>
for (x = Math.ceil(Math.random() * 10), i=0;i<x;i++){
$('<div />').appendTo($('#container')).addClass('trans');
}
var divs = $('#container div');
var x = divs.eq(Math.ceil(Math.random() * divs.length));
x[0].offsetHeight;
x.addClass('wide');
使用此JavaScript,我们会随机添加1到10个div
个元素,然后随机选择其中一个并添加wide
类。
你会注意到奇怪的JavaScript行,即x[0].offsetHeight
。这是整个行动的关键。调用offsetHeight
会在不使用setTimeout或查询CSS值的情况下触发文档重排。
与DOM相关的重排是什么:
reflow计算页面的布局。元素的回流 重新计算元素的尺寸和位置,它也是 触发了该元素的孩子,祖先和孩子的进一步回流 在DOM中出现的元素。然后它召集决赛 重绘。回流是非常昂贵的,但不幸的是它可以 容易触发。
因此,请谨慎使用这些功能。对于大多数现代浏览器来说,并没有太多关注(因为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;
}
答案 4 :(得分:2)
正如@onetrickpony所问,如果所有规则都在CSS文件中并且不应该添加到JS函数中,该怎么办。
基于Torin Finnemann的回答,只是略有改变:
添加一个额外的类,其中定义了规则:new-rules
var div = $('<div class="trans" />');
$('#container').append(div);
var div = $('<div />').addClass('trans');
$('#container').append(div);
div.height();
div.addClass('new-rules');
CSS中的具有预定义的类:
.trans.new-rules {
width: 200px;
background: yellow;
}
现在在更改CSS时不需要与JS混在一起。在new-rules
:)
答案 5 :(得分:1)
var div = $('<div />');
$('#container').append(div);
div.css('width', '20px').addClass('trans', function() {
div.css('width', '200px')
});
创建一个新的DIV元素并将'trans'类添加到该元素以触发CSS过渡