摘要:用來定義元素兩種狀態(tài)之間的過渡。到目前為止,我們利用完全模擬了第一部分我們使用實現(xiàn)的功能,而且看上去更簡潔。附上利用來實現(xiàn)該方案的代碼用于參考。由于代碼效果時好時壞,猜測可能與的容器相關(guān)。
背景
在日常的項目開發(fā)中,我們會很經(jīng)常的遇見如下的需求:
在瀏覽器頁面中,當(dāng)鼠標(biāo)移動到某個部分后,另一個部分在延遲若干時間后出現(xiàn)
在鼠標(biāo)移除該區(qū)域后,另一部分也在延遲若干時間后消失
我相信這是一個很常見的一個需求,有很多種方式能夠?qū)崿F(xiàn),但是,其實現(xiàn)方式的原理各不相同,也有利有弊。
實現(xiàn)方案 CSS在CSS中,有一個偽類hover也能夠監(jiān)聽鼠標(biāo)移動到某個元素上面,因此我們也可以利用CSS來實現(xiàn)我們剛剛的功能。
我們需要使用的是CSS3中的新特性:transition。
transition是一個簡寫屬性,可設(shè)置transition-property, transition-duration, transition-timing-function, transition-delay。 transition用來定義元素兩種狀態(tài)之間的過渡。不同狀態(tài)可以用 pseudo-classes 定義,比如 :hover 、:active或使用JavaScript設(shè)置。
該屬性第一個值為需要變化的屬性值,第二個值為其持續(xù)時間,第三個值為變化方式,第四個值為其延時。該屬性指定的值只要指定的屬性有任何變化,都會觸發(fā)該屬性。即在從該樣式到其他樣式,以及其他樣式回到該樣式時都會產(chǎn)生效果。例如:
transition:opacity 1s linear 1s;
具體介紹請看MDN官方介紹。
現(xiàn)在,讓我們用transition屬性來實現(xiàn)上面的功能。簡單點如下所示:
//HTML文件Title //Sass文件 #container { display: inline-block; #div1 { width: 100px; height: 100px; background-color: #000; } #div2 { visibility: hidden; opacity: 0; width: 100px; height: 100px; background-color: #F00; transition-delay: 0.5s; } &:hover { #div2 { visibility: visible; opacity: 1; } } }
通過在CSS中添加transition-duration,我們可以實現(xiàn)延時顯示的目的。并且,我們不需要自己去清除定時器,而由瀏覽器來判別。
在此,我們?yōu)槭裁床挥?b>display屬性呢,因為在display改變時,transition并不會生效。
那我們?yōu)槭裁葱枰谑褂昧?b>opacity屬性的時候同時使用visibility屬性呢。因為opacity屬性只是讓元素變得透明,而不會讓元素消失。如果不加速visibility屬性的話,那元素變透明后仍然可以點擊,那么會出現(xiàn)一些奇怪的影響。
到目前為止,我們利用CSS完全模擬了第一部分我們使用JavaScript實現(xiàn)的功能,而且看上去更簡潔。那么,下面我們來講一些更加復(fù)雜的功能有助于大家理解transition。
transition進(jìn)階現(xiàn)在我們需要在鼠標(biāo)移動上去后,出現(xiàn)一個漸變的效果,讓另一框慢慢出現(xiàn),同時在鼠標(biāo)移出的時候也有漸變消失的效果,那么我們就需要來使用一下transition的另外幾個屬性。
在上面的代碼中稍加改動,就能夠得到我們需要的效果。
transition: opacity 0.5s linear;
這樣的話,在鼠標(biāo)移入的時候,會有一個漸變的效果。但是,問題也出現(xiàn)了,在鼠標(biāo)移出的時候,div2立馬就消失了。讓我們來分析一下鼠標(biāo)移入和移出時的效果。
當(dāng)鼠標(biāo)移入時:
鼠標(biāo)移入div1元素
觸發(fā)了hover事件,div2的visibility屬性變?yōu)?b>visible
transition屬性讓opacity屬性從0變?yōu)?
而當(dāng)鼠標(biāo)移出時:
鼠標(biāo)移出div1元素
hover事件停止觸發(fā),div2的visibility屬性變?yōu)?b>hidden
transition屬性讓opacity屬性從1變?yōu)?
根據(jù)上面的情況我們知道,當(dāng)hover事件結(jié)束后,visibility屬性立馬就變成了hidden了,因此后面的動畫效果就無法看到了。
那么如果我們?yōu)?b>visibility屬性也加上延時呢,能不能夠達(dá)到我們的目標(biāo),讓我們來看一下效果。
transition: visibility 0s linear 0.5s, opacity 0.5s linear;
代碼改動為如上情況后,我們會發(fā)現(xiàn),當(dāng)鼠標(biāo)移出的時候,能夠看到動畫效果。但是當(dāng)鼠標(biāo)移入時,動畫效果消失了,現(xiàn)在再讓我們來分析下為什么會出現(xiàn)這個情況。
當(dāng)時鼠標(biāo)移入時:
鼠標(biāo)移入div1元素
觸發(fā)hover事件
transition屬性讓opacity屬性從0變?yōu)?
visibility屬性變?yōu)?b>visible
當(dāng)鼠標(biāo)移出時:
鼠標(biāo)移出div1元素
hover事件停止觸發(fā)
transition屬性讓opacity屬性從1變?yōu)?
visibility屬性變?yōu)?b>hidden
從上面的分析我們可以知道,因為visibility屬性為不連續(xù)變化屬性,因此在transition中只有transition-delay對該屬性產(chǎn)生了效果。所以visibility屬性延時了0.5s執(zhí)行,導(dǎo)致了在鼠標(biāo)移入時看不到效果。
那么,我們有沒有辦法同時在鼠標(biāo)移入和移出的時候同時看到動畫效果呢。需要達(dá)到這個目的,其實換一個思路立馬就能夠解決。我們不只需要在hover事件中重置這個延時,將其重新指定為0,馬上就能夠達(dá)到我們想要的效果。具體示例代碼如下:
#container { display: inline-block; #div1 { width: 100px; height: 100px; background-color: #000; } #div2 { visibility: hidden; opacity: 0; width: 100px; height: 100px; background-color: #F00; transition: visibility 0s linear 0.5s, opacity 0.5s linear; } &:hover { #div2 { visibility: visible; opacity: 1; transition-delay: 0s; } } }
那么現(xiàn)在讓我們來分析下為什么這么寫能夠達(dá)到我們需要的效果。
當(dāng)鼠標(biāo)移入時:
鼠標(biāo)移入div1
hover事件觸發(fā),重新指定transition屬性的transition-delay為0s,visibility屬性由hidden立馬變成visible
transition屬性讓opacity屬性由0變?yōu)?
當(dāng)鼠標(biāo)移出時:
鼠標(biāo)移出div1
hover事件停止觸發(fā),transition延時恢復(fù)到0.5s,因此visibility屬性不會馬上觸發(fā)
transition屬性讓opacity屬性由1變?yōu)?
visibility屬性由visible變?yōu)?b>hidden
我們通過一個很簡單巧妙的方法,通過改變transition-delay,從而讓visibility屬性立即執(zhí)行,達(dá)到了我們需要的效果。
JavaScript附上利用JS來實現(xiàn)該方案的代碼用于參考。這個其實應(yīng)該是大部分人會想到的方法,利用mouseover或者click事件來進(jìn)行事件的監(jiān)聽,利用setTimeout來進(jìn)行延時處理,例如這樣:
Title
但是上面這個代碼有一個比較嚴(yán)重的問題,就是當(dāng)鼠標(biāo)兩次移動上去的間隔小于500ms時,上一次的setTimeout的代碼還是會觸發(fā),因此會看到一次閃動的效果。
因此,我們需要在檢測到兩次間隔小于500ms時,清除掉上次的setTimeout的代碼。所以,改動代碼如下(注:如有表現(xiàn)與描述不一致請看文章末尾說明):
div1.addEventListener("mouseover", function() { clearTimeout(handle); setTimeout(function() { div2.style.display = "block"; }, 500); }); var handle = 0; div1.addEventListener("mouseleave", function() { handle = setTimeout(function() { div2.style.display = "none"; }, 500); });
調(diào)整為上述代碼之后,基本可以滿足我們的需求。后續(xù)如果需要添加動畫之類的操作,也只需要繼續(xù)像代碼添加相關(guān)邏輯即可,在此就不再演示。
總結(jié)在需求開發(fā)的過程中,遇到了這個問題。最開始用JavaScript實現(xiàn),開發(fā)起來比較復(fù)雜,容易與業(yè)務(wù)邏輯代碼混在一起不好維護(hù)。通過CSS來實現(xiàn)這個功能,既簡單高效,又能夠避免增加JavaScript復(fù)雜度,是一個比較優(yōu)的解決方案。
參考CSS3 transitions using visibility and delay(英文)
transition過渡
transition示例
說明jsbin是一個在線的編輯器,能夠在代碼編寫完成后馬上看到效果,但是該文中有部分代碼在jsbin中出現(xiàn)表現(xiàn)與本地不一致的情況(例如CSS進(jìn)階中最后一個代碼),大家可以將代碼放到本地驗證。由于代碼效果時好時壞,猜測可能與jsbin的容器相關(guān)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/115161.html
摘要:中文譯為轉(zhuǎn)換,但我更傾向于稱呼它變形大名鼎鼎的變形金剛叫。意為縮放,顧名思義,是用于改變元素的大小。每個時間點對應(yīng)一個狀態(tài),代表一個關(guān)鍵幀。我們可以在可視化的創(chuàng)建我們自己的貝塞爾曲線。 簡介 Animation可以讓你不用依賴javascript或jquery,用純CSS在網(wǎng)頁中輕松實現(xiàn)各種動畫效果。 兼容性 animation在絕大部分主流瀏覽器都得到了很好的支持!還在兼容IE9的同...
摘要:感謝遺忘的過路人這位博主,發(fā)現(xiàn)了高級前端進(jìn)階一中的轉(zhuǎn)樹形數(shù)據(jù)的問題。引發(fā)的思考引發(fā)的思考之前的方法,只要進(jìn)行一次遍歷即可,然而現(xiàn)在發(fā)現(xiàn),之前的方法的前提是數(shù)據(jù)已經(jīng)是排好序的。感謝 遺忘的過路人 這位博主,發(fā)現(xiàn)了 高級前端進(jìn)階(一) 中的list轉(zhuǎn)樹形數(shù)據(jù)的問題。當(dāng)然也是我的疏忽。抱歉?。?!一、解決問題復(fù)現(xiàn)一下問題將list數(shù)據(jù)不按id順序排序,將之打亂// list數(shù)據(jù)[ { ...
摘要:默認(rèn),只執(zhí)行一次動畫動畫名稱,該名稱為動畫關(guān)鍵幀的名稱。默認(rèn)如何理解表示的是關(guān)鍵幀的名稱,那么如何定義關(guān)鍵幀呢使用。語法名稱關(guān)鍵幀樣式或總結(jié)其實也并不復(fù)雜,其有個子屬性。下一篇動畫三源碼解析通過閱讀動畫庫的源碼,來提高對中屬性的認(rèn)識 前言 上一篇中,總結(jié)了一下 transition 以及 cubic-bezier()。本篇中,將介紹 css3 動畫中的更為靈活的動畫屬性:animati...
摘要:與關(guān)鍵幀動作這是動作系統(tǒng)的核心。而關(guān)鍵幀動作又包含理更加基本的元素關(guān)鍵幀關(guān)鍵幀包含的屬性與屬性是同名的且與所有視圖的屬性都是對應(yīng)關(guān)鍵。為動作執(zhí)行到達(dá)關(guān)鍵幀時觸發(fā)。 Ngui簡介 這是一個GUI的排版顯示引擎和跨平臺的GUI應(yīng)用程序開發(fā)框架,基于NodeJS/OpenGL,這也是第一個在移動端Android/iOS融合NodeJS的前端GUI項目,至此JavaScript成為了真正意義上...
閱讀 877·2021-11-23 09:51
閱讀 909·2021-11-23 09:51
閱讀 2576·2021-11-15 18:01
閱讀 3961·2021-10-11 11:07
閱讀 2473·2021-09-22 15:30
閱讀 1137·2021-09-22 14:59
閱讀 1616·2019-08-30 15:55
閱讀 1822·2019-08-30 15:52