CSS转换不会被解雇

时间:2011-08-15 18:43:29

标签: jquery css css3 transitions css-transitions

我正在创建一个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;
}

我在这里弄得一团糟,还是“一气呵成”并不是应该做的事情?

非常感谢所有帮助。

6 个答案:

答案 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事件将触发

example jsfiddle

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()功能

example jsfiddle

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。这不是引起回流的唯一方法。


Link to a fiddle

<强>的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:)

的CSS文件中更改它

http://jsfiddle.net/FYPpt/201/

答案 5 :(得分:1)

var div = $('<div />');

$('#container').append(div);

div.css('width', '20px').addClass('trans', function() {
   div.css('width', '200px') 
});

创建一个新的DIV元素并将'trans'类添加到该元素以触发CSS过渡