首页 > css3 动画问题

css3 动画问题

$('.dom').css('transition', 'transform 0s linear');

$('.dom').css('transform', 'translateX(100px)');

$('.dom').css('transition', 'transform 0.3s linear');

这样写的意思是,先解除动画,然后移动100px,然后再绑定动画,可是这样三句连续写的话,还是会产生动画。而

把第三句

setTimeout(function({
              $('.dom').css('transition', 'transform 0.3s linear');
          }),0)

像这样放里面就是可以实现我要的效果的。
当然实现我想要的效果,有更好的办法,我只是想问为什么会有上面的情况!

上面的提问有问题,其实最开始的那3端代码是不会产生动画的。
现在还有一个新的问题- -

比如

.dom{
    width:100px;
    height:100px;
    transition: height 1s linear;
}
<script>
    $('.dom').css('height','200px');
</script>

这样操作是没办法产生动画的,只有把这个高度的变化操作放在一个异步操作内,比如定时器,动作的回调函数之内,或者hover。这又是为什么呢? 样式的渲染会整合js和css内的样式修改代码吗?


首先JS是单线程我们都知道,然后这里的CSS设置要生效需要通过浏览器DOM渲染线程来完成,所以只有等当前的代码栈执行完毕后,才会去更新DOM让这里的CSS效果生效。那么理所当然拿了第三句话设置的transition的值

你可以测试一下,下面的代码并不是立刻让背景被红色,而是必须等到for循环跑完,浏览器才有空闲去做DOM的update工作:

$('.dom').css('background', 'red');
for(var i = 0; i < 1000000; i++) Math.sin(i); 

类似的:

$('.dom').css('transform', 'translateX(100px)');
$('.dom').css('transition', 'transform 0.3s linear');
for(var i = 0; i < 1000000; i++) Math.sin(i); 

回答你的新问题

先说结论:动画有没有,取决于设置transition和设置目标值(这里的是height=‘200px')是否在不同的代码栈中完成。如果是,则没有动画,如果不是,则有动画。

你的第一个问题诠释了这个结论,关于第二个问题,以下是我的测试和分析(chrome49下测试)。为了排除jQuery的影响,我使用原生DOM API

ABCD四个Case。唯一的区别是

如何加载外部JS脚本,在目标DOM元素之前,之后,同步加载还是异步加载。

测试结果是:只要目标DOM元素(<div id="dom"></div>)和设置目标transition属性的JS代码(document.getElementById('dom').style.height = '100px';)之间有外部JS的同步加载,就会出现动画。

原因是:解析DOM和执行内嵌JS可以看作在同一个代码栈内完成,同步(默认)加载外部脚本会阻塞后面的DOM解析,也其实中断了之前的代码栈,只有外部脚本返回,才用新的代码栈接着后面的解析(可以想象为ajax的回调)。

Case A:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test</title>
    <style>
        #dom {
            width: 100px;
            height: 50px;
            background: red;
            transition: height 1s linear;
        }
    </style>
</head>
<body>
    <!-- 没有加载外部脚本,没有动画 -->
    <div id="dom"></div>
    <script>
        document.getElementById('dom').style.height = '100px';
    </script>
</body>
</html>

Case B:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test</title>
    <style>
        #dom {
            width: 100px;
            height: 50px;
            background: red;
            transition: height 1s linear;
        }
    </style>
</head>
<body>
    <!-- 目标DOM之前加载外部脚本,没有动画 -->
    <script type="text/javascript" src="temp.js"></script>
    <div id="dom"></div>
    <script>
        document.getElementById('dom').style.height = '100px';
    </script>
</body>
</html>

Case C:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test</title>
    <style>
        #dom {
            width: 100px;
            height: 50px;
            background: red;
            transition: height 1s linear;
        }
    </style>
</head>
<body>
    <div id="dom"></div>
    <!-- 目标DOM之后加载外部脚本,有动画 -->
    <script type="text/javascript" src="temp.js"></script>
    <script>
        document.getElementById('dom').style.height = '100px';
    </script>
</body>
</html>

Case D:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test</title>
    <style>
        #dom {
            width: 100px;
            height: 50px;
            background: red;
            transition: height 1s linear;
        }
    </style>
</head>
<body>
    <div id="dom"></div>
    <!-- 目标DOM之后加载外部脚本(异步加载),没有动画 -->
    <script type="text/javascript" src="temp.js" defer></script>
    <script>
        document.getElementById('dom').style.height = '100px';
    </script>
</body>
</html>

(对了,以上纯属个人对浏览器行为义正严辞的YY...)

【热门文章】
【热门文章】