解决transition动画与display冲突的几种方法
如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的动画效果,至于更深层次的原因嘛,借我借我一双慧眼吧~
- WinRT:WebAuthenticationBroker For OAuth认证
- 你不知道的javaScript笔记(1)
- JQuery实现仿sina新浪微博新鲜事滚动
- 简单的jquery拖曵原理js特效实例
- 使用MiniProfiler调试ASP.NET MVC网站性能
- 大金主撑腰 4声母Mynt.com竟36万元结拍
- ASP.NET MVC4 Web API 堆栈将添加指定消息处理功能
- 页面copyright部分始终居于页面底部
- Hammock for REST
- 网页超过一屏时自动浮动在网页最上方的图层特效
- 关于gcc、glibc和binutils模块之间的关系
- 贝叶斯过滤算法
- 強大的jQuery Chart组件-Highcharts
- vue2.0 配置 选项 属性 方法 事件 ——速查
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- WSL 下搭建前端开发环境
- 编译安装 SeasLog 扩展
- Python3笔试实际操作基础1.md
- Python3入门学习四.md
- 通用封装函数——四则运算
- 打造自己最喜爱的 Windows10 —— 系统与软件配置优化篇
- 编译安装 IgBinary 扩展
- Python3入门学习二.md
- 编译安装 Yaml 扩展
- 一行代码不用写,就可以训练、测试、使用模型,这个star量1.5k的项目帮你做到
- 打造自己最喜爱的 Windows10 —— 纯命令安装系统篇
- Ubuntu18.04 切换 Python 版本
- Python3入门学习三.md
- Yur 主题 MarkDown 展示
- Python3入门学习一.md