微信小程序自定义头部导航栏和导航栏背景图片 navigationStyle问题


Posted in Javascript onJuly 26, 2019

这两天因为要做一个带背景的小程序头,哭了,小程序导航栏有背景也就算了,还得让导航栏上的背景顺下来,心态小崩。现在可以单独设置一个页面的小程序头了,但是前提是要微信7.0以上的版本,考虑到兼容性问题,还是不要贸然的上了,所以用老版本的替换所有页面的小程序头来做。

​ 参考了其他篇的文章,但是没有解决自定义背景的和返回按钮的颜色的问题,还有因为IOS的橡皮筋效果,对IOS端不太友好,屏幕会乱划。所以针对性的改动了这些功能,因为才学小程序两三天,所以其中踩了很多坑,但好在最后效果还是达到了。

下面是效果图:

微信小程序自定义头部导航栏和导航栏背景图片 navigationStyle问题

原理其实就是通过将原来的头禁用,然后PAGE自然而然的顶上去以后,定义一个头的组件,将他设置成fixed布局固定在原来头的部分,然后给page加上Margin-top,所以还原原来的感觉。背景待会再说。

1.app配置

​ 首先禁用所有头导航,在app.json的window里加一行这个,你会发现所有头都消失了。然后禁止滑动页面,滑动问题用scroll-view解决

"window": {
 "navigationStyle": "custom"
}, 
"disableScroll": true

​ 然后在app.js里获取导航头的高度的全局数据

// app.js

App({
 globalData: {
 statusBarHeight: wx.getSystemInfoSync()['statusBarHeight']
 },
 // 判断是否由分享进入小程序
 if (e.scene == 1007 || e.scene == 1008) {
  this.globalData.share = true
 } else {
  this.globalData.share = false
 }
 //获取设备顶部窗口的高度(不同设备窗口高度不一样,根据这个来设置自定义导航栏的高度)
 //这个最初我是在组件中获取,但是出现了一个问题,当第一次进入小程序时导航栏会把
 //页面内容盖住一部分,当打开调试重新进入时就没有问题,这个问题弄得我是莫名其妙
 //虽然最后解决了,但是花费了不少时间
 wx.getSystemInfo({
  success: res => {
  this.globalData.height = res.statusBarHeight
  }
 })
 },
 globalData: {
 userInfo: null,
 share: false, // 分享默认为false
 height: 0 // 顶部高度
 }
})

在app.wxss给page加一个高度百分之百。

/* app.wxss */
page {
 height: 100%;
}

​ app配置到这里应该完事了。

2.组件配置

组件结构:

微信小程序自定义头部导航栏和导航栏背景图片 navigationStyle问题

放源码吧

// navbar.wxml

<view class='nav-wrap' style='height: {{height*2 + 20}}px;'>
 <!-- 导航栏背景图片 -->
 <image class="backgroundimg" src="{{navbarData.address}}" bindload="imgLoaded" style="width:{{imageWidth}}px;height:{{imageHeight}}px" />
 <!-- // 导航栏 中间的标题 -->
 <view class='nav-title' wx:if='{{!navbarData.white}}' style='line-height: {{height*2 + 44}}px;'>
 {{navbarData.title}}
 </view>
 <view class='nav-title' wx:else='{{!navbarData.white}}' style='line-height: {{height*2 + 44}}px; color:#ffffff'>
 {{navbarData.title}}
 </view>
 <view style='display: flex; justify-content: space-around;flex-direction: column'>
 <!-- // 导航栏 左上角的返回按钮 -->
 <!-- // 其中wx:if='{{navbarData.showCapsule}}' 是控制左上角按钮的显示隐藏,首页不显示 -->
 <view class='nav-capsule' style='height: {{height*2 + 44}}px;' wx:if='{{navbarData.showCapsule}}'>
  <!-- //左上角的返回按钮,wx:if='{{!share}}'空制返回按钮显示 -->
  <!-- //从分享进入小程序时 返回上一级按钮不应该存在 -->
  <!-- navbarData.white是控制按钮颜色的,因为背景有深浅色,返回按钮自己找图片 -->
  <view bindtap='_navback' wx:if='{{!share&&navbarData.white}}'>
  <image src='../../images/返 回 (1).svg' mode='aspectFit' class='back-pre'></image>
  </view>
  <view bindtap='_navback' wx:else='{{!share}}'>
  <image src='../../images/返 回.svg' mode='aspectFit' class='back-pre'></image>
  </view>
 </view>
 </view>
</view>
<!-- 导航栏下面的背景图片 -->
<image class="backgroundimg" src="{{navbarData.address}}" bindload="imgLoaded" style="width:{{imageWidth}}px;height:{{imageHeight}}px" />

CSS:

/* navbar.wxss */

/* 顶部要固定定位 标题要居中 自定义按钮和标题要和右边微信原生的胶囊上下对齐 */
.nav-wrap {
 /* display: none; */
 position: fixed;
 width: 100%;
 top: 0;
 background: #fff;
 color: #000;
 z-index: 9999999;
 background: #000;
 overflow: hidden;
}
/* 背景图 */
.backgroundimg {
 position: absolute;
 z-index: -1;
}
/* 标题要居中 */
.nav-title {
 position: absolute;
 text-align: center;
 max-width: 400rpx;
 overflow: hidden;
 text-overflow: ellipsis;
 white-space: nowrap;
 top: 0;
 left: 0;
 right: 0;
 bottom: 0;
 margin: auto;
 font-size: 36rpx;
 color: #2c2b2b;
 font-weight: 450;
}

.nav-capsule {
 display: flex;
 align-items: center;
 margin-left: 30rpx;
 width: 140rpx;
 justify-content: space-between;
 height: 100%;
}

.back-pre {
 width: 32rpx;
 height: 36rpx;
 margin-top: 4rpx;
 padding: 10rpx;
}
.nav-capsule {
 width: 36rpx;
 height: 40rpx;
 margin-top: 3rpx;
}

在JSON里声明我是个组件

{
 "component": true,
 "usingComponents": {}
}

最后是js。

const app = getApp()
Component({
 properties: {
 navbarData: {
  //navbarData 由父页面传递的数据,变量名字自命名
  type: Object,
  value: {},
  observer: function(newVal, oldVal) {}
 }
 },
 data: {
 height: '',
 //默认值 默认显示左上角
 navbarData: {
  showCapsule: 1
 },
 imageWidth: wx.getSystemInfoSync().windowWidth, // 背景图片的高度
 imageHeight: '' // 背景图片的长度,通过计算获取
 },
 attached: function() {
 // 获取是否是通过分享进入的小程序
 this.setData({
  share: app.globalData.share
 })
 // 定义导航栏的高度 方便对齐
 this.setData({
  height: app.globalData.height
 })
 },
 methods: {
 // 返回上一页面
 _navback() {
  wx.navigateBack()
 },
 // 计算图片高度
 imgLoaded(e) {
  this.setData({
  imageHeight:
   e.detail.height *
   (wx.getSystemInfoSync().windowWidth / e.detail.width)
  })
 }
 //返回到首页
 // _backhome() {
 // wx.switchTab({
 //  url: '/pages/index/index'
 // })
 // }
 }
})

大概就是这么多,怎么在页面上用呢

3.具体页面配置

​ 页面的HTML,我是内容里面放页面的东西。

<nav-bar navbar-data='{{nvabarData}}'></nav-bar>
<scroll-view scroll-y style="height: 100%;">
 <view class="scroll-view-item" style='padding-top: {{height}}px;'>我是内容</view>
</scroll-view>

页面的JSON,navigationBarTextStyle是用来配置胶囊颜色的,因为胶囊是微信给的,不能自定义,只能改颜色,所以委屈一下从这里改一下吧

{
 "usingComponents": {
 "nav-bar": "../../components/navbar/navbar"
 },
 "navigationBarTextStyle": "white"
}

页面JS,图片自己填上地址就好了。注意getApp()不要省。

const app = getApp()
Page({
 data: {
  // 导航头组件所需的参数
  nvabarData: {
   showCapsule: 1, //是否显示左上角图标  1表示显示  0表示不显示
   title: '标题', //导航栏 中间的标题
   white: true, // 是就显示白的,不是就显示黑的。
   address: '../../images/蒙版组 1@2x.png' // 加个背景 不加就是没有
  },
  // 导航头的高度
  height: app.globalData.height * 2 + 20
 }
})

4.存在的问题

上拉刷新

​ 我没有试过哈,不过原生的微信上拉刷新这么用是准定不行了,如果喜欢IOS橡皮筋模式的同学或者想要刷新的同学可以在具体页面里删掉scroll-view组件换成view(记得保留那个padding-top!),然后把app.json的禁用滑动删除掉。具体的我也没有深入,大家自行解决吧。

5.踩的坑

​ 单纯分享下,不看也可以,首先就是设置页面的背景的时候,我考虑过直接在css上设置background image,但是有一个问题是,小程序的background image 只支持在线的地址或者是base64。我不知道为什么要这么做。真的很迷。但是线上的不稳定,base64太长了,代码不好看也不好整理,所以考虑了一下还是用Image组件吧。

​ 然后第二个坑又来了,image组件自带宽高,而且用Mode里的任何值都不能完成需求。如果我设置成width:100%占满父元素的话,他的长还是默认的340px,所以还是鼓捣了鼓捣,先设置宽度不是100%了,而是通过wx.**getSystemInfoSync**().windowWidth;来获取的屏幕宽度。然后再通过image组件的事件获取原图的长宽,探后计算屏幕宽和原图宽的率,然后再将这个率乘上原图长度,就可以获取到一个占满父元素又对着比例的图了,然后给父元素套上overflow:hidden就好了。

​ 第三个坑,就是怎么做背景的拼接,想了想也不是个坑,直接在组件的最外层再加一个一模一样的image标签就行了,这样就做到了标签上显示半个背景图,然后在他的下层又能显示一个完整的背景图,因为上面被盖住了,所以地下的下半部分和导航栏的上半部分背景正好拼接起来,所以问题也就这么解决了。

总结

以上所述是小编给大家介绍的微信小程序自定义头部导航栏和导航栏背景图片 navigationStyle问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
JQuery实现鼠标移动到图片上显示边框效果
Jan 09 Javascript
js生成缩略图后上传并利用canvas重绘
May 15 Javascript
用JavaScript实现PHP的urlencode与urldecode函数
Aug 13 Javascript
使用jQuery调用XML实现无刷新即时聊天
Aug 07 Javascript
功能强大的jquery.validate表单验证插件
Nov 07 Javascript
js实现带简单弹性运动的导航条
Feb 22 Javascript
Vue2.0学习之详解Vue 组件及父子组件通信
Dec 12 Javascript
vue+springmvc导出excel数据的实现代码
Jun 27 Javascript
Vue 应用中结合vux使用微信 jssdk的方法
Aug 28 Javascript
js实现图片局部放大效果详解
Mar 18 Javascript
使用React代码动态生成栅格布局的方法
May 24 Javascript
详解vue3中组件的非兼容变更
Mar 03 Vue.js
jQuery-Citys省市区三级菜单联动插件使用详解
Jul 26 #jQuery
微信小程序—setTimeOut定时器的问题及解决
Jul 26 #Javascript
layUI实现三级导航菜单效果
Jul 26 #Javascript
layui实现三级联动效果
Jul 26 #Javascript
layui实现三级导航菜单
Jul 26 #Javascript
layui实现左侧菜单点击右侧内容区显示
Jul 26 #Javascript
详解nvm管理多版本node踩坑
Jul 26 #Javascript
You might like
《PHP编程最快明白》第二讲 数字、浮点、布尔型、字符串和数组
2010/11/01 PHP
php ajax confirm 删除实例详解
2019/03/06 PHP
Yii 框架使用数据库(databases)的方法示例
2020/05/19 PHP
不同浏览器对回车提交表单的处理办法
2010/02/13 Javascript
jQuery源码分析-01总体架构分析
2011/11/14 Javascript
拉动滚动条加载数据的jquery代码
2012/05/03 Javascript
javascript设计模式 接口介绍
2012/07/24 Javascript
打豆豆小游戏 用javascript编写的[打豆豆]小游戏
2013/01/08 Javascript
Extjs根据条件设置表格某行背景色示例
2014/07/23 Javascript
JavaScript中的闭包
2016/02/24 Javascript
jQuery绑定事件的四种方式介绍
2016/10/31 Javascript
基于JS实现的随机数字抽签实例
2016/12/08 Javascript
使用JSON格式提交数据到服务端的实例代码
2018/04/01 Javascript
JS实现将二维数组转为json格式字符串操作示例
2018/07/12 Javascript
JavaScript选择排序算法原理与实现方法示例
2018/08/06 Javascript
React Native开发封装Toast与加载Loading组件示例
2018/09/08 Javascript
laydate时间日历插件使用方法详解
2018/11/14 Javascript
解决微信小程序中转换时间格式IOS不兼容的问题
2019/02/15 Javascript
layui 关闭open弹出框 刷新table表格页面的方法
2019/09/16 Javascript
[26:24]完美副总裁、DOTA2负责人蔡玮专访:电竞如人生
2014/09/11 DOTA
Python找出list中最常出现元素的方法
2016/06/14 Python
Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例
2017/12/12 Python
python3将视频流保存为本地视频文件
2018/06/20 Python
Python 调用PIL库失败的解决方法
2019/01/08 Python
python面向对象实现名片管理系统文件版
2019/04/26 Python
基于logstash实现日志文件同步elasticsearch
2020/08/06 Python
Python eval函数介绍及用法
2020/11/09 Python
伦敦一家领先的精品零售商:IRIS Fashion
2019/05/24 全球购物
美国球迷装备的第一来源:FOCO
2020/07/03 全球购物
大学生学年自我鉴定
2014/02/10 职场文书
大学生职业生涯规划书
2014/03/14 职场文书
绿色小区申报材料
2014/08/22 职场文书
父亲节寄语大全
2015/02/27 职场文书
2015小学五年级班主任工作总结
2015/05/21 职场文书
详解盒子端CSS动画性能提升
2021/05/24 HTML / CSS
实现AJAX异步调用和局部刷新的基本步骤
2022/03/17 Javascript