下文转自http://www.cnblogs.com/ihardcoder/p/3859026.html
如demo(如果没有显示,请查看源地址http://jsfiddle.net/ihardcoder/HNduT/2/)所示,基本的效果是在点击“Translate”按钮后,蓝色区域透明度变为0,然后隐藏display:none;点击Reset按钮后,首先显示蓝色区域display:block,然后透明度逐渐恢复至1,代码如下: 复制代码 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后得到的效果是:蓝色区域瞬间显示出来,并没有透明度改变的过渡效果。 至于产生这种现象的原因,深层次的机制我也尚未搞明白,暂时理解为CSS3的transition过渡不支持display的改变,直接操作display会破坏transition的动画,所以在第14行通过setTimeout将opacity的transition动画与display的操作分隔。 而第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中被执行,这样便的到我们想要的过渡效果。 第二种方法,由于display对transition的破坏作用,还有另外一种方法来hack,没有错,就是setTimeout!(这货完全是js的大杀器!)代码如下: 复制代码 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的动画效果,至于更深层次的原因嘛,借我借我一双慧眼吧~
transition遇上display选项卡效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>jquery 多次点击展示不同效果</title> <script src="jquery-1.11.3.min.js"></script> <style type="text/css"> *{ margin: 0px auto; height: 0px; } .container{ width: 200px; height: 100px; margin-top: 50px; overflow: hidden; } .button_dj{ width: 350px; height: 50px; margin-top: 30px; } .disp{ line-height: 100px; text-align: center; } .dis{ width: 200px; height: 100px; background-color: aqua; } .dis_one{ width: 200px; height: 100px; background-color:antiquewhite; display: none; } .dis_two{ width: 200px; height: 100px; background-color:coral; display: none; } .dianji{ width: 100px; height: 40px; float: left; margin: 0px 5px 0px 5px; border-radius: 10px; line-height: 40px; text-align: center; background-color: #f5f5f5; } </style> </head> <body> <div class="container"> <div id="container1" class="dis disp">container1</div> <div id="container2" class="dis_one disp">container2</div> <div id="container3" class="dis_two disp">container3</div> </div> <div class="button_dj"> <div id="testbtn1" class="dianji">点击1</div> <div id="testbtn2" class="dianji">点击2</div> <div id="testbtn3" class="dianji">点击3</div> </div> </body> <script type="text/javascript"> var btn1 = $("#testbtn1"); var btn2 = $("#testbtn2"); var btn3 = $("#testbtn3"); var container1 = $("#container1"); var container2 = $("#container2"); var container3 = $("#container3"); var containers = $(".disp"); btn1.on(‘click‘, function(e) { containers.css({ "transition": "opacity 1s", "-webkit-transition": "opacity 1s", "-moz-transition": "opacity 1s", "-o-transition": "opacity 1s", "-ms-transition": "opacity 1s", "opacity": "0" }); setTimeout(function() { containers.css("display","none"); containers.css("display"); container1.css("display", "block"); container1.css("display"); container1.css({ "transition": "opacity 1s", "-webkit-transition": "opacity 1s", "-moz-transition": "opacity 1s", "-o-transition": "opacity 1s", "-ms-transition": "opacity 1s", "opacity": "1" }); }, 800); }); btn2.on(‘click‘, function(e) { containers.css({ "transition": "opacity 1s", "-webkit-transition": "opacity 1s", "-moz-transition": "opacity 1s", "-o-transition": "opacity 1s", "-ms-transition": "opacity 1s", "opacity": "0" }); setTimeout(function() { containers.css("display","none"); containers.css("display"); container2.css("display", "block"); container2.css("display"); container2.css({ "transition": "opacity 1s", "-webkit-transition": "opacity 1s", "-moz-transition": "opacity 1s", "-o-transition": "opacity 1s", "-ms-transition": "opacity 1s", "opacity": "1" }); }, 800); }); btn3.on(‘click‘, function(e) { containers.css({ "transition": "opacity 1s", "-webkit-transition": "opacity 1s", "-moz-transition": "opacity 1s", "-o-transition": "opacity 1s", "-ms-transition": "opacity 1s", "opacity": "0" }); setTimeout(function() { containers.css("display","none"); containers.css("display"); container3.css("display", "block"); container3.css("display"); container3.css({ "transition": "opacity 1s", "-webkit-transition": "opacity 1s", "-moz-transition": "opacity 1s", "-o-transition": "opacity 1s", "-ms-transition": "opacity 1s", "opacity": "1" }); }, 800); }); </script> </html>
时间: 2024-10-11 17:35:09