您好,登錄后才能下訂單哦!
這篇文章主要介紹了微信小程序如何實(shí)現(xiàn)膠囊按鈕返回|首頁自定義導(dǎo)航欄功能,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
在小程序中,從轉(zhuǎn)發(fā)出來的小程序消息卡片進(jìn)入,因?yàn)轫撁鏃V兄挥幸粋€(gè),所以不會出現(xiàn)返回按鈕,對于一些電商平臺來說,當(dāng)商品被轉(zhuǎn)發(fā)后會很影響客戶查看其它產(chǎn)品和首頁,這時(shí)候就需要使用自定義導(dǎo)航欄自己寫一個(gè)“膠囊按鈕”。如下圖所示:
從別的頁面點(diǎn)到商品頁時(shí)會有返回和首頁按鈕;
當(dāng)從分享頁進(jìn)入到商品頁時(shí),因?yàn)轫撁鏃V挥幸粋€(gè),所以只有首頁按鈕;
首先我們需要如何開啟自定義導(dǎo)航欄,查看手冊后會發(fā)現(xiàn)一個(gè)頁面配置項(xiàng): navigationStyle
之前的版本此配置項(xiàng)只能在app.js中配置,是全局的屬性,而現(xiàn)在可以在單獨(dú)的頁面json中配置,實(shí)現(xiàn)單獨(dú)頁面自定義導(dǎo)航欄。
整體思路
當(dāng)使用了 navigationStyle:custom
后,之前的頂部標(biāo)題欄會被刪除,右側(cè)的膠囊按鈕則會固定在右上角。然后在當(dāng)前頁面添加了三個(gè)view(狀態(tài)欄、標(biāo)題欄、主體內(nèi)容),可以看出三塊的布局,我直接寫死的高度:狀態(tài)欄20px,標(biāo)題欄44px。這個(gè)是自定義導(dǎo)航欄的關(guān)鍵,需要去計(jì)算這兩塊的高度,還有返回|首頁膠囊按鈕的位置?;A(chǔ)庫 2.1.0開始可以使用 wx.getMenuButtonBoundingClientRect() 來獲得 右側(cè)膠囊按鈕的位置信息 ,而有了這個(gè)信息,就能相對的算出我們想要在左側(cè)添加的膠囊按鈕的位置。通過 wx.getSystemInfoSync()中的statusBarHeight找到狀態(tài)欄的高度 。
目錄結(jié)構(gòu)
├── components 組件 │ ├── headerNavbar 頂部自定義導(dǎo)航欄 │ │ └── headerNavbar.js │ │ └── headerNavbar.json │ │ └── headerNavbar.wxml │ │ └── headerNavbar.wxss ├── pages 頁面 │ ├── index 首頁 │ │ └── index.js │ │ └── index.json │ │ └── index.wxml │ │ └── index.wxss │ ├── navigationStyle 引入自定義導(dǎo)航欄的頁面(單獨(dú)配置了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ù) // 因?yàn)槲以趧e的頁面也需要使用此信息,所以沒有單獨(dú)獲得 statusBarHeight wx.getSystemInfo({ // 獲取設(shè)備信息 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
<!-- 自定義導(dǎo)航欄 --> <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 : "默認(rèn)標(biāo)題"}}{{navbarHeight}} </view> <view class="navbar-icon" wx:if='{{navbarData.showCapsule ? navbarData.showCapsule : true}}' > <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>
為了適配不同手機(jī)屏幕, 高度和膠囊按鈕的位置都需要在html里面賦值 ,下面會詳細(xì)的說明高度如何計(jì)算。在自定義導(dǎo)航欄組件中分為兩部分, 一個(gè)是頂部的導(dǎo)航欄另一個(gè)是自己寫的loading。
因?yàn)樽远x導(dǎo)航欄是fixed到頂部的, 為了保證不擋住下面的主體內(nèi)容,我們需要在導(dǎo)航欄和主體內(nèi)容之間添加一個(gè)跟導(dǎo)航欄相同的高度 ,class先叫做box。這樣可以保證導(dǎo)航欄不擋著主體內(nèi)容。但是會出現(xiàn)另一個(gè)問題,如果此頁面支持下拉刷新, 那么導(dǎo)航欄會把小程序原生的loading樣式擋住,而在主體內(nèi)容的前面會出現(xiàn)一個(gè)空白的box,雖說不影響使用,但是在用戶看來會很奇怪,莫名其妙的多出來一塊,box只有在loading結(jié)束后才會上去 。所以在這里需要自己手寫一個(gè)loading的動畫效果放在組件的最底下,高度跟導(dǎo)航欄一樣。
可以看到下面的最終效果,藍(lán)色導(dǎo)航條下面的三個(gè)點(diǎn)是小程序原生loading,再下面三個(gè)小點(diǎn)是自己寫的loading。
而我們想要的效果則是,當(dāng)小程序原生的loading被當(dāng)時(shí),自己寫的loading就可以替代原生的loading
headerNavbar.js
狀態(tài)欄高度 = app.globalData.systeminfo.statusBarHeight
需要注意 膠囊位置信息的原點(diǎn)是在頁面的左上角 ,所以需要轉(zhuǎn)換一下,把 原膠囊位置信息起名為膠囊,轉(zhuǎn)換后的叫做現(xiàn)膠囊。
/*** iphone6 的膠囊位置信息
* wx.getMenuButtonBoundingClientRect() 坐標(biāo)信息以屏幕左上角為原點(diǎn)
* 膠囊寬度: 87
* 膠囊高度: 32
* 膠囊左邊界坐標(biāo): 278
* 膠囊上邊界坐標(biāo): 26
* 膠囊右邊界坐標(biāo): 365
* 膠囊下邊界坐標(biāo): 58
* 狀態(tài)欄高度:20*/
現(xiàn)膠囊上邊距 = 膠囊上邊界坐標(biāo) - 狀態(tài)欄高度
現(xiàn)膠囊右邊距 = 屏幕寬度 - 膠囊右邊界坐標(biāo)
現(xiàn)膠囊下邊距 = 膠囊下邊界坐標(biāo) - 膠囊高度 - 狀態(tài)欄高度
導(dǎo)航欄高度 = 膠囊下邊界坐標(biāo) + 現(xiàn)膠囊下邊距
注意:膠囊下邊界坐標(biāo)包含了 狀態(tài)欄、膠囊高度和狀態(tài)欄和膠囊高度之間的距離,因?yàn)槟z囊是居中在導(dǎo)航欄里的 ,所以上邊距與下邊距應(yīng)該一致,所以是 膠囊下邊界坐標(biāo) - 膠囊高度 - 狀態(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 沒有 若從分享頁進(jìn)入則為 false statusBarHeight: 0, // 狀態(tài)欄高度 navbarHeight: 0, // 頂部導(dǎo)航欄高度 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() 坐標(biāo)信息以屏幕左上角為原點(diǎn) * 菜單按鍵寬度: 87 * 菜單按鍵高度: 32 * 菜單按鍵左邊界坐標(biāo): 278 * 菜單按鍵上邊界坐標(biāo): 26 * 菜單按鍵右邊界坐標(biāo): 365 * 菜單按鍵下邊界坐標(biāo): 58 */ let btnPosi = { // 膠囊實(shí)際位置,坐標(biāo)信息不是左上角原點(diǎn) height: headerPosi.height, width: headerPosi.width, // 膠囊top - 狀態(tài)欄高度 top: headerPosi.top - statusBarHeight, // 膠囊bottom - 膠囊height - 狀態(tài)欄height (現(xiàn)膠囊bottom 為距離導(dǎo)航欄底部的長度) bottom: headerPosi.bottom - headerPosi.height - statusBarHeight, // 屏幕寬度 - 膠囊right right: app.globalData.systeminfo.screenWidth - headerPosi.right } let haveBack; if (getCurrentPages().length === 1) { // 當(dāng)只有一個(gè)頁面時(shí) haveBack = false; } else { haveBack = true; } this.setData({ haveBack: haveBack, // 獲取是否是通過分享進(jìn)入的小程序 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()
來判斷當(dāng)前頁面是否從分享頁進(jìn)入, 因?yàn)槿绻麖姆窒眄撨M(jìn)入頁面棧中應(yīng)該只有一條數(shù)據(jù),在跳轉(zhuǎn)到其他頁面時(shí)頁面棧的length則會增加 ,在其他頁面就會顯示出返回和首頁按鈕。
注意:微信7.0.0支持wx.getMenuButtonBoundingClientRect(),
如果想兼容低版本的微信,只能把導(dǎo)航欄的高度寫死,通過一些大佬的計(jì)算得出的高度:
'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" } }
先在需要使用自定義導(dǎo)航欄的頁面json中添加navigationStyle:custom
enablePullDownRefresh: true 開啟下拉刷新
backgroundTextStyle: light是把loading的樣式改成白色,這樣就不會顯示出來loading的三個(gè)點(diǎn)
navigationStyle.wxml
<headernavbar navbar-data="{{nvabarData}}"></headernavbar> <view class="home-page"> <text> 上面是自定義導(dǎo)航欄↑↑↑ </text> <text> 下面是主體內(nèi)容↓↓↓ </text> <navigator url="./testPage"> 跳轉(zhuǎn)到測試頁 </navigator> </view>
navigationStyle.js
Page({ data: { // 組件所需的參數(shù) nvabarData: { showCapsule: 1, // 是否顯示左上角膠囊按鈕 1 顯示 0 不顯示 title: '組件列表' // 導(dǎo)航欄 中間的標(biāo)題 } }, onPullDownRefresh() { setTimeout(() = >{ wx.stopPullDownRefresh(); // 停止下拉 }, 2000); }, })
注意:雖說這么做在小程序開發(fā)工具中看起來都是對的,得到的導(dǎo)航欄高度也是64px但是在真機(jī)上測試后,還是有偏差,在iphone8 plus上高度是60px。
可以通過這張圖明顯看到差了幾px,如果你是單獨(dú)幾個(gè)頁面使用自定義導(dǎo)航,細(xì)心的用戶可能會發(fā)現(xiàn),但是基本不影響。如果是全局使用自定義導(dǎo)航,那就不存在這個(gè)問題了。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“微信小程序如何實(shí)現(xiàn)膠囊按鈕返回|首頁自定義導(dǎo)航欄功能”這篇文章對大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。