天天看點

利用css transition屬性實作一個帶動畫顯隐的微信小程式部件

我們先來看效果圖

利用css transition屬性實作一個帶動畫顯隐的微信小程式部件

像這樣的一個帶過渡效果的小部件在我們實際開發中的應用幾率還是比較大的,但是在開發微信小程式的過程中可能有的小夥伴發現transition這個屬性它不好使(下面說明)是以我們這個時候會考慮去使用微信官方提供的wx.createAnimation  API來建立動畫。

接下來我帶各位小夥伴如何讓 transition 屬性在這種需求中好使起來,下面上代碼

page({
    data: {
        show:false//用于顯示或隐藏控件
    },
    chanMask:function(){
        var isShow = this.data.show ? false : true;//如果顯示就隐藏,隐藏就顯示
        this.setData({
            show:isShow
        })
    }
})
           

index.wxss

顯示前 .mask-con { transition: 1s ;   position: fixed ; width: 100% ; height: 300 rpx ; left: 0 ; bottom: -300 rpx ; background-color: white ; text-align: center ; line-height: 300 rpx ; box-shadow: 0 1px 10px #aaa ; } 顯示後 .mask-con-show { bottom: 0 ; } <!--index.wxml--> < view class = "container"> < button bindtap = "chanMask"> 點我 </ button > < view class = "mask-con {{show ? 'mask-con-show' : ''}}"> < view class = "close" bindtap = "chanMask"> X </ view > 慢慢飛起 </ view > </ view >

在以上代碼中我們首先在data中定義了一個show變量用于mask-con控件的顯示狀态,在chanMask函數中交替的改變這個變量,然後将chanMask函數綁定給button和close控件的點選事件上,最後我們根據show來決定是否給mask-con(我們的動畫控件)添加一個class: mask-con-show那麼到這裡我們已經實作了一個帶過渡的顯隐小部件,但是對于某些需求這還是太勉強了,比如下圖的情況:

利用css transition屬性實作一個帶動畫顯隐的微信小程式部件

現在很多的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: 300 rpx ; left: 0 ; bottom: -300 rpx ; background-color: white ; transition: 1s ; text-align: center ; line-height: 300 rpx ; box-shadow: 0 1px 10px #aaa ; } .mask-con-show { bottom: 0 ; } <!--index.wxml--> < view class = "container"> < button bindtap = "chanMask"> 點我 </ button > < view class = "mask {{show ? 'show' : 'hide'}}"> < view class = "mask-shadow {{show ? 'mask-shadow-on' : ''}}"></ view > < view class = "mask-con {{show ? 'mask-con-show' : ''}}"> < view class = "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--> < view class = "container"> < button bindtap = "chanMask"> 點我 </ button > < view class = "mask {{show ? 'show' : 'hide'}}" bindtap = "chanMask"> < view class = "mask-shadow {{runAM ? 'mask-shadow-on' : ''}}"></ view > < view class = "mask-con {{runAM ? 'mask-con-show' : ''}}"> < view class = "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

新人第一次寫部落格有點啰嗦了,望見諒

利用css transition屬性實作一個帶動畫顯隐的微信小程式部件

GitHub連接配接 https://github.com/1441327053/frontEnd-WXapp/tree/master/widget-transition