注意:支付宝 10.3.60 版本(2023-03)对小程序导航栏进行了,本文内容面向 10.3.60 及以上的版本。关于新旧版本差异及适配方法,请参考《导航栏行为升级开发者适配指南》。
一、默认导航栏
1.1 简介
小程序的导航栏由状态栏和标题栏组成。如图所示,第一行包括手机电量和时间的区域,叫状态栏;第二行“标题 按钮”区域统称为标题栏。
1.2 导航栏按钮
导航栏按钮的展现和行为依赖于运行时页面栈状态,描述如下表:
按钮 | 展示规则 | 响应行为 | 去除或隐藏 | 点击监听 | 布局信息 |
---|---|---|---|---|---|
返回 |
始终展示 |
|
不支持 |
my.getleftbuttonsboundingclientrect() | |
返回凯发k8官方网娱乐官方首页 | 页面栈深度等于 1,且当前页面为非凯发k8官方网娱乐官方首页、非 tabbar 页面 | 跳转到小程序凯发k8官方网娱乐官方首页,相当于 my.relaunch | my.hidebackhome() | 不支持 | my.getleftbuttonsboundingclientrect() |
收藏、已收藏 | 始终展示 注:支付宝客户端 10.1.95 及以上版本中,符合准入规则的小程序,默认右上角会显示“添加到凯发k8官方网娱乐官方首页”按钮,否则展示“收藏按钮”。准入规则暂不对外。 |
收藏/取消收藏当前小程序 | 不支持 | 不支持 | my.getmenubuttonboundingclientrect() |
胶囊按钮 - 菜单 | 始终展示 | 弹出小程序菜单 | 不支持 | 不支持点击监听,但可通过 my.iscollected() 获取是否收藏。 | my.getmenubuttonboundingclientrect() |
胶囊按钮 - 收起 | 始终展示 | 直接回退至支付宝凯发k8官方网娱乐官方首页,小程序切换到后台运行并可以从凯发k8官方网娱乐官方首页⊕入口复访 | 不支持 | 不支持 | my.getmenubuttonboundingclientrect() |
其中关于页面栈的判断,可通过 getcurrentpages().length 获取当前页面栈中的页面数量(即“页面栈深度”)。
路由 api 的影响
使用不同的路由 api 跳转,会对页面栈产生不同的影响 点击了解详情。结合以上按钮特性可知:
- 当使用 my.relaunch(),或页面栈数量等于 1 时使用 my.redirectto(),跳转到非凯发k8官方网娱乐官方首页、非 tabbar 页面时会展示“返回凯发k8官方网娱乐官方首页” 按钮。
- 当使用 my.navigateto(),或当页面栈数量大于 1 时使用 my.redirectto() 跳转,一定会展示返回按钮。凯发k8官方网娱乐官方首页是否展示返回按钮,以导航行为是否升级为准。
1.3 导航栏标题
文字标题
可在 app.json
或 page.json
中配置 defaulttitle
,也可使用 my.setnavigationbar() 设置入参 title
。若当前页面没有配置,则以 app.json
中的配置为主,否则以当前页面为主。
// 若在 app.json 中的 window 中配置,则对全局页面生效
"window": {
"defaulttitle": "全局项目"
},
// 若在 page.json 中配置,则对当前页面生效
{
"defaulttitle": "当前页面",
}
// 也可以使用 my.setnavigationbar() 设置当前页面的标题
my.setnavigationbar({
title: '当前页面'
})
图片标题
导航栏的标题,也可以用一张图片表示。需传入 https://
开头的图片链接地址。
可在 app.json
或 page.json
中配置 titleimage
,也可使用 my.setnavigationbar() 设置入参 image
。
注:图片标题的优先级大于文字标题。即若对同一个页面即设置了图片标题,又设置了文字标题,则只有图片标题会生效。
// 在 app.json 中的 window 中配置,对所有页面生效
"window": {
"titleimage": "https://mdn.alipayobjects.com/huamei_esgcm9/afts/img/a*phqft4oze_eaaaaaaaaaaaaadsajaq/original"
},
// 在 page.json 中配置,仅对当前页面生效
// 优先级高于 app.json 中的配置
{
"titleimage": "https://mdn.alipayobjects.com/huamei_esgcm9/afts/img/a*phqft4oze_eaaaaaaaaaaaaadsajaq/original",
}
// 也可以使用 my.setnavigationbar() 设置当前页面的图片标题
my.setnavigationbar({
image: 'https://mdn.alipayobjects.com/huamei_esgcm9/afts/img/a*phqft4oze_eaaaaaaaaaaaaadsajaq/original'
})
1.4 导航栏颜色
导航栏背景色
导航栏背景色决定了状态栏和标题栏的背景色。
可在 app.json
或 page.json
通过 titlebarcolor
配置,也可使用 my.setnavigationbar() 通过入参 backgroundcolor
设置。
注:若 app.json
中没有配置 titlebarcolor
,而某一页面的 page.json
中做过配置,则从它路由跳转到达的目标页面会沿用该配置,如果该目标页面自己没有配置的话。
// 若在 app.json 中的 window 中配置,则对全局页面生效
"window": {
"titlebarcolor": "#ffffff"
},
// 若在 page.json 中配置,则对当前页面生效
// 优先级高于 app.json 中的配置
{
"titlebarcolor": "#ffffff"
}
// 也可以使用 my.setnavigationbar() 设置当前页面的导航栏的背景色
my.setnavigationbar({
backgroundcolor: "#ffffff"
})
导航栏前景色
导航栏前景色决定了状态栏文字、按钮、标题文字的颜色。
导航栏前景色可使用 my.setnavigationbar() 通过入参 frontcolor
设置,从支付宝 10.5.30 开始,也可通过 app.json
或 page.json
中的 navigationbarfrontcolor
设置。
注:
frontcolor
必须和backgroundcolor
一起设置才能生效;- 导航栏背景色会影响导航栏前景色。若只设置导航栏背景色,则当背景色为
#ffffff
时前景色为黑色,否则前景色为白色。
// 若在 app.json 中的 window 中配置,则对全局页面生效
"window": {
"navigationbarfrontcolor": "white"
},
// 若在 page.json 中配置,则对当前页面生效
{
"navigationbarfrontcolor": "white"
}
// 也可以使用 my.setnavigationbar() 设置当前页面的导航栏的前景色
my.setnavigationbar({
frontcolor: '#ffffff',
backgroundcolor: '#000000'
})
导航栏底部边框颜色
可使用 my.setnavigationbar() 通过入参 borderbottomcolor
设置。
注:若设置了backgroundcolor
,则borderbottomcolor
不再生效,默认会和backgroundcolor
颜色一样。
my.setnavigationbar({
borderbottomcolor: "#000000"
})
二、自定义导航栏
在实际开发中,默认导航栏可能并不能满足开发者的需求,比如导航栏背景色不支持渐变色等,这时候就需要自定义导航栏。
2.1 如何自定义
首先,在 app.json
或 page.json
中配置以下两个字段,让导航栏透明显示,并允许导航栏点击穿透。
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
transparenttitle | string | "none" | 导航栏透明设置。 "none":标题栏区域完全不透明 "always":标题栏区域完全透明 "auto":标题栏背景根据页面滚动距离自动控制渐变 |
titlepenetrate | string | "no" | 是否允许导航栏点击穿透。 |
然后,通过 my.getsysteminfosync() 中的 titlebarheight
和 statusbarheight
字段获取标题栏和状态栏的高度,在 .axml 中给自己定义的组件设置相应高度,从而进行自定义开发。
注意:设置透明导航栏后,导航栏的按钮,标题依然存在。依然可通过他们的展示或设置规则进行设置,从而达到预期的效果。
2.2 示例代码
2.2.1 背景色为渐变色的导航栏样式
.json 示例代码
{
"transparenttitle": "always",
"titlepenetrate": "yes", // 允许点击穿透后,才能触发导航栏上的 ontap 事件
"defaulttitle": "", // 将导航栏默认的 title 置空
"titlebarcolor": "#000000" // 虽然设置导航栏背景色不生效,但可以影响前景色为白色
}
.js 示例代码
page({
data: {
titlebarheight: 0,
statusbarheight: 0,
},
onload(options) {
// 获取手机基础信息(头状态栏和标题栏高度)
const {
titlebarheight,
statusbarheight,
} = my.getsysteminfosync();
this.setdata({
titlebarheight,
statusbarheight,
});
},
//点击手机标题栏触发的事件,需要在 index.json 配置 titlepenetrate:"yes"
ontitlebar(e) {
console.log('点击了标题栏');
}
});
.axml 示例代码
hi,我是自定义标题~
.acss 示例代码
.custom-nav {
background-image: linear-gradient(to bottom, #bc3985, #d15b2c);
}
.custom-titlebar {
display: flex;
align-items: center;
color: white;
font-size: 16px;
margin-left: 16px;
}
2.2.2 实现 "transparenttitle": "auto" 效果
透明导航栏 auto
模式的效果为:前景色默认为白色,当页面上滑时,出现背景色为白色,前景色为黑色的导航栏。
但当同时设置导航栏颜色时(如配置了 titlebarcolor
),就会覆盖 auto
模式的效果。
如何既配置 titlebarcolor
,又拥有 auto
模式的默认效果呢? 一种实现方式如下:
// 使用 jsapi 在页面滑动时对导航栏颜色进行动态设置
onpagescroll({ scrolltop }) {
if (scrolltop > 60) {
my.setnavigationbar({
backgroundcolor: '#ffffff’, // 背景色会影响前景色,相当于设置前景色为黑色
})
} else {
my.setnavigationbar({
backgroundcolor: '#f5f5f5’, // 相当于设置前景色为白色
})
}
}