如demo(若是没有显示,请查看源地址http://jsfiddle.net/ihardcoder/HNduT/2/)所示,基本的效果是在点击“Translate”按钮后,蓝色区域透明度变为0,而后隐藏display:none;点击Reset按钮后,首先显示蓝色区域display:block,而后透明度逐渐恢复至1,代码以下:javascript
1 var btn1 = $("#testbtn1"); 2 var btn2 = $("#testbtn2"); 3 var container = $("#container"); 4 5 btn1.on('click', function(e) { 6 container.css({ 7 "transition": "opacity 1s", 8 "-webkit-transition": "opacity 1s", 9 "-moz-transition": "opacity 1s", 10 "-o-transition": "opacity 1s", 11 "-ms-transition": "opacity 1s", 12 "opacity": "0.1" 13 }); 14 setTimeout(function() { 15 container.css("display", "none"); 16 }, 1000); 17 }); 18 btn2.on('click', function(e) { 19 container.css("display","block"); 20 container.css("display"); 21 container.css("opacity","1"); 22 });
上述代码中第20行看起来很奇怪,可能会有人疑问这句代码的做用,事实是,若是没有这句代码,在点击Reset后获得的效果是:蓝色区域瞬间显示出来,并无透明度改变的过渡效果。css
至于产生这种现象的缘由,深层次的机制我也还没有搞明白,暂时理解为CSS3的transition过渡不支持display的改变,直接操做display会破坏transition的动画,因此在第14行经过setTimeout将opacity的transition动画与display的操做分隔。java
而第20行代码的目的,我是这样理解的,浏览器的UI线程在处理UI操做时,将多个css属性的set操做加入在同一个tick中处理(关于浏览器处理tick机制,请参考http://www.infoq.com/cn/articles/javascript-high-performance-animation-and-page-rendering?utm_source=infoq&utm_medium=popular_links_homepage),也就是说,若是不插入第20行代码,第19行和第21行的css属性set操做将会被同时执行,因此将会获得瞬间显示出来的效果;第20行代码实际上是css属性的get操做,个人理解是,若是在两个css属性的set操做中间插入get操做,UI线程在处理的时候将会按顺序执行,display的操做和opacity的操做在不一样的tick中被执行,这样便的到咱们想要的过渡效果。web
第二种方法,因为display对transition的破坏做用,还有另一种方法来hack,没有错,就是setTimeout!(这货彻底是js的大杀器!)代码以下:chrome
1 btn2.on('click', function(e) { 2 container.css("display","block"); 3 setTimeout(function(){ 4 container.css("opacity","1"); 5 },delay); 6 });
可是用setTimeout的方法有一个弊端,第5行的delay在不一样的浏览器(甚至不一样版本的相同浏览器)中须要设置不一样的数值,经本人测试,chrome35和IE10下delay=0便可,Firefox30下delay>=14.浏览器
第三种解决方法是经过window.requestAnimationFram来实现,代码以下:测试
1 btn2.on('click', function(e) { 2 container.css("display","block"); 3 requestanimationframe(function(){ 4 container.css("opacity","1"); 5 }); 6 });
requestAnimationFram的做用是将opacity的操做推迟到下一个tick中处理,从而将display的操做分隔开,基本原理与setTimeout相同。动画
另外,关于display为什么会破坏transition动画,目前本人仍未找到相关资料来证实其内部机制,个人我的理解是,display的操做会触发浏览器的reflow操做,而transition支持的效果只是触发浏览器的repaint操做,回到上面的demo,若是咱们经过visibility属性来控制显示与隐藏,则不会破坏transition的效果。因此,能够暂时这么认为:reflow与repaint的混合会破坏transition的动画效果,至于更深层次的缘由嘛,借我借我一双慧眼吧~spa