微信小程序胶囊按钮 返回 |首页自定义导航栏详解
在小程序中,进入消息卡转发的小程序。由于只有一叠页面,因此没有显示返回按钮。一些电商平台表示,产品一旦发货,就会极大地影响顾客查看其他产品和首页的方式。目前,您必须使用自定义导航栏自己编写“胶囊按钮”。如下图所示:
当您从其他页面点击产品页面时,会出现后退和主页按钮;
从分享页面进入商品页面时,由于只有一叠页面,所以只有一个home键;
首先我们需要启用自定义导航栏。查看指南后,我们发现页面配置项:navigationStyle
在之前的版本中,这个配置项只能在app.js中配置,并且是一个全局属性。但现在它可以配置为单独页面 json 格式来实现单独页面的自定义导航栏。
总体思路
如果使用navigationStyle:custom,则会删除之前的顶部标题栏,并将右侧的胶囊按钮固定在右上角。然后,我向当前页面添加了三个视图(状态栏、标题栏和正文内容)。您将看到三个块的布局。我直接编程了高度:状态栏20px,标题栏44px。这是定制导航栏的关键。你需要计算这两个块的高度和返回位置 |主页胶囊按钮。从Basic Library 2.1.0版本开始,您可以使用命令wx.getMenuButtonBoundingClientRect()来获取❝右侧胶囊按钮的位置信息。从这些信息我们就可以相对计算出我们想要做什么。在左侧添加了胶囊按钮位置。通过 wx.getSystemInfoSync() 中的 statusBarHeight 求出状态栏的高度。 ?有wx.getSystmInfo这样成功的回调函数,但是是作为对象使用的wx.getMenuButtonBoundingClientRect().height。 组件代码
headerNavbar.wxml
<!-- 自定义导航栏 -->
<view class='navbar-wrap'
style='height:{{navbarHeight}}px;padding-top:{{statusBarHeight}}px;'>
<view class="navbar-text"
style='line-height:{{navbarBtn.height + navbarBtn.top}}px;'>
{{navbarData.title ? navbarData.title : "默认标题"}}{{navbarHeight}}
</view>
<view class="navbar-icon"
wx:if='{{navbarData.showCapsule ? navbarData.showCapsule : true}}'
style="top:{{navbarBtn.top + statusBarHeight}}px;left:{{navbarBtn.right}}px;height:{{navbarBtn.height}}px;">
<image wx:if='{{haveBack}}' bindtap="_goBack" class="floatL" ></image>
<view wx:if='{{haveBack}}' class="floatL"></view>
<image bindtap="_goHome" ></image>
</view>
</view>
<!-- 手写loading -->
<view class="navbar-loading" style='height:{{navbarHeight}}px;line-height:{{navbarHeight}}px;'>
<text>...</text>
</view>复制代码
为了适应不同的手机屏幕,高度和胶囊按钮位置值必须在♸ HTML 中设置。下面详细解释一下高度是如何计算的。自定义导航栏组件分为两部分,一个是顶部的导航栏,另一个是我写的加载。
由于自定义导航栏固定在顶部,为了保证下面的主要内容不被遮挡,我们需要在导航栏和主要内容之间添加一个与导航栏相同的高度 ,第一类这称为盒子。这样可以确保导航栏不会遮挡主要内容。但还有另一个问题。如果此页面支持下拉刷新,将阻止导航栏小部件加载样式,并且主要内容前面会出现一个空框。虽然不影响使用,但是对于用户来说却显得很陌生。莫名其妙多了一块,装完箱子才升起。所以这里需要手动编写加载动画效果并将其放置在组件底部与导航栏同高。
你可以看到下面的最终效果。蓝色导航栏下面的三个点是小程序的bootstrap,下面的三个点是你自己写的bootstrap。
我们希望当小程序bootstrap被删除时,我们的自定义加载器可以替换bootstrap
headerNavbar.js
HeaderNavbar height = app.globalData.systeminfo。 statusBarHeight
需要注意的是,的胶囊位置信息的原点是在页面的左上角,所以需要进行转换。 原始胶囊位置信息称为胶囊,变换后的信息称为当前胶囊。
/*** iphone6 的胶囊位置信息
* wx.getMenuButtonBoundingClientRect() 坐标信息以屏幕左上角为原点
* 胶囊宽度: 87
* 胶囊高度: 32
* 胶囊左边界坐标: 278
* 胶囊上边界坐标: 26
* 胶囊右边界坐标: 365
* 胶囊下边界坐标: 58
* 状态栏高度:20*/复制代码
活动胶囊上边距 = 胶囊上边框坐标 - 状态栏高度
活动胶囊右边距 = 屏幕宽度 - 胶囊右边框坐标
当前胶囊下边距 = 底部坐标胶囊边框 - 胶囊高度 - 状态栏高度
导航栏高度 = 胶囊底部边框坐标 + 当前胶囊高度下边距
注:胶囊底部边框坐标包括 状态栏、胶囊高度和距离状态栏和胶囊高度之间,由于胶囊位于导航栏的中间,所以上边距和下边距应该是均匀的,所以这些就是胶囊下边框的坐标 - 胶囊的高度- 状态栏的高度。
const app = getApp();
Component({
properties: {
navbarData: { // 由父页面传递的数据
type: Object,
value: {},
observer: function (newVal, oldVal) { }
}
},
data: {
haveBack: true, // 是否有返回按钮,true 有 false 没有 若从分享页进入则为 false
statusBarHeight: 0, // 状态栏高度
navbarHeight: 0, // 顶部导航栏高度
navbarBtn: { // 胶囊位置信息
height: 0,
width: 0,
top: 0,
bottom: 0,
right: 0
}
},
// 微信7.0.0支持wx.getMenuButtonBoundingClientRect()获得胶囊按钮高度
attached: function () {
let statusBarHeight = app.globalData.systeminfo.statusBarHeight // 状态栏高度
let headerPosi = app.globalData.headerBtnPosi // 胶囊位置信息
/**
* wx.getMenuButtonBoundingClientRect() 坐标信息以屏幕左上角为原点
* 菜单按键宽度: 87
* 菜单按键高度: 32
* 菜单按键左边界坐标: 278
* 菜单按键上边界坐标: 26
* 菜单按键右边界坐标: 365
* 菜单按键下边界坐标: 58
*/
let btnPosi = { // 胶囊实际位置,坐标信息不是左上角原点
height: headerPosi.height,
width: headerPosi.width,
// 胶囊top - 状态栏高度
top: headerPosi.top - statusBarHeight,
// 胶囊bottom - 胶囊height - 状态栏height (现胶囊bottom 为距离导航栏底部的长度)
bottom: headerPosi.bottom - headerPosi.height - statusBarHeight,
// 屏幕宽度 - 胶囊right
right: app.globalData.systeminfo.screenWidth - headerPosi.right
}
let haveBack;
if (getCurrentPages().length === 1) { // 当只有一个页面时
haveBack = false;
} else {
haveBack = true;
}
this.setData({
haveBack: haveBack, // 获取是否是通过分享进入的小程序
statusBarHeight: statusBarHeight,
navbarHeight: headerPosi.bottom + btnPosi.bottom, // 原胶囊bottom + 现胶囊bottom
navbarBtn: btnPosi
})
},
methods: {
_goBack: function () {
wx.navigateBack({
delta: 1
});
},
_goHome: function () {
wx.switchTab({
url: '/pages/index/index',
});
}
}
})
复制代码
使用 getCurrentPages() 判断当前页是否是从共享页插入的, 因为从共享页插入时,页栈中应该只有一个数据项,其长度会随着页数的增加而增加堆栈跳转到其他页面,其他页面上显示后退和主页按钮。
注意。微信7.0.0支持wx.getMenuButtonBoundingClientRect()。如果想兼容低版本的微信,可以硬编码导航栏的高度。一些专家计算出的高度:
'iPhone': 64,
'iPhone 551004
当您使用wx.getMenuButton时,有Rect(BoundingClien)信息如下图 { 高度: 24,宽度:65.25,顶部:-0.5,底部:-0.5,右侧:101.25}
然后你可能在开发工具中缩放了视图并将其恢复到100%,那么它应该是正常的。
headeNavBar.wxss
.navbar-wrap {
position: fixed;
width: 100%;
top: 0;
z-index: 9999999;
background-color: #3281FF;
box-sizing: border-box;
}
.navbar-text {
text-align: center;
font-size: 36rpx;
color: #fff;
font-weight: 600;
}
.navbar-icon {
position: fixed;
display: flex;
border-radius: 64rpx;
border: 0.5px solid rgba(255,255,255, 0.3);
box-sizing: border-box;
}
.navbar-icon image {
height: 20px;
width: 20px;
padding: 5px 10px 10px;
display: inline-block;
overflow: hidden;
}
.navbar-icon view {
height: 18px;
border-left: 0.5px solid rgba(255,255,255, 0.3);
margin-top: 6px;
}
.navbar-loading {
background: #fff;
text-align: center;
}
复制代码
Reference组件页面代码
NAvigationStyle.json
{
"navigationStyle": "custom",
"enablePullDownRefresh": true,
"backgroundTextStyle": "light",
"usingComponents": {
"headerNavbar": "/components/headerNavbar/headerNavbar"
}
}
复制代码
首先添加导航风格:custom
reef-reush-reush:d trueshrewnabletrueshrewnable背景textStyle:灯光将加载样式更改为白色,因此不显示加载点
navigationStyle.wxml
<headernavbar navbar-data="{{nvabarData}}"></headernavbar>
<view class="home-page">
<text>
上面是自定义导航栏↑↑↑
</text>
<text>
下面是主体内容↓↓↓
</text>
<navigator url="./testPage">
跳转到测试页
</navigator>
</view>
复制代码
navigationStyle.js
Page({
data: {
// 组件所需的参数
nvabarData: {
showCapsule: 1,
// 是否显示左上角胶囊按钮 1 显示 0 不显示
title: '组件列表' // 导航栏 中间的标题
}
},
onPullDownRefresh() {
setTimeout(() = >{
wx.stopPullDownRefresh(); // 停止下拉
},
2000);
},
})
复制代码
注意。虽然在小程序开发工具中可以看到,但一切似乎都是正确的。生成的导航栏高度也是 64 像素。但在真机上测试后发现存在异常值。 iPhone8 Plus的高度为60像素。
这张图片清楚地显示了几个像素的差异。如果在多个单独的页面上使用自定义导航,细心的用户可能会注意到,但基本上不受影响。如果您全局使用自定义导航,则不会出现此问题。
项目代码:https://github.com/Shay0921/header-navbar.git
作者:Shay Liu Xinyu
链接:https://juejin.im/post/5d02021958aab来源:Dig Kim
版权归作者所有。商业转载请联系作者获取授权。非商业转载请注明出处。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。