css3 動畫與display:none沖突的解決方案


概述

css不能在display:none和display:block之間進行動畫,並且也不能在height:0和height:auto之間進行動畫。這里我研究了一下在display:none和display:block之間進行動畫的解決方案,記錄下來供以后開發時參考,相信對其他人也有用。

參考資料:
CSS3 Animation and Display None
解決transition動畫與display沖突的幾種方法

機制

我的理解是這樣的:由於display:none會引起頁面的重繪事件,所以它是一個異步的延時事件,所以瀏覽器其實會先解析animate的代碼,然后再執行display:none。

這樣就引發了一個問題:如果我們要設置類似淡入淡出的效果怎么辦?就是讓元素在消失/出現的同時產生動畫怎么辦?這里我研究了2個解決方案。

利用絕對定位和visiblity

不利用display:none,而是利用它的替代方式:

opacity: 0;
visibility: hidden;

但是這樣會占據空間。如果不想占據空間的話,只能使用絕對定位,把元素獨立出去。這個時候會有一個層疊問題,所以需要搭配z-index控制層疊關系使它出現或者消失。

示例如下:

//自身css效果
.animate {
    position: absolute;
    top: 0;
    left: 0;

    transition: 1s;
    opacity: 0;
    visibility: hidden;
    z-index: 0;
}

//出現時的效果
.cur {
    opacity: 1;
    visibility: visible;
    z-index: 10;
}

利用timeout

jquery里面也有淡入淡出的方法,它是怎么實現的呢?通過查資料可以知道,它是通過deferred對象通過延時display: none來實現的。好處是能夠適用於出現時占據空間,消失時又不占據空間的情況。實例如下:

//css
.div {
    display: none;
}
.div-animate1 {
    display: block;
    visibility: hidden;
    opacity: 0;
    transform: translate3d(100px, 0, 0);
    transition: 1s;
}
.div-animate2 {
    visibility: visible;
    opacity: 1;
    transform: translate3d(0, 0, 0);
}

//js
function divAnimate1($div, divClass1, divClass2) {
    $div.addClass(divClass1);

    setTimeout(function(){
        $div.addClass(divClass2);
    });
}
function divAnimate2($div, divClass1, divClass2) {
    $div.removeClass(divClass2);

    setTimeout(function(){
        $div.removeClass(divClass1);
    }, 1000); //1s是動畫時間。
}

其它

我還試過用transitionend事件,window.requestanimationframe來實現,但是都或多或少的有副作用。

另外總結一下:

  1. 如果消失前后都需要占據空間,則用visiblity。
  2. 如果消失前后都不需要占據空間,則用絕對定位和visiblity。
  3. 如果消失前需要占據空間但是消失后不需要占據空間,則用timeout和visiblity。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM