詳解微信小程序膠囊按鈕返回|首頁自定義導航欄功能
項目代碼:https://github.com/Shay0921/header-navbar.git
在小程序中,從轉(zhuǎn)發(fā)出來的小程序消息卡片進入,因為頁面棧中只有一個,所以不會出現(xiàn)返回按鈕,對于一些電商平臺來說,當商品被轉(zhuǎn)發(fā)后會很影響客戶查看其它產(chǎn)品和首頁,這時候就需要使用自定義導航欄自己寫一個“膠囊按鈕”。如下圖所示:
從別的頁面點到商品頁時會有返回和首頁按鈕;
當從分享頁進入到商品頁時,因為頁面棧只有一個,所以只有首頁按鈕;
首先我們需要如何開啟自定義導航欄,查看手冊后會發(fā)現(xiàn)一個頁面配置項: navigationStyle
之前的版本此配置項只能在app.js中配置,是全局的屬性,而現(xiàn)在可以在單獨的頁面json中配置,實現(xiàn)單獨頁面自定義導航欄。
整體思路
當使用了 navigationStyle:custom
后,之前的頂部標題欄會被刪除,右側(cè)的膠囊按鈕則會固定在右上角。然后在當前頁面添加了三個view(狀態(tài)欄、標題欄、主體內(nèi)容),可以看出三塊的布局,我直接寫死的高度:狀態(tài)欄20px,標題欄44px。這個是自定義導航欄的關鍵,需要去計算這兩塊的高度,還有返回|首頁膠囊按鈕的位置。基礎庫 2.1.0開始可以使用 wx.getMenuButtonBoundingClientRect() 來獲得 右側(cè)膠囊按鈕的位置信息 ,而有了這個信息,就能相對的算出我們想要在左側(cè)添加的膠囊按鈕的位置。通過 wx.getSystemInfoSync()中的statusBarHeight找到狀態(tài)欄的高度 。
目錄結(jié)構(gòu)
├── components 組件 │ ├── headerNavbar 頂部自定義導航欄 │ │ └── headerNavbar.js │ │ └── headerNavbar.json │ │ └── headerNavbar.wxml │ │ └── headerNavbar.wxss ├── pages 頁面 │ ├── index 首頁 │ │ └── index.js │ │ └── index.json │ │ └── index.wxml │ │ └── index.wxss │ ├── navigationStyle 引入自定義導航欄的頁面(單獨配置了navigationStyle) │ │ └── navigationStyle.js │ │ └── navigationStyle.json │ │ └── navigationStyle.wxml │ │ └── navigationStyle.wxss │ │ └── testPage.js 路由測試頁面(后面用來測試跳轉(zhuǎn)顯示不同膠囊按鈕) │ │ └── testPage.json │ │ └── testPage.wxml │ │ └── testPage.wxss
全局變量
app.js
在app.js中要先獲得狀態(tài)欄高度和右側(cè)膠囊位置信息
App({ onLaunch: function (options) { // 這里省略掉了登錄和獲取用戶信息等函數(shù) // 因為我在別的頁面也需要使用此信息,所以沒有單獨獲得 statusBarHeight wx.getSystemInfo({ // 獲取設備信息 success: (res) => { this.globalData.systeminfo = res }, }) // 獲得膠囊按鈕位置信息 this.globalData.headerBtnPosi = wx.getMenuButtonBoundingClientRect() }, globalData: { systeminfo: {}, // 系統(tǒng)信息 headerBtnPosi: {} // 膠囊按鈕位置信息 } })
這里需要注意wx.getMenuButtonBoundingClientRect()
,并不是像wx.getSystmInfo一樣有success回調(diào)函數(shù),而是像對象一樣 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" src="/img/navbar_back_white.png"></image> <view wx:if='{{haveBack}}' class="floatL"></view> <image bindtap="_goHome" src="/img/navbar_home_white.png"></image> </view> </view> <!-- 手寫loading --> <view class="navbar-loading" style='height:{{navbarHeight}}px;line-height:{{navbarHeight}}px;'> <text>...</text> </view>
為了適配不同手機屏幕, 高度和膠囊按鈕的位置都需要在html里面賦值 ,下面會詳細的說明高度如何計算。在自定義導航欄組件中分為兩部分, 一個是頂部的導航欄另一個是自己寫的loading。
因為自定義導航欄是fixed到頂部的, 為了保證不擋住下面的主體內(nèi)容,我們需要在導航欄和主體內(nèi)容之間添加一個跟導航欄相同的高度 ,class先叫做box。這樣可以保證導航欄不擋著主體內(nèi)容。但是會出現(xiàn)另一個問題,如果此頁面支持下拉刷新, 那么導航欄會把小程序原生的loading樣式擋住,而在主體內(nèi)容的前面會出現(xiàn)一個空白的box,雖說不影響使用,但是在用戶看來會很奇怪,莫名其妙的多出來一塊,box只有在loading結(jié)束后才會上去 。所以在這里需要自己手寫一個loading的動畫效果放在組件的最底下,高度跟導航欄一樣。
可以看到下面的最終效果,藍色導航條下面的三個點是小程序原生loading,再下面三個小點是自己寫的loading。
而我們想要的效果則是,當小程序原生的loading被當時,自己寫的loading就可以替代原生的loading
headerNavbar.js
狀態(tài)欄高度 = app.globalData.systeminfo.statusBarHeight
需要注意 膠囊位置信息的原點是在頁面的左上角 ,所以需要轉(zhuǎn)換一下,把 原膠囊位置信息起名為膠囊,轉(zhuǎn)換后的叫做現(xiàn)膠囊。
/*** iphone6 的膠囊位置信息
* wx.getMenuButtonBoundingClientRect() 坐標信息以屏幕左上角為原點
* 膠囊寬度: 87
* 膠囊高度: 32
* 膠囊左邊界坐標: 278
* 膠囊上邊界坐標: 26
* 膠囊右邊界坐標: 365
* 膠囊下邊界坐標: 58
* 狀態(tài)欄高度:20*/
現(xiàn)膠囊上邊距 = 膠囊上邊界坐標 - 狀態(tài)欄高度
現(xiàn)膠囊右邊距 = 屏幕寬度 - 膠囊右邊界坐標
現(xiàn)膠囊下邊距 = 膠囊下邊界坐標 - 膠囊高度 - 狀態(tài)欄高度
導航欄高度 = 膠囊下邊界坐標 + 現(xiàn)膠囊下邊距
注意:膠囊下邊界坐標包含了 狀態(tài)欄、膠囊高度和狀態(tài)欄和膠囊高度之間的距離,因為膠囊是居中在導航欄里的 ,所以上邊距與下邊距應該一致,所以是 膠囊下邊界坐標 - 膠囊高度 - 狀態(tài)欄高度。
const app = getApp(); Component({ properties: { navbarData: { // 由父頁面?zhèn)鬟f的數(shù)據(jù) type: Object, value: {}, observer: function (newVal, oldVal) { } } }, data: { haveBack: true, // 是否有返回按鈕,true 有 false 沒有 若從分享頁進入則為 false statusBarHeight: 0, // 狀態(tài)欄高度 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 // 狀態(tài)欄高度 let headerPosi = app.globalData.headerBtnPosi // 膠囊位置信息 /** * wx.getMenuButtonBoundingClientRect() 坐標信息以屏幕左上角為原點 * 菜單按鍵寬度: 87 * 菜單按鍵高度: 32 * 菜單按鍵左邊界坐標: 278 * 菜單按鍵上邊界坐標: 26 * 菜單按鍵右邊界坐標: 365 * 菜單按鍵下邊界坐標: 58 */ let btnPosi = { // 膠囊實際位置,坐標信息不是左上角原點 height: headerPosi.height, width: headerPosi.width, // 膠囊top - 狀態(tài)欄高度 top: headerPosi.top - statusBarHeight, // 膠囊bottom - 膠囊height - 狀態(tài)欄height (現(xiàn)膠囊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 + 現(xiàn)膠囊bottom navbarBtn: btnPosi }) }, methods: { _goBack: function () { wx.navigateBack({ delta: 1 }); }, _goHome: function () { wx.switchTab({ url: '/pages/index/index', }); } } })
通過 getCurrentPages()
來判斷當前頁面是否從分享頁進入, 因為如果從分享頁進入頁面棧中應該只有一條數(shù)據(jù),在跳轉(zhuǎn)到其他頁面時頁面棧的length則會增加 ,在其他頁面就會顯示出返回和首頁按鈕。
注意:微信7.0.0支持wx.getMenuButtonBoundingClientRect(),
如果想兼容低版本的微信,只能把導航欄的高度寫死,通過一些大佬的計算得出的高度:
'iPhone': 64,
'iPhone X': 88,
'android': 68
具體查看:
https://developers.weixin.qq.com/community/develop/doc/0006c012dc8028f04b070dd0551004
如果你使用 wx.getMenuButtonBoundingClientRect()
得到信息有小數(shù) ,如下所示
{height: 24, width: 65.25, top: -0.5, bottom: -0.5, right: 101.25}
那么你可能是把開發(fā)工具中的視圖縮放了,還原成100%就正常了。
headerNavbar.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; }
引用組件頁面代碼
navigationStyle.json
{ "navigationStyle": "custom", "enablePullDownRefresh": true, "backgroundTextStyle": "light", "usingComponents": { "headerNavbar": "/components/headerNavbar/headerNavbar" } }
先在需要使用自定義導航欄的頁面json中添加navigationStyle:custom
enablePullDownRefresh: true 開啟下拉刷新
backgroundTextStyle: light是把loading的樣式改成白色,這樣就不會顯示出來loading的三個點
navigationStyle.wxml
<headernavbar navbar-data="{{nvabarData}}"></headernavbar> <view class="home-page"> <text> 上面是自定義導航欄↑↑↑ </text> <text> 下面是主體內(nèi)容↓↓↓ </text> <navigator url="./testPage"> 跳轉(zhuǎn)到測試頁 </navigator> </view>
navigationStyle.js
Page({ data: { // 組件所需的參數(shù) nvabarData: { showCapsule: 1, // 是否顯示左上角膠囊按鈕 1 顯示 0 不顯示 title: '組件列表' // 導航欄 中間的標題 } }, onPullDownRefresh() { setTimeout(() = >{ wx.stopPullDownRefresh(); // 停止下拉 }, 2000); }, })
注意:雖說這么做在小程序開發(fā)工具中看起來都是對的,得到的導航欄高度也是64px但是在真機上測試后,還是有偏差,在iphone8 plus上高度是60px。
可以通過這張圖明顯看到差了幾px,如果你是單獨幾個頁面使用自定義導航,細心的用戶可能會發(fā)現(xiàn),但是基本不影響。如果是全局使用自定義導航,那就不存在這個問題了。
項目代碼:https://github.com/Shay0921/header-navbar.git
總結(jié)
以上所述是小編給大家介紹的詳解微信小程序膠囊按鈕返回|首頁自定義導航欄功能,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復大家的!
- 微信小程序?qū)崿F(xiàn)可拖動懸浮圖標(包括按鈕角標的實現(xiàn))
- 微信小程序?qū)㈨撁姘粹o懸浮固定在底部的實現(xiàn)代碼
- 微信小程序點擊按鈕動態(tài)切換input的disabled禁用/啟用狀態(tài)功能
- 微信小程序中的video視頻實現(xiàn) 自定義播放按鈕、封面圖、視頻封面上文案
- 微信小程序?qū)崿F(xiàn)單個卡片左滑顯示按鈕并防止上下滑動干擾功能
- 微信小程序批量監(jiān)聽輸入框?qū)Π粹o樣式進行控制的實現(xiàn)代碼
- 微信小程序 多行文本顯示...+顯示更多按鈕和收起更多按鈕功能
- 微信小程序按鈕點擊動畫效果的實現(xiàn)
- 操作按鈕懸浮固定在微信小程序底部的實現(xiàn)代碼
- 微信小程序mpvue點擊按鈕獲取button值的方法
- 微信小程序單選radio及多選checkbox按鈕用法示例
- 微信小程序開發(fā)之點擊按鈕退出小程序的實現(xiàn)方法
- 微信小程序按鈕巧妙用法
相關文章
javascript框架設計讀書筆記之數(shù)組的擴展與修復
本文是司徒正美的《javascript框架設計》的第三章第2節(jié)的讀書筆記,本節(jié)主要介紹的是javascript數(shù)組的擴展與修復,本文則是選取了其中的重點部分展示給大家。2014-12-12js+html5獲取用戶地理位置信息并在Google地圖上顯示的方法
這篇文章主要介紹了js+html5獲取用戶地理位置信息并在Google地圖上顯示的方法,涉及html5元素的操作技巧,需要的朋友可以參考下2015-06-06微信小程序wx.navigateTo中events屬性實現(xiàn)頁面間通信傳值,數(shù)據(jù)同步
這篇文章主要介紹了微信小程序wx.navigateTo中events屬性實現(xiàn)頁面間通信傳值,數(shù)據(jù)同步,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-07-07