1. 程式人生 > >自定義tabBar 解決頁面跳轉動畫斷片問題

自定義tabBar 解決頁面跳轉動畫斷片問題

記錄一次事件......由於業務需求,小程式底部的tabBar需要動態獲取並顯示,而官方提供的app.json 內tabBar的配置無法再程式中修改,因此需要自定義類似官方效果的tabBar導航欄。上一篇文章已經描述瞭如何自定義tabBar以及如何使用(元件來自網路,效果不錯,貼上過來記錄學習)。但是,在真機上測試的時候暫時發現了以下兩個問題:
  1. 當前頁面可重複點選
  2. 頁面切換與tabBar展示不同步,tabBar會出現“閃現”的情況,視覺效果很糟糕

針對【問題1】:解決方案:在tabBar元件上新增事件,點選的時候判斷目標頁面路由與當前頁面路由是否相同,相同則不做跳轉處理,否則跳轉新頁面;針對【問題2】:解決方案:
  1. 用css幀動畫過渡,我使用了兩種型別的過渡:【tabBar從透明到不透明過渡】,【從各個方向移動到正確tabBar位置過渡】,效果仍然不好,因為無法完美匹配小程式頁面切換的動畫節奏。
  2. 既然css搞不定,那就js函式解決吧!
    這裡主要利用到兩個頁面跳轉函式:【navigateTo】與【navigateBackTo】
    因為針對【問題1】的時候已經給元件加了相應的點選事件,具體的跳轉等操作邏輯是放在監聽的函式裡完成的,主要解決思路是利用navigateTo【當前頁面入棧,並開啟新頁面】的特性已經這種方式頁面跳轉的平滑效果,這樣就已經解決了“閃現”問題,但是新的問題是【現在頁面棧最多儲存10層頁面】當大於這個數量後,新的頁面無法入棧,也就無法開啟新的頁面了(mmp!!!)。
    因此,就需要使用到【navigateBackTo】在可以開啟新頁面的時候(即:當前頁面路由不等於目標頁面路由),先用 
    getCurrentPages()獲取當前頁面棧(陣列),然後遍歷頁面棧判斷目標頁面是否存在於其中,如果存在:使用【navigateBackTo】退回到存在的那個頁面(同時也是目標頁面);否則,使用【navigateTo】開啟頁面;
    以下是具體的實現方法

//tabBar元件裡的監聽事件<viewclass="tabbar_nav"data-url='{{item.pagePath}}'bindtap='__bindNavigate'</view>// 呼叫navTab的一級頁面__bindNavigate: function (e) {      util.switchTabBar(this.route,e);
}// util.js 中自定義tabBar 跳轉具體實現事件functionswitchTabBar(currRoute,e){  var currUrl = currRoute;  var targeturl = e.currentTarget.dataset.url;  (currUrl.indexOf('/') != 0) && (currUrl = '/' + currUrl);  //當前頁面路由不是目標頁面路由 進而判斷【navigateTo/navigateBack】if (currUrl != targeturl) {    navigateBackToExistOrNavigateToNew(getCurrentPages(), targeturl)  }else {    wx.showToast({      title: '試試下拉頁面重新整理頁面吧',      image: "/resources/images/nomore.png"    })  }}// 選擇具體的跳轉方式functionnavigateBackToExistOrNavigateToNew(routers,targetRouter){  var total = routers.length;  var len = routers.length;  while (len--) {    //如果目標頁面存在於頁面棧,則navigateBack至頁面站內的目標頁面    if (('/' + routers[len].__route__) == targetRouter) {        console.log("__route__: /", routers[len].__route__, ' == target:', targetRouter);        console.log("Result:path equal,back delta:", total - 1, ',', len, ',', (total - 1 - len));        wx.navigateBack({          delta: total - 1 - len        })        return true;    } else {        console.log("__route__: /", routers[len].__route__, ' != target:', targetRouter);    }  }  //如果目標頁面不存在於頁面棧,則navigateTo  wx.navigateTo({    url: targetRouter,  })  return false;}當然也是出於無奈,沒有找到更好地方法,歡迎更好地解決方案!