微信小程序自定义导航栏(模板化)


Posted in Javascript onNovember 15, 2019

前段时间写过一篇关于微信小程序自定义导航栏的自定义组件,但是对于分享页有一定的bug
这次用模板化又搞了一遍 优化了下Android与IOS 显示更接近微信原生的导航栏,以及修复分享页面不显示返回首页按钮
如果大家不习惯模板化的话可以 针对自己的需求拿以前封装的组件化做一些修改
微信小程序自定义导航栏(组件化)

CustomNavBar.wxml

<template name="CustomNavBar">
 <block wx:if="{{ showNavBar }}">

 <!-- 自定义导航栏悬浮时,卡空行 -->
 <block wx:if="{{ needFixed }}">
  <view style="position: relative; width: 100%; height: {{ navHeight }}px;"></view>
 </block>

 <view class="custom-navbar-con relative {{ iOS ? ' ios ' : ' android ' }}" style="height: {{ navHeight }}px; {{ needFixed ? 'position: fixed; top: 0;' : '' }}">
  <view class="custom-navbar-statusbar-con relative" style="height: {{ statusBarHeight }}px;"></view>
  <view class="custom-navbar-content relative" style="height: {{ navHeight - statusBarHeight }}px;">

  <!-- iOS端的导航栏显示方式 -->
  <block wx:if="{{ navTitle && navTitle.length > 0 }}">
   <view class="custom-navbar-title ios">{{ navTitle }}</view>
  </block>

  <block wx:if="{{ showLeftMenu }}">
   <view class="custom-navbar-left-menu-con clearfix" style="top: {{ navRightMenuRect.top - statusBarHeight - 1 }}px; left: {{ winWidth - navRightMenuRect.right }}px; height: {{ navRightMenuRect.height + 2 }}px;">
   <block wx:if="{{ showBackBtn }}">
    <view class="custom-navbar-icon-btn pull-left back" style="height: {{ navRightMenuRect.height }}px" bindtap="customNavBarBack">
    <image class="icon" src="../../image/icon-nav-back.png" mode="aspectFit" style="width: {{ navRightMenuRect.height }}px;" />
    <text class="text"></text>
    </view>
   </block>

   <block wx:if="{{ showHomeBtn }}">
    <view class="custom-navbar-icon-btn pull-left home" style="height: {{ navRightMenuRect.height }}px" bindtap="customNavBarBackToHome">
    <image class="icon" src="../../image/icon-nav-home.png" mode="aspectFit" style="width: {{ navRightMenuRect.height }}px;" />
    <text class="text"></text>
    </view>
   </block>

   <!-- android端的导航栏显示方式 -->
   <block wx:if="{{ navTitle && navTitle.length > 0 }}">
    <view class="custom-navbar-title android pull-left" style="line-height: {{ navRightMenuRect.height - 2 }}px;">{{ navTitle }}</view>
   </block>
   </view>
  </block>
  </view>
 </view>
 </block>
</template>

CustomNavBar.wxss

.custom-navbar-con { position: relative; width: 100%; background-color: white; z-index: 9999; }
.custom-navbar-con .custom-navbar-statusbar-con { width: 100%; }
.custom-navbar-con .custom-navbar-content { width: 100%; }
.custom-navbar-con .custom-navbar-left-menu-con { position: absolute; }
.custom-navbar-con .custom-navbar-left-menu-con .custom-navbar-icon-btn { height: 100%; border-radius: 200px; border: 1px solid rgba(220, 220, 220, 0.6); }
.custom-navbar-con .custom-navbar-left-menu-con .custom-navbar-icon-btn .icon { height: 90%; margin-top: 2.5%; }
.custom-navbar-con .custom-navbar-left-menu-con .custom-navbar-icon-btn .text { font-size: 27rpx; }
.custom-navbar-con .custom-navbar-left-menu-con .custom-navbar-icon-btn.back { border: none; }
.custom-navbar-con .custom-navbar-left-menu-con .custom-navbar-icon-btn.back~.custom-navbar-icon-btn.home { margin-left: 10rpx; }
.custom-navbar-con .custom-navbar-left-menu-con .custom-navbar-icon-btn.switch-shop { padding-left: 5px; padding-right: 25rpx; }


.custom-navbar-con.ios .custom-navbar-title.android { display: none; }
.custom-navbar-con.android .custom-navbar-title.ios { display: none; }
.custom-navbar-con .custom-navbar-title.ios { font-weight: bold; text-align: center; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); -webkit-transform: translate(-50%, -50%); }
.custom-navbar-con .custom-navbar-title.android { padding-left: 30rpx; }```

CustomNavBar.js

```javascript
module.exports = function(PageInstance) {
 let App = getApp()

 let _tplData = {
 _CustomNavBar_: {
  navRightMenuRect: App.NavRightMenuRect,
  navRightMenuCenterY: App.NavRightMenuCenterY,
  statusBarHeight: App.StatusBarHeight,
  winWidth: App.WinWidth,
  winHeight: App.WinHeight,
  iOS: App.iOS,

  navTitle: '', // 当前只合适短标题,如需长标题,建议隐藏自定义导航栏,自定义展示
  navHeight: App.CustomNavHeight,

  needFixed: false,

  showNavBar: !App.NavRightMenuRect ? false : true,
  showLeftMenu: true,
  showBackBtn: true,
  showHomeBtn: false
 }
 }

 let _tplMethods = {
 customNavBarBack() {
  wx.navigateBack()
 },
 customNavBarBackToHome() {
  let url = '/pages/index/index'
  wx.reLaunch({
  url: url
  })
 }
 }
 let isIndexPage = !!(PageInstance.route == 'pages/index/index')
 let pages = getCurrentPages()
 if (pages.length == 1) {
 _tplData._CustomNavBar_.showBackBtn = false
 _tplData._CustomNavBar_.showHomeBtn = !isIndexPage
 }

 // 每个页面 可单独配置自定义导航栏
 if (PageInstance.data.CustomNavBarConfig) {
 Object.assign(_tplData._CustomNavBar_, PageInstance.data.CustomNavBarConfig)
 }

 // !!!! 最后执行
 // 当无法获取到右上角按钮胶囊的布局位置时,强制设置自定义导航栏为隐藏状态
 if (!App.NavRightMenuRect) {
 _tplData._CustomNavBar_.showNavBar = false
 }

 Object.assign(PageInstance, _tplMethods)
 PageInstance.setData(_tplData)
 return this
}

app.js的配置

// 自定义导航栏
import CustomNavBar from './template/CustomNavBar/CustomNavBar';

 App({
 //自定义 模板式 组件
 CustomNavBar,
 
 // 系统信息
  WinWidth: 0,
  WinHeight: 0,
  StatusBarHeight: 0,
  PixelRatio: 1,
  SystemFullName: '',
  SystemVersion: '',
  SystemSDKVersion: '',

  //自定义导航栏相关
  NavRightMenuRect: null,
  NavRightMenuCenterY: 0,
  CustomNavHeight: 0,
  
 onLaunch: function (options) {
 let self = this
 let systemInfo = wx.getSystemInfoSync()
 self.iOS = systemInfo.platform === 'ios'
 self.isDebug = systemInfo.platform === 'devtools'
 if (self.isDebug) {
  // 单纯为了在开发工具下调试 自定义导航栏
  // 开发工具下不存在App版本号的区分
  systemInfo.version = '7.0.0'
 }
 self.WinWidth = systemInfo.windowWidth
 self.WinHeight = systemInfo.windowHeight
 self.StatusBarHeight = systemInfo.statusBarHeight
 // 部分小程序库版本没有返回状态栏高度
 if (!self.StatusBarHeight) {
  self.StatusBarHeight = 20
 }
 self.PixelRatio = Math.max(systemInfo.pixelRatio, 2)
 self.SystemFullName = systemInfo.system
 self.SystemVersion = systemInfo.version
 self.SystemSDKVersion = systemInfo.SDKVersion

 // app.json全局配置的自定义导航栏的话,客户端需求版本为6.6.0
 // 每个页面 单独配置的自定义导航栏的话,客户端需求版本为7.0.0
 // wx.getMenuButtonBoundingClientRect方法,要求基础库版本为2.1.0
 if (self.compareVersion(self.SystemVersion, '6.6.0') >= 0) {
  // 官方的6.6.0版本以上客户端,最低基础库版本为1.9.4
  // 6.6.0以上且[1.9.4 - 2.1.0]范围内的机型无法使用wx.getMenuButtonBoundingClientRect
  // 所以手动写死非全面屏手机的适配胶囊布局位置
  self.NavRightMenuRect = {
  top: 26,
  bottom: 58,
  right: self.WinWidth - 10,
  width: 87,
  height: 32
  }
  // 如果系统信息返回的状态栏高度大于20,认为是全面屏手机
  if (self.StatusBarHeight > 20) {
  self.NavRightMenuRect.top = 50
  self.NavRightMenuRect.bottom = 82
  }

  // 2019年08月21日22:09:22
  // 微信小程序库出现bug,导致部分机型wx.getMenuButtonBoundingClientRect无返回值
  // 所以在这之前先默认写死一个NavRightMenuRect,防止全局的自定义导航栏已经隐藏了但是无法显示自定义导航栏
  // 详见https://developers.weixin.qq.com/community/develop/doc/00062238d78e880aedd88b72351c00
  if (wx.getMenuButtonBoundingClientRect) {
  let NavRightMenuRect = wx.getMenuButtonBoundingClientRect()
  self.NavRightMenuRect = {
   top: NavRightMenuRect.top,
   bottom: NavRightMenuRect.bottom,
   right: NavRightMenuRect.right,
   width: NavRightMenuRect.width,
   height: NavRightMenuRect.height
  }
  }

  self.NavRightMenuCenterY = self.NavRightMenuRect.top + self.NavRightMenuRect.height / 2
  self.CustomNavHeight = self.NavRightMenuRect.bottom + (self.NavRightMenuRect.top - self.StatusBarHeight)
 } else {
  self.NavRightMenuRect = null
  self.CustomNavHeight = 0
 }
 },
 
  // 比较两个版本号
 compareVersion (v1, v2) => {
   v1 = v1.split('.')
   v2 = v2.split('.')
   const len = Math.max(v1.length, v2.length)
 
   while (v1.length < len) {
     v1.push('0')
   }
   while (v2.length < len) {
     v2.push('0')
   }
 
   for (let i = 0; i < len; i++) {
     const num1 = parseInt(v1[i])
     const num2 = parseInt(v2[i])
 
     if (num1 > num2) {
       return 1
     } else if (num1 < num2) {
       return -1
     }
   }
   return 0
 } 
    
}),

假如在index 页面引用

index.wxml

<!-- 自定义NavBar -->
<import src="../../template/CustomNavBar/CustomNavBar.wxml" />
<template is="CustomNavBar" data="{{ ..._CustomNavBar_ }}"></template>

index.js

onLoad: function(options) {
  new App.CustomNavBar(this)
 }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
基于jquery的loading效果实现代码
Nov 05 Javascript
关于js拖拽上传 [一个拖拽上传修改头像的流程]
Jul 13 Javascript
jquery修改属性值实例代码(设置属性值)
Jan 06 Javascript
js取float型小数点后两位数的方法
Jan 18 Javascript
js图片预加载示例
Apr 30 Javascript
浅谈JavaScript中setInterval和setTimeout的使用问题
Aug 01 Javascript
JS实现的论坛Ajax打分效果完整实例
Oct 31 Javascript
bootstrap快速制作后台界面
Dec 05 Javascript
Js实现中国公民身份证号码有效性验证实例代码
May 03 Javascript
详解angular ui-grid之过滤器设置
Jun 07 Javascript
echarts同一页面中四个图表切换的js数据交互方法示例
Jul 03 Javascript
在Vue.js中使用TypeScript的方法
Mar 19 Javascript
在node环境下parse Smarty模板的使用示例代码
Nov 15 #Javascript
微信小程序自定义头部导航栏(组件化)
Nov 15 #Javascript
create-react-app中添加less支持的实现
Nov 15 #Javascript
taro小程序添加骨架屏的实现代码
Nov 15 #Javascript
详解Angular Karma测试的持续集成实践
Nov 15 #Javascript
Javascript 类型转换、封闭函数及常见内置对象操作示例
Nov 15 #Javascript
JavaScript定时器常见用法实例分析
Nov 15 #Javascript
You might like
全国FM电台频率大全 - 23 四川省
2020/03/11 无线电
php实现模拟post请求用法实例
2015/07/11 PHP
WordPress中调试缩略图的相关PHP函数使用解析
2016/01/07 PHP
WordPress分页伪静态加html后缀
2016/06/08 PHP
thinkPHP框架中执行原生SQL语句的方法
2017/10/25 PHP
php如何实现数据库的备份和恢复
2020/11/30 PHP
jQuery UI-Draggable 参数集合
2010/01/10 Javascript
select标签模拟/美化方法采用JS外挂式插件
2013/04/01 Javascript
jquery 获取标签名(tagName)示例代码
2013/07/11 Javascript
jquery实现点击页面计算点击次数
2015/01/23 Javascript
javascript自定义右键弹出菜单实现方法
2015/05/25 Javascript
详解JavaScript中数组的相关知识
2015/07/29 Javascript
JS 清除字符串数组中,重复元素的实现方法
2016/05/24 Javascript
JavaScript箭头函数_动力节点Java学院整理
2017/06/28 Javascript
nodejs 搭建简易服务器的图文教程(推荐)
2017/07/18 NodeJs
element-ui多文件上传的实现示例
2019/04/10 Javascript
JavaScript箭头函数中的this详解
2019/06/19 Javascript
世界上最短的数字判断js代码
2019/09/09 Javascript
python实现文件路径和url相互转换的方法
2015/07/06 Python
Python简单实现TCP包发送十六进制数据的方法
2016/04/16 Python
Python实现TCP协议下的端口映射功能的脚本程序示例
2016/06/14 Python
Python 数据结构之队列的实现
2017/01/22 Python
pycharm设置注释颜色的方法
2018/05/23 Python
详解Python是如何实现issubclass的
2019/07/24 Python
python如何通过twisted搭建socket服务
2020/02/03 Python
为什么说python更适合树莓派编程
2020/07/20 Python
Cinque网上商店:德国服装品牌
2019/03/17 全球购物
StringBuilder和String的区别
2015/05/18 面试题
房地产员工找工作的自我评价
2013/11/15 职场文书
幼儿教师思想汇报
2014/01/10 职场文书
帮一个朋友写的求职信
2014/08/09 职场文书
出纳工作检讨书范文
2014/12/27 职场文书
幼儿园六一儿童节演讲稿
2015/03/19 职场文书
Django+Nginx+uWSGI 定时任务的实现方法
2022/01/22 Python
Matplotlib绘制条形图的方法你知道吗
2022/03/21 Python
Python测试框架pytest核心库pluggy详解
2022/08/05 Golang