博客
关于我
解决transition动画与display冲突的几种方法
阅读量:661 次
发布时间:2019-03-16

本文共 2350 字,大约阅读时间需要 7 分钟。

如(如果没有显示,请查看源地址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的动画效果,至于更深层次的原因嘛,借我借我一双慧眼吧~

转载地址:http://fndqz.baihongyu.com/

你可能感兴趣的文章
Kali-linux:nmap命令
查看>>
s3c2440 ads程序移植到keil中(一) 初步完成
查看>>
工程经济—建设工程定额
查看>>
工程经济—工程量清单编制
查看>>
1Z204050、施工质量不合格的处理
查看>>
【字节网盘】九款超好看不同页面404源码
查看>>
两款404页面自动跳转源码html
查看>>
二改广告横幅在线制作源码 美化版
查看>>
服饰贴图定制小程序V1.2.4安装更新一体包+小程序前端
查看>>
一款好看新颖的404页面源码
查看>>
创意沙雕黑色蝙蝠侠/小丑动态404页面源码
查看>>
使用Mac OS X如何开启和配置防火墙
查看>>
格式化Mac硬盘---DoYourData Super Eraser安全、快速
查看>>
MacOS磁盘分区出错的解决办法
查看>>
MacOS 应对系统无响应的方法
查看>>
Mac隐藏辅助功能|自定义苹果Mac显示器
查看>>
ActivityNotFoundException异常错误
查看>>
Error merging: refusing to merge unrelated histories
查看>>
git远程仓库切换
查看>>
带照片捕捉功能的ESP32-CAM PIR运动检测器
查看>>