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


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 相关文章推荐
20行代码实现的一个CSS覆盖率测试脚本
Jul 07 Javascript
浅谈EasyUI中Treegrid节点的删除
Mar 01 Javascript
深入探讨javascript中的数据类型
Mar 04 Javascript
弹出遮罩层后禁止滚动效果【实现代码】
Apr 29 Javascript
jQuery页面元素动态添加后绑定事件丢失方法,非 live
Jun 16 Javascript
完美的js div拖拽实例代码
Sep 24 Javascript
jQuery Ztree行政地区树状展示(点击加载)
Nov 09 Javascript
JS制作类似选项卡切换的年历
Dec 03 Javascript
手动用webpack搭建第一个ReactApp的示例
Apr 11 Javascript
Hexo已经看腻了,来手把手教你使用VuePress搭建个人博客
Apr 26 Javascript
浅谈laytpl 模板空值显示null的解决方法及简单的js表达式
Sep 19 Javascript
vue-cli设置css不生效的解决方法
Feb 07 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
DISCUZ 分页代码
2007/01/02 PHP
微信公众平台开发之配置与请求
2015/08/26 PHP
PHP receiveMail实现收邮件功能
2018/04/25 PHP
javascript 跳转代码集合
2009/12/03 Javascript
node.js插件nodeclipse安装图文教程
2020/10/19 Javascript
Jquery实现遮罩层的简单实例(就是弹出DIV周围都灰色不能操作)
2016/07/14 Javascript
浅谈JavaScript中的this指针和引用知识
2016/08/05 Javascript
微信小程序开发之入门实例教程篇
2017/03/07 Javascript
TypeScript入门-接口
2017/03/30 Javascript
(模仿京东用户注册)用JQuery实现简单表单验证,初学者必看
2018/01/08 jQuery
layer.confirm点击第一个按钮关闭弹出框的方法
2019/09/09 Javascript
js中Function引用类型常见有用的方法和属性详解
2019/12/11 Javascript
python实现在windows服务中新建进程的方法
2015/06/30 Python
Python中按键来获取指定的值
2019/03/02 Python
Django自定义用户表+自定义admin后台中的字段实例
2019/11/18 Python
keras模型可视化,层可视化及kernel可视化实例
2020/01/24 Python
Pygame的程序开始示例代码
2020/05/07 Python
python 写一个水果忍者游戏
2021/01/13 Python
HTML5 Canvas图像模糊完美解决办法
2018/02/06 HTML / CSS
html5本地存储 localStorage操作使用详解
2016/09/20 HTML / CSS
HTML5中在title标题标签里设置小图标的方法
2020/06/23 HTML / CSS
法国综合购物网站:RueDuCommerce
2016/09/12 全球购物
销售所有的狗狗产品:Dog.com
2016/10/13 全球购物
ALDI奥乐齐官方海外旗舰店:德国百年超市
2017/12/27 全球购物
ZWILLING双立人英国网上商店:德国刀具锅具厨具品牌
2018/05/15 全球购物
管理科学大学生求职信
2013/11/13 职场文书
实习生评语
2014/04/26 职场文书
酒店管理专业自荐信
2014/05/23 职场文书
银行职员工作失误检讨书
2014/10/14 职场文书
2015年中学体育教师工作总结
2015/10/23 职场文书
提升Nginx性能的一些建议
2021/03/31 Servers
Jsonp劫持学习
2021/04/01 PHP
JS新手入门数组处理的实用方法汇总
2021/04/07 Javascript
Python控制台输出俄罗斯方块的方法实例
2021/04/17 Python
详解JS ES6编码规范
2021/05/07 Javascript
Linux中各个目录的作用与内容
2022/06/28 Servers