当transition遇到display

实现淡入淡出时,可以使用jQuery的fadeIn()/fadeOut()。使用css3的transition(过渡)也能实现。
现在我们借助transition模仿jQuery实现盒子的淡入淡出:
通过button的click事件,给div#box添加或删除classname实现效果
HTML结构:

<button>动画按钮</button>
<div class="box" id="box"></div>

过渡改变opacity属性值

css代码:

.box {
    background-color: goldenrod;
    width: 300px; height: 200px;
    margin: 100px auto;
    transition: all 1s linear;
}
.hide { 
    /* display: none; */
    opacity: 0 
}

JS代码:

var $box = $('#box');
$('button').on('click', function() {
    if($box.hasClass('hide')) {
        $box.removeClass('hide');
    }else {
        $box.addClass('hide');
    }
});

在点击按钮后可以看到淡入淡出效果,但是在css代码中解除对display属性注释后,在刷新页面,淡出淡入效果没有了。究其原因在于transition不支持display的none值与其它值之间的过渡,进而影响到盒子对opacity的过渡效果。
我们可以按照下面的步骤,实现效果:

  • 当盒子可见时,先实现opacity动画,动画结束后添加display: none
  • 当盒子不可见时,首先使其可见display: block,然后执行opacity动画。

解决办法

opacity: 0从.hide抽离。
css代码:

.hide { display: none; }
.opacity0 { opacity: 0; }

JS代码如下:

var $box = $('#box');
$('button').on('click', function() {
    if($box.hasClass('hide')) {
        $box.removeClass('hide');
        requestAnimationFrame(function() {          // 合适时机执行淡入动画
            $box.removeClass('opacity0');
        });
    }else {
        $box.addClass('opacity0');
        $box.one('transitionEnd, webkitTransitionEnd', function() {
            $box.addClass('hide');                 // 动画结束后, 隐藏盒子
        });
    }
});

参考:
http://ued.ctrip.com/blog/when-on-transition-display.html
http://www.impressivewebs.com/animate-display-block-none/
http://oli.jp/2010/css-animatable-properties/