自定义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组件里的监听事件
<view class="tabbar_nav" data-url='{{item.pagePath}}' bindtap='__bindNavigate'
</view>

// 调用navTab的一级页面
__bindNavigate: function (e) {
      util.switchTabBar(this.route,e);
}

// util.js 中自定义tabBar 跳转具体实现事件
function   switchTabBar (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"
    })
  }
}
// 选择具体的跳转方式
function  navigateBackToExistOrNavigateToNew (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;
}

当然也是出于无奈,没有找到更好地方法,欢迎更好地解决方案!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值