微信小程序 自定义头部导航栏和导航栏背景图片 navigationStyle
这两天因为要做一个带背景的小程序头,哭了,小程序导航栏有背景也就算了,还得让导航栏上的背景顺下来,心态小崩。现在可以单独设置一个页面的小程序头了,但是前提是要微信7.0以上的版本,考虑到兼容性问题,还是不要贸然的上了,所以用老版本的替换所有页面的小程序头来做。
参考了jiuyucha的文章,但是没有解决自定义背景的和返回按钮的颜色的问题,还有因为IOS的橡皮筋效果,对IOS端不太友好,屏幕会乱划。所以针对性的改动了这些功能,因为才学小程序两三天,所以其中踩了很多坑,但好在最后效果还是达到了。
下面是效果图:
原理其实就是通过将原来的头禁用,然后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.组件配置
组件结构:
放源码吧
// 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的更多相关文章
- 微信小程序自定义头部导航栏
<!--index.wxml--> <view> <navbar id='index_header' background='{{background}}' pageNa ...
- 微信小程序——自定义导航栏
微信头部导航栏可能通过json配置: 但是有时候我们项目需求可能需要自定义头部导航栏,如下图所示: 现在具体说一下实现步骤及方法: 步骤: 1.在 app.json 里面把 "navigat ...
- 微信小程序 自定义导航组件 nav头部 全面屏设计
nav-dynamic 微信小程序自定义nav头部组件:适配全面屏设计: 实现功能 初始进入页面时,展示初始状态下的nav样式: 页面滚动时,监听页面滚动事件,展示滚动状态下的nav样式: 根据配置字 ...
- 微信小程序-自定义底部导航
代码地址如下:http://www.demodashi.com/demo/14258.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.co ...
- 微信小程序自定义弹窗wcPop插件|仿微信弹窗样式
微信小程序自定义组件弹窗wcPop|小程序消息提示框|toast自定义模板弹窗 平时在开发小程序的时候,弹窗应用场景还是蛮广泛的,但是微信官方提供的弹窗比较有局限性,不能自定义修改.这个时候首先想到的 ...
- 微信小程序自定义 tabbar
一定的需求情况下,无法使用小程序原生的 tabbar 的时候,需要自行实现一个和 tabbar 功能一模一样的自制组件. 查阅了海量的博客和文档之后,亲自踩坑.总结了三种在不使用微信小程序原生 tab ...
- 微信小程序自定义tabbar的实现
微信小程序自定义tabbar的实现 目的:当采用微信的自定义tabbar组件的时候,切换的时候会出现闪屏的效果:当使用微信默认的tabbar的时候,限制了tabbar的数量以及灵活配置. 方案:自己动 ...
- 微信小程序自定义组件,提示组件
微信小程序自定义组件,这里列举了一个常用的提示自定义组件,调用自定义组件中的方法和字段.仅供参考和学习. 编写组件: 在根目录下添加“components”目录,然后像添加Page页面一样添加自定义组 ...
- 微信小程序自定义Tabber,附详细源码
目录 1,前言 2,说明 3,核心代码 1,前言 分享一个完整的微信小程序自定义Tabber,tabber按钮可以设置为跳转页面,也可以设置为功能按钮.懒得看文字的可以直接去底部,博主分享了小程序代码 ...
随机推荐
- scala 语法速查
摘自官网 variables var x = 5 Good x = 6 Variable. val x = 5 Bad x = 6 Constant. var x: Double = 5 Expl ...
- FOLDER
一.建noTab的Folder Form:1.创建数据库对象: create table 和相应的view. 2.基于模板Template.fmb创建一个新的Form:****.fmb 添加一个 ...
- GIL全局解释器锁、死锁、递归锁、线程队列
目录 GIL全局解释锁 多线程的作用 测试计算密集型 IO密集型 死锁现象 递归锁 信号量(了解) 线程队列 GIL全局解释锁 GIL本质上是一个互斥锁. GIL是为了阻止同一个进程内多个进程同时执行 ...
- 渗透测试学习 二十一、 JSP相关漏洞
大纲 ST2漏洞 (Struts2) 反序列漏洞 网站容器,中间键 其他漏洞 Struts2漏洞 简介: Struts2是一个基于MVC设计模式的Web应用框架,它本质上相 ...
- requests---发送post请求完成登录
前段时间写过一个通过cookies完成登录,今天我们写一篇通过post发送请求完成登录豆瓣网 模拟登录 1.首先找到豆瓣网的登录接口 打开豆瓣网站的登录接口,请求错误的账号密码,通过F12或者抓包工具 ...
- 解决汉化pycharme之后设置打不开的问题
首先进入安装pycharme目录下lib目录下,将汉化包移出去,只留下英文包 然后打开pycharme即可打开设置 在你改完设置之后,可以再将汉化包放进来 英文包:https://pan.baidu. ...
- Jmeter之BeanShell
在Jmeter中各种分类组件中都有相应的BeanShell组件,这里简单的说明一下Beanshell的使用. 一.概念 BeanShell是一种符合Java语法的脚本语言,也有自己的一些特定语法 二. ...
- python线程类的start()和run()
start()方法: 开始线程活动. 对每一个线程对象来说它只能被调用一次,它安排对象在一个另外的单独线程中调用run()方法,而非当前所处的线程,当该方法在同一个线程对象中被调用超过一次时,会引入R ...
- mysql 插入表情数据报错
mysql 插入表情数据报错 1.编码类型改成:utf8mb4 2.连接类型也要改成:utf8mb4_general_ci 3.在每个保存的前面执行一次 self.cursor.execute('SE ...
- Vue.js面试整理
Vue项目结构介绍 build 文件夹:用于存放 webpack 相关配置和脚本. config 文件夹:主要存放配置文件,比如配置开发环境的端口号.开启热加载或开启gzip压缩等. dist 文件夹 ...