$('.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...)