微信小程序自定義導(dǎo)航欄實(shí)例代碼
背景
在做快狗打車小程序時,關(guān)于默認(rèn)導(dǎo)航欄,我們遇到了以下的問題:
- Android、IOS手機(jī)對于頁面title的展示不一致,安卓title的顯示不居中
- 頁面的title只支持純文本級別的樣式控制,不能夠做更豐富的title效果
- 左上角的事件無法監(jiān)聽、定制
- 路由導(dǎo)航單一,只能夠返回上一頁,深層級頁面的返回不夠友好
我們希望的是:在各個機(jī)型頁面上title一致性 & 個性化展示、取得左上角點(diǎn)擊事件控制權(quán)及深層級頁面的一鍵返回
實(shí)現(xiàn)
step1 自定義
第一步 取得導(dǎo)航欄的控制權(quán)
小程序支持自定義導(dǎo)航欄,只需要在app.json文件中,window項(xiàng)中配置
"navigationStyle": "custom"
這樣微信就放開了導(dǎo)航欄的控制權(quán),只保留右上角的膠囊。
頁面會從視窗的頂部開始渲染,如圖

接下來,我們要做的就是實(shí)現(xiàn)一個導(dǎo)航欄組件,把它放置在頁面原來的默認(rèn)導(dǎo)航欄的位置,內(nèi)容什么的完全由開發(fā)者自己定制。
step2 功能點(diǎn)
第二步 梳理導(dǎo)航欄的功能點(diǎn)
- 導(dǎo)航欄高度(各個機(jī)型動態(tài)適配)
- 導(dǎo)航欄內(nèi)容定制
- 所有機(jī)型title居中顯示(自己布局實(shí)現(xiàn))
- 首頁導(dǎo)航欄左上角顯示個人中心、中部title使用個性圖標(biāo)
- 嵌套頁面左上角顯示返回上一頁 + 回到首頁按鈕
- 非常規(guī)首頁左上角顯示回到首頁按鈕
導(dǎo)航欄高度 包含兩個部分:工具欄和title欄, 工具欄的高度一般是固定的20px,title欄的高度需要計(jì)算
導(dǎo)航欄內(nèi)容的定制,需要識別當(dāng)前頁面的性質(zhì),根據(jù)不同的頁面展示不同的內(nèi)容,可以通過獲取當(dāng)前的頁面路由棧來判定當(dāng)前的頁面性質(zhì)

step3 導(dǎo)航欄組件基本結(jié)構(gòu)
目前快狗打車小程序的基本結(jié)構(gòu)
// navBar.wxml <cover-view class='place-holder'></cover-view> <cover-view class='nav-bar'> <cover-view class='tool-bar' style='height: 20px'></cover-view> <cover-view class='title-bar'> <cover-view class='left-cell'> // scene0 常規(guī)首頁 個人中心按鈕 // scene1 非常規(guī)首頁 回首頁按鈕 // scene2 嵌套頁 返回上一頁按鈕 + 回首頁按鈕 </cover-view> <cover-view class='center-cell'> // scene0 常規(guī)首頁 個性化title // scene1 其他頁 正常title </cover-view> <cover-view class='right-cell'> // 占位用的 </cover-view> </cover-view> </cover-view>
Tips:
組件內(nèi)多了一個占位的place-holder塊,是因?yàn)槟承╉撁嬗蓄愃茲L動列表的需求,要保證導(dǎo)航欄始終在視窗的頂部的話,需要使用定位,定位之后脫離文檔流,在最初的時候需要占位塊保證后續(xù)的頁面內(nèi)容不會被導(dǎo)航欄遮擋
使用cover-view布局是因?yàn)榭旃返臉I(yè)務(wù)中有類似map的原生組件,使用view的話有被遮擋的風(fēng)險
step4 高度計(jì)算
需要計(jì)算title-bar的高度
在 默認(rèn)導(dǎo)航欄 & 無底部tab欄 的情況下,使用wx.getSystemInfoSync獲取手機(jī)信息,可以看到兩項(xiàng)信息:
- screenHeight 屏幕高度,單位px
- windowHeight 可使用窗口高度,單位px
這種情況下,二者的差值就是默認(rèn)的導(dǎo)航欄的高度, 但是在設(shè)置了"navigationStyle": "custom"之后,二者的值是一樣的了,因此導(dǎo)航欄的高度我們需要使用統(tǒng)計(jì)的經(jīng)驗(yàn)值。
根據(jù)統(tǒng)計(jì),得到如下的結(jié)果:
{
'iPhone': 64,
'iPhoneX': 88,
'Android': 68,
'samsung': 72
}
工具欄的高度可根據(jù)wx.getSystemInfoSync返回值中的statusBarHeight獲取。
至此,我們得到了導(dǎo)航欄的相關(guān)的高度值
// 導(dǎo)航欄總高度 & 占位塊高度
placeHoder = totalBar = {
'iPhone': 64,
'iPhoneX': 88,
'Android': 68,
'samsung': 72
}
// 時間、信號等工具欄的高度
toolBar = systermInfo.statusBarHeight
// 頁面title欄的高度
titleBar = totalBar - toolBar
step5 內(nèi)容定制
在組件的生命周期函數(shù)attached中,我們可以獲取當(dāng)前的頁面路由棧
let pages = getCurrentPages() let current_page = pages[pages.length - 1].route const NORMAL_ENTRY = '常規(guī)的入口頁路徑' // scene 0 常規(guī)入口頁 個性化title、個人中心 pages.length === 1 && current_page === NORMAL_ENTRY // scene 1 非常規(guī)入口頁 回首頁 pages.length === 1 && current_page !== NORMAL_ENTRY // scene 2 嵌套頁面 返回 + 回首頁 pages.length > 1
根據(jù)不同的條件,展示不同的內(nèi)容
最終效果
scene 0 常規(guī)首頁

scene 1 非常規(guī)首頁

scene 2 嵌套頁

目前在生產(chǎn)環(huán)境99%的機(jī)型中,都可以完美的運(yùn)行。
寫在最后
- 自定義導(dǎo)航欄是全局生效的,一旦設(shè)置,各個原生小程序頁面都需要引入
- 目前微信版本7+支持了針對特定頁面的自定義導(dǎo)航欄,可以根據(jù)需要個性化定制
- 自定義導(dǎo)航欄在web-view頁面不會起效
- 有嘗試把導(dǎo)航欄做成插件,但是遇到在插件組件中無法獲取頁面路由棧的問題,因此沒有成功
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。
相關(guān)文章
JavaScript常見的跨標(biāo)簽頁通信方式總結(jié)
跨標(biāo)簽頁通信是指在瀏覽器中的不同標(biāo)簽頁之間進(jìn)行數(shù)據(jù)傳遞和通信的過程,這篇文章為大家整理了前端常見的跨標(biāo)簽頁通信方式,有需要的小伙伴可以了解下2023-10-10
小程序獲取當(dāng)前位置加搜索附近熱門小區(qū)及商區(qū)的方法
這篇文章主要介紹了小程序獲取當(dāng)前位置加搜索附近熱門小區(qū)及商區(qū)的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-04-04
單元測試框架Jest搭配TypeScript的安裝與配置方式
這篇文章主要介紹了單元測試框架Jest搭配TypeScript的安裝與配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01
JavaScript代碼實(shí)現(xiàn)春晚劉謙魔術(shù)的模擬程序
昨晚春晚上劉謙的兩個魔術(shù)表演都非常精彩,尤其是第二個魔術(shù),他演繹了經(jīng)典的約瑟夫環(huán)問題!約瑟夫環(huán)是一個經(jīng)典的數(shù)學(xué)問題,本文給出了完整的 JavaScript 代碼實(shí)現(xiàn),感興趣的同學(xué)可以自己動手實(shí)現(xiàn)一下2024-02-02
圖形編輯器中JS實(shí)現(xiàn)防誤操作之拖拽阻塞
這篇文章主要為大家介紹了圖形編輯器中JS實(shí)現(xiàn)防誤操作之拖拽阻塞實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03

