当transition遇上display(选项卡效果)

下文转自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

当transition遇上display(选项卡效果)的相关文章

CSS3及JS简单实现选项卡效果(适配手机端和pc端)

想要适配手机端和pc端,有几种简单的方法,本人使用的是百分比分配的方法. *{ padding: 0; margin: 0; } body,html{ width: 100%; height: 100%; overflow: hidden; } #bottom_box{ width: 100%; height: 50px; background-color: #eee; display: flex; //这是flex布局,父元素设置为flex,子元素设置几等份就是分成几等份 position:

语音导航的tab选项卡效果

前端开发whqet,csdn,王海庆,whqet,前端开发专家 ladies and 乡亲们,程序员同志们,周末仍然坚守工作岗位,或者学习不辍的童鞋们,福音来了. 语音识别高不高端.难不难? 今天给大家推荐一个简单易用的js实现的语音识别框架annyang,然后一个案例示范使用. 在线案例,下载收藏. annyang是一个能够实现语音识别的js类库,小巧易用(仅仅2k),兼容中文.接下来我们看看怎么使用. 首先导入该annyang库,可以使用CDN的方式,也可以下载来使用. <!--下载到本地使

Javascript进阶篇——总结--DOM案例+选项卡效果

断断续续的把慕课的JavaScript基础和进阶看完了,期间不怎么应用有的都忘记了,接下来多开始写些效果,进行实际应用. 制作一个表格,显示班级的学生信息. 1. 鼠标移到不同行上时背景色改为色值为 #f2f2f2,移开鼠标时则恢复为原背景色 #fff 2. 点击添加按钮,能动态在最后添加一行 3. 点击删除按钮,则删除当前行 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title> new document </ti

css3 transition属性实现3d动画效果

transition属性是一个很强大的3d动画属性,我动手试了一下,很多在网上很火的网页动画都可以用这个属性实现,只能说这个属性是在是太强大啦,本人在学习次属性之后才知道自己对css3的认识还是偏少,现在我给大家介绍并实际实现下该属性. transition字面意思是变迁.变换.过度的意思,所以transition属性也离不开这个大致意思,其中该属性中的重要属性是: transition-property:指定过度的元素; 如:transition-property:background,就是指

解决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 contai

渗透场景篇--当XSS遇上CSRF

你是否有过这样的经历,你发现了一个xss,但是貌似只能叉自己,输出点只有自己可以看见.这个时候,你会觉得这个xss很鸡肋,当你就此忽略这个漏洞的时候,你可能丢掉一个发出组合技能的机会.    今天我们来介绍一个场景,当xss遇上csrf的时候,是否能打出一套漂亮的组合技能. 实验环境:     ZvulDirll[请用下面我简单修改过的版本]     下载地址:在文章最后面 一.安装:0x00:解压ZVulDrill压缩包,将其放在www目录下,也就是你的网站根目录.0x01.编辑ZVulDri

javascript 一个页面多个tab选项卡效果

<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>javascript 一个页面多个tab选项卡效果</title> <script> var tab=function(id,event){ var oDiv=document.getElementById(id); var oBtn=oDiv.getElementsByTagName(

选项卡效果

例子一. 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>选项卡效果</title> 6 <script type="text/javascript" src="jquery.min.js"></script> 7 <

WPF实现选项卡效果(1)——使用AvalonDock

简介 公司最近一个项目,软件采用WPF开发,需要实现类似于VS的选项卡(或者是浏览器的选项卡)效果.搜寻诸多资料后,发现很多同仁推荐AvalonDock这款开源控件.在其官方地址下载源码和Demo后,对其进行了初步的研究,初步实现了预期效果. AvalonDocking的结构树 在下载的Demo中,我们可以发现AvalonDock的可视化结构树如下: <avalon:DockingManager x:Name="dockingManager"> <avalon:Lay