demo(如果没有显示,请查看源地址http://jsfiddle.net/ihardcoder/HNduT/2/)所示,基本的效果是在点击“Translate”按钮后,蓝色区域透明度变为0,然后隐藏display:none;点击Reset按钮后,首先显示蓝色区域display:block,然后透明度逐渐恢复至1,代码如下:

 var btn1 = $("#testbtn1");
var btn2 = $("#testbtn2");
var container = $("#container"); btn1.on('click', function(e) {
container.css({
"transition": "opacity 1s",
"-webkit-transition": "opacity 1s",
"-moz-transition": "opacity 1s",
"-o-transition": "opacity 1s",
"-ms-transition": "opacity 1s",
"opacity": "0.1"
});
setTimeout(function() {
container.css("display", "none");
}, 1000);
});
btn2.on('click', function(e) {
container.css("display","block");
container.css("display");
container.css("opacity","1");
});

上述代码中第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的大杀器!)代码如下:

  btn2.on('click', function(e) {
container.css("display","block");
setTimeout(function(){
container.css("opacity","1");
},delay);
});

但是用setTimeout的方法有一个弊端,第5行的delay在不同的浏览器(甚至不同版本的相同浏览器)中需要设置不同的数值,经本人测试,chrome35和IE10下delay=0即可,Firefox30下delay>=14.

第三种解决方法是通过window.requestAnimationFram来实现,代码如下:

 btn2.on('click', function(e) {
container.css("display","block");
requestanimationframe(function(){
container.css("opacity","1");
});
});

requestAnimationFram的作用是将opacity的操作推迟到下一个tick中处理,从而将display的操作分隔开,基本原理与setTimeout相同。

另外,关于display为何会破坏transition动画,目前本人仍未找到相关资料来证明其内部机制,我的个人理解是,display的操作会触发浏览器的reflow操作,而transition支持的效果只是触发浏览器的repaint操作,回到上面的demo,如果我们通过visibility属性来控制显示与隐藏,则不会破坏transition的效果。所以,可以暂时这么认为:reflow与repaint的混合会破坏transition的动画效果,至于更深层次的原因嘛,借我借我一双慧眼吧~

解决transition动画与display冲突的几种方法的更多相关文章

  1. java 解决Hash(散列)冲突的四种方法--开放定址法(线性探测,二次探测,伪随机探测)、链地址法、再哈希、建立公共溢出区

    java 解决Hash(散列)冲突的四种方法--开放定址法(线性探测,二次探测,伪随机探测).链地址法.再哈希.建立公共溢出区 标签: hashmaphashmap冲突解决冲突的方法冲突 2016-0 ...

  2. Hash算法解决冲突的四种方法

    Hash算法解决冲突的方法一般有以下几种常用的解决方法 1, 开放定址法: 所谓的开放定址法就是一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入 公式为 ...

  3. Maven 知识点总结以及解决jar报冲突的几种方法

    1.常见的命令 Compile Test Package Install Deploy Clean 2.坐标的书写规范 groupId 公司或组织域名的倒序 artifactId 项目名或模块名 ve ...

  4. 哈希表(一):解决hash冲突的几种方法

    (一)线性探测法 线性探测法是最简单的处理冲突的方法. (1)插入元素:插入元素时,如果发生冲突,算法将从该槽位向后遍历哈希表,直到找到表中的下一个空槽,并将该值放入到空槽当中. (2)查找元素:查找 ...

  5. 【转载】解决繁体、日文游戏乱码的五种方法 转载自:http://tieba.baidu.com/p/488627981

    方法1:转换区域 开始——设置——控制面板——区域和语言选项——分别选择“高级”和“区域选项”标签——在其下拉框中都选择“日语”(或“日本”)(选项有点多,慢慢找)——重启后即可生效. *某影注:日语 ...

  6. 20190627_解决ADB的device offline问题的两种方法

    故障现象: error: device offline 故障解决: 第一种方法: C:\Users\WXY\Desktop\XY\adb>adb nodaemon server cannot b ...

  7. Hash(散列函数)简单应用引出解决散列冲突的四种方法

    商店允许顾客通过电话订购商品,并在几天后上门自取.商店的数据库使用客户的电话号码作为其检索的关键字(客户知道自己的电话号码,而且这些电话关键字几乎是唯一的).如何组织商店的数据库,以允许更加高效的进行 ...

  8. TortoiseGit 解决冲突的两种方法

    一.冲突发生原因: 用户A 有新提交 用户B 没有pull, 写新代码 ,pull , 提示有冲突   Solution: 1: stash save(把自己的代码隐藏存起来) -> 重新pul ...

  9. JavaScript解决命名冲突的一种方法

    过程化编码 过程化编码, 表现为 定义若干函数,然后调用定义函数, 随着页面交互逻辑变化, 从简单到复杂, 定义的所有函数.和变量 都挂在 window对象上, window对象 编程者子自定义变量名 ...

随机推荐

  1. 文件操作命令(TYPE)

    type 命令: // 描述: 显示文本文件的内容. 但不能进行修改. // 语法: type [<Drive>:][<Path>]<FileName> // 参数 ...

  2. SOP - Validation

    Table of Contents目录表1 Roles and Responsibilities related to validation与验证相关的1个角色和职责2 Introduction2引言 ...

  3. SHELL脚本学习-定时检查Oracle alert日志并发送mail

    对于DBA来说,检查alert日志是日常工作.告警日志日积月累往往很大,而且每次在服务器上查看或者下载到目标主机查看都十分不方便. 为了方便,以下做出两种情况:(其他情况类推) 第一场景:每天早上上班 ...

  4. spring+struts+hibernate整合

    spring整合: 1:添加配置文件和相应的spring jar包(记得一定要加上commons-logging的jar包,有坑****) 2:创建date对象,如果成功则spring的环境ok

  5. android 开发案列汇总

    Android 开发案列汇总 1.一款轻量级的便签软件,界面简单干净,绿色无广告.支持部分Markdown语法,可以方便地输入和预览Markdown文本,并且生成长微博图片保存到本地. 文章来源:ht ...

  6. Ubuntu 16.04 安装PCL库以及测试

    参考链接:https://blog.csdn.net/dantengc/article/details/78446600 参考博客,官网一直安装不成功,后来参照一篇博客终于安装成功了,记录如下. 1. ...

  7. 别人的Linux私房菜(17)进程管理与SELinux初探

    程序在磁盘中,通过用户的执行触发.触发事件时,加载到内存,系统将它定义成进程,给予进程PID,根据触发的用户和属性,给予PID合适的权限. PID和登陆者的UID/GID有关.父进程衍生出来的进程为子 ...

  8. tensorflow学习之(十一)将python代码写入文件

    #save to file import tensorflow as tf import numpy as np ##(1)Save to file 把相关变量存储到文件中 #remember to ...

  9. 通过PRINT过程制作报表

    通过PRINT过程制作报表 PRINT过程是SAS中用于输出数据集内容的最简单常用的过程,它可将选择的观测和字段以简单的矩形表格形式输出. 1.1 制作简单报表 使用PRINT过程最简单的语法形式如下 ...

  10. Python_day7

    sys模块 import sys def _add(a, b): return a + b def _sub(a, b): return a - b def _mul(a, b): return a ...