css不能在display:none和display:block之間進(jìn)行動(dòng)畫(huà),并且也不能在height:0和height:auto之間進(jìn)行動(dòng)畫(huà)。這里我研究了一下在display:none和display:block之間進(jìn)行動(dòng)畫(huà)的解決方案,記錄下來(lái)供以后開(kāi)發(fā)時(shí)參考,相信對(duì)其他人也有用。
我的理解是這樣的:由于display:none會(huì)引起頁(yè)面的重繪事件,所以它是一個(gè)異步的延時(shí)事件,所以瀏覽器其實(shí)會(huì)先解析animate的代碼,然后再執(zhí)行display:none。
這樣就引發(fā)了一個(gè)問(wèn)題:如果我們要設(shè)置類(lèi)似淡入淡出的效果怎么辦?就是讓元素在消失/出現(xiàn)的同時(shí)產(chǎn)生動(dòng)畫(huà)怎么辦?這里我研究了2個(gè)解決方案。
不利用display:none,而是利用它的替代方式:
opacity: 0;visibility: hidden;
但是這樣會(huì)占據(jù)空間。如果不想占據(jù)空間的話,只能使用絕對(duì)定位,把元素獨(dú)立出去。這個(gè)時(shí)候會(huì)有一個(gè)層疊問(wèn)題,所以需要搭配z-index控制層疊關(guān)系使它出現(xiàn)或者消失。
示例如下:
//自身css效果 .animate { position: absolute; top: 0; left: 0; transition: 1s; opacity: 0; visibility: hidden; z-index: 0; } //出現(xiàn)時(shí)的效果 .cur { opacity: 1; visibility: visible; z-index: 10; }
jquery里面也有淡入淡出的方法,它是怎么實(shí)現(xiàn)的呢?通過(guò)查資料可以知道,它是通過(guò)deferred對(duì)象通過(guò)延時(shí)display: none來(lái)實(shí)現(xiàn)的。好處是能夠適用于出現(xiàn)時(shí)占據(jù)空間,消失時(shí)又不占據(jù)空間的情況。實(shí)例如下:
//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是動(dòng)畫(huà)時(shí)間。 }
我還試過(guò)用transitionend事件,window.requestanimationframe來(lái)實(shí)現(xiàn),但是都或多或少的有副作用。
另外總結(jié)一下:
如果消失前后都需要占據(jù)空間,則用visiblity。
如果消失前后都不需要占據(jù)空間,則用絕對(duì)定位和visiblity。
如果消失前需要占據(jù)空間但是消失后不需要占據(jù)空間,則用timeout和visiblity。
DISPLAY:NONE的元素如何觸發(fā)過(guò)渡動(dòng)畫(huà)?
display:none的元素更改為display:block為何不可以和其他屬性修改一樣觸發(fā)動(dòng)畫(huà)呢?
這是因?yàn)閐isplay屬性剛開(kāi)始是none,所以還沒(méi)有創(chuàng)建,改為block之后需要等待js渲染隊(duì)列更新
但是transition屬性在一開(kāi)始就有了,所以transform改變?cè)氐臅r(shí)候并沒(méi)有觸發(fā)動(dòng)畫(huà)
解決方法:讓元素獲取dom.offsetHeight,觸發(fā)js渲染隊(duì)列更新,讓元素先展示出來(lái)。
<!DOCTYPE html> <html> <head> <title>測(cè)試</title> <style type="text/css"> html, body, div, span, h1, h2, h3, h4, h5, h6, p a, img, ol, ul, li { margin:0;padding:0;border:0;outline:0; } ul, li{ list-style-type: none; } .father{ border: 1px solid black; height: 300px; width: 1000px; } .one{ background-color: red; height: 300px; width: 200px; display: none; transition: 1s ease; } </style> </head> <body> <div class="father"> <div class="one"></div> <button type="button" onclick="change()">測(cè)試</button> </div> <script> function change(){ var one = document.getElementsByClassName('one')[0]; one.style.display='block'; // 區(qū)別在于有沒(méi)有獲取one.offsetHeight console.log(one.offsetHeight); one.style.transform='translateX(200px)'; } </script> </body> </html>
用opacity實(shí)現(xiàn)淡入淡出的效果。噢!good!一切正常
<!DOCTYPE html> <html> <meta charset="uft-8"> <head> <style> .div1{ background: red; } .div2 { width:100px; height:100px; background:blue; transition:opacity 2s; -moz-transition:opacity 2s; /* Firefox 4 */ -webkit-transition:opacity 2s; /* Safari and Chrome */ -o-transition:opacity 2s; /* Opera */ opacity: 0; } .div1:hover .div2 { opacity:1; } </style> </head> <body> <div class="div1"> <p>請(qǐng)移動(dòng)到紅色div上</p> <div class="div2"></div> </div> </body> </html>
或者用animation,在keyframe中寫(xiě)也一樣。這里就不寫(xiě)出代碼了
但是難免我們會(huì)遇到這樣的需求,也一定會(huì)遇到: 我們都知道opacity:0的時(shí)候,其實(shí)他還是占頁(yè)面空間的,他會(huì)遮擋到他下面的層(不是視覺(jué)上)。而且綁定在他上面的一些onclick事件之類(lèi)的,也同樣會(huì)發(fā)生。 這時(shí)候我們想在opacity:0的時(shí)候,把他隱藏掉,用display: none。 好,那我們稍微在css中加幾句,變成
.div1{ background: red; } .div2 { width:100px; height:100px; background:blue; transition:opacity 2s; -moz-transition:opacity 2s; /* Firefox 4 */ -webkit-transition:opacity 2s; /* Safari and Chrome */ -o-transition:opacity 2s; /* Opera */ opacity: 0; display: none; } .div1:hover .div2 { opacity:1; display:block }
打開(kāi)瀏覽器看一下效果先。 我擦。。。。淡入淡出的效果全沒(méi)了怎么回事。。。這簡(jiǎn)直是破壞性的作用,這也是之前做動(dòng)畫(huà)過(guò)程中遇到的大坑
聰明的碼農(nóng)們當(dāng)然有辦法來(lái)解決這種情況。 大家都知道visibility的效果其實(shí)跟 display 在一定程度上相似, 當(dāng)然是一定程度上。 那為什么說(shuō)只是一定程度上相似呢,因?yàn)樗匀皇钦伎臻g的,那么這時(shí)候看官一定會(huì)說(shuō),這么用跟opacity壓根沒(méi)區(qū)別呀
但聰明的碼農(nóng)們一定又想到,這時(shí)候,他是不會(huì)遮擋到下面的層的,也就是說(shuō) 他跟opacity這樣的存在不同,onclick等事件是不會(huì)發(fā)生的。
我們來(lái)說(shuō)下visibility, 常用到的是visible和 hidden 兩個(gè)值。但也可以是數(shù)值, 等于0時(shí)相當(dāng)于hidden,而只要大于0時(shí),visibility就為visible。那我們利用這點(diǎn)。
.div1{ background: red; } .div2 { width:100px; height:100px; background:blue; transition:all 2s; -moz-transition:all 2s; /* Firefox 4 */ -webkit-transition:all 2s; /* Safari and Chrome */ -o-transition:all 2s; /* Opera */ visibility: hidden } .div1:hover .div2 { visibility: visible }
瀏覽一下,會(huì)發(fā)現(xiàn),這時(shí)候是會(huì)有延時(shí)隱藏的效果的。很好,又發(fā)現(xiàn)新東西了
那漸變的效果怎么辦。。。。
聰明的碼農(nóng)們又想起了opacity 。。。結(jié)合起來(lái)用會(huì)怎么用呢
.div1{ background: red; } .div2 { width:100px; height:100px; background:blue; transition:all 2s; -moz-transition:all 2s; /* Firefox 4 */ -webkit-transition:all 2s; /* Safari and Chrome */ -o-transition:all 2s; /* Opera */ visibility: hidden; opacity: 0 } .div1:hover .div2 { visibility: visible; opacity: 1 }
瀏覽下先。。。。!?。?!一切正常了
其實(shí),visibility會(huì)在opacity生效后再應(yīng)用。比如隱藏時(shí),先opacity變?yōu)?,再應(yīng)用了visibility:hidden 這時(shí)候就隱藏起來(lái)了,相關(guān)的事件也不會(huì)發(fā)生。 看來(lái)display:none這時(shí)候被拋棄了啊
當(dāng)然,有人會(huì)說(shuō)visibility:hidden始終是占著頁(yè)面空間的,display能夠減少頁(yè)面的repaint,還是要用display:none怎么做呢
聰明的碼農(nóng)又想到了: 先把display變成block 然后延遲transition動(dòng)畫(huà)的執(zhí)行
當(dāng)然啦 這就需要用到JS了
以上就是css3 動(dòng)畫(huà)與display:none沖突的解決方法!
如對(duì)本文有疑問(wèn),請(qǐng)?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會(huì)為你解答!! 點(diǎn)擊進(jìn)入論壇