利用css transition屬性實現一個帶動畫顯隱的微信小程式部件
我們先來看效果圖
像這樣的一個帶過渡效果的小部件在我們實際開發中的應用機率還是比較大的,但是在開發微信小程式的過程中可能有的小夥伴發現transition這個屬性它不好使(下面說明)所以我們這個時候會考慮去使用微信官方提供的wx.createAnimation API來建立動畫。
接下來我帶各位小夥伴如何讓 transition 屬性在這種需求中好使起來,下面上程式碼
index.wxsspage({ data: { show:false//用於顯示或隱藏控制元件 }, chanMask:function(){ var isShow = this.data.show ? false : true;//如果顯示就隱藏,隱藏就顯示 this.setData({ show:isShow }) } })
顯示前.mask-con{ transition:1s; position:fixed;width:100%;height:300rpx;left:0;bottom:-300rpx;background-color:white;text-align:center;line-height:300rpx;box-shadow:01px10px#aaa;}顯示後.mask-con-show{bottom:0;}<!--index.wxml--><viewclass="container"> <buttonbindtap="chanMask">點我</button
在以上程式碼中我們首先在data中定義了一個show變數用於mask-con控制元件的顯示狀態,在chanMask函式中交替的改變這個變數,然後將chanMask函式繫結給button和close控制元件的點選事件上,最後我們根據show來決定是否給mask-con(我們的動畫控制元件)新增一個class: mask-con-show那麼到這裡我們已經實現了一個帶過渡的顯隱小部件,但是對於某些需求這還是太勉強了,比如下圖的情況:
現在很多的APP或小程式都是以這種方式來close彈窗控制元件,那個X使用者點的不過癮,看到這裡聰明的小夥伴可能會想到再另外新增一個陰影控制元件在mask-con的下層並繫結上我們的chanMask函式,這樣的話陰影控制元件和我們的mask-con就可能不是在一個整體上了,不夠直觀,又比如說領導要讓這個陰影它有一個顯示顏色慢慢加深,隱藏慢慢減淡的效果,為了應對這種情況,我們把程式碼調整如下:
page({
data: {
show:false//用於顯示或隱藏mask控制元件
},
chanMask:function(){
var isShow = this.data.show ? false : true;//如果顯示就隱藏,隱藏就顯示
this.setData({
show:isShow
})
}
})
index.wxss
.mask-shadow{width:100%;height:100%;background-color:#000;opacity:0;transition:1s;}.mask-shadow-on{opacity:0.3;}.mask-con{position:absolute;width:100%;height:300rpx;left:0;bottom:-300rpx;background-color:white;transition:1s;text-align:center;line-height:300rpx;box-shadow:01px10px#aaa;}.mask-con-show{bottom:0;}<!--index.wxml--><viewclass="container"><buttonbindtap="chanMask">點我</button><viewclass="mask {{show ? 'show' : 'hide'}}"><viewclass="mask-shadow {{show ? 'mask-shadow-on' : ''}}"></view><viewclass="mask-con {{show ? 'mask-con-show' : ''}}"><viewclass="close"bindtap="chanMask">X</view> 慢慢飛起</view></view></view>在這裡我們設定了兩個樣式類名mask-shadow-on和mask-con-show來定義陰影以及主要控制元件mask-con動畫後的效果(具體程式碼根據自己的需求決定),看起來一切都OK,沒有任何問題,那麼先執行一波,艾瑪,神馬情況?陰影和我們的mask-con直接懟了出來毫無過渡效果,那這是何原因影響我們程式的效果呢,經過一番考量博主發現在display為none的情況之下我們的transition屬性可能會失效,那到這裡有的小夥伴可能會問 “博主,那個不對啊,我們明明已經將mask的display設定成block怎麼還有這種問題呢”
是這樣的,我們的mask控制元件它顯示需要那麼一點時間才能完全顯示出來,但是呢我們的變數show設定成true之後,我們的陰影控制元件和主要控制元件也會馬上新增上了動畫後樣式類名,這個時間它比mask顯示所需的時間要快,所以我們的機器它認為mask還是處於display為none的情況
打個比方說:mask是這一整塊的老大,這個老大都還沒表演完事,你們這些做小弟就已經出來搶風頭了,你讓當老大的面子往哪放,不行我得把你們這些搶我風頭的都給幹掉,看你們還得瑟。這個老大的人狠話不多,你搶了他風頭不行,你想不表演他(使用者體驗)也不高興,而且他表演完了還不跟你說,那這個老大這麼難伺候該怎麼辦呢?有的小夥伴已經感覺到迷茫了嗎,那還在等什麼,趕快拿起你手中的電話撥打求助熱線。。。。。啊呸,扯遠了
其實決解的方法很簡單,沒錯答案就是 setTimeout()函式,來,我們把程式碼再改一遍:
page({
data: {
show:false,//用於顯示或隱藏mask控制元件
runAM:false//用於動畫執行的根據
},
chanMask:function(){
var isShow = this.data.show ? false : true;//如果顯示就隱藏,隱藏就顯示
var delay = isShow ? 30 : 1000;//第一個時間是博主測出來控制元件顯示所需的時間,第二個是動畫所需的時間
if(isShow){
this.setData({
show:isShow
});
}else{
this.setData({
runAM:isShow
})
}
setTimeout(function(){
if(isShow){
this.setData({
runAM:isShow
});
}else{
this.setData({
show:isShow
});
}
}, delay);
}
})
<!--index.wxml--><viewclass="container"><buttonbindtap="chanMask">點我</button><viewclass="mask {{show ? 'show' : 'hide'}}"bindtap="chanMask"><viewclass="mask-shadow {{runAM ? 'mask-shadow-on' : ''}}"></view><viewclass="mask-con {{runAM ? 'mask-con-show' : ''}}"><viewclass="close"bindtap="chanMask">X</view> 慢慢飛起</view></view></view>在以上程式碼中,我們給data新添加了一個變數runAM用於動畫何時開始執行的憑證,再在chanMask函式定義了一個用於設定延時的變數delay 程式碼可能有點繞博主在此粗暴的解釋一下
程式的整個過程都是根據isShow這個變數來走的,
當isShow為true時也就是說我們要開啟mask控制元件了,所以我們先把mask控制元件顯示出來,然後在延時30毫秒後去為要執行動畫的控制元件新增上樣式類名
當isShow為false時我們先把動畫控制元件的類名去掉(去掉後會執行動畫回到原本的形態),然後在延時1000毫秒(動畫所需的時間)後讓mask隱藏
關於delay的第一個值的設定時博主自己測出來的,如果各位小夥伴還擔心控制元件沒顯示的話可以設成50毫秒或100毫秒都無所這0.1秒的時間差對使用者體驗的影響並不大,如過你設了1秒都沒反應,我只能說換手機吧
最後你會發現在整個過程中博主都只調用一個函式進行顯示或隱藏,並沒有為關閉新建函式處理,這種寫法逼格滿滿有木有
此方法同樣適用於H5
新人第一次寫部落格有點囉嗦了,望見諒