溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

微信小程序如何實(shí)現(xiàn)膠囊按鈕返回|首頁自定義導(dǎo)航欄功能

發(fā)布時(shí)間:2021-07-09 16:27:01 來源:億速云 閱讀:1486 作者:小新 欄目:web開發(fā)

這篇文章主要介紹了微信小程序如何實(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í)會有返回和首頁按鈕;

微信小程序如何實(shí)現(xiàn)膠囊按鈕返回|首頁自定義導(dǎo)航欄功能 

當(dāng)從分享頁進(jìn)入到商品頁時(shí),因?yàn)轫撁鏃V挥幸粋€(gè),所以只有首頁按鈕;

微信小程序如何實(shí)現(xiàn)膠囊按鈕返回|首頁自定義導(dǎo)航欄功能 

首先我們需要如何開啟自定義導(dǎo)航欄,查看手冊后會發(fā)現(xiàn)一個(gè)頁面配置項(xiàng): navigationStyle

微信小程序如何實(shí)現(xiàn)膠囊按鈕返回|首頁自定義導(dǎo)航欄功能 

之前的版本此配置項(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)欄的高度 。

微信小程序如何實(shí)現(xiàn)膠囊按鈕返回|首頁自定義導(dǎo)航欄功能 

目錄結(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。

微信小程序如何實(shí)現(xiàn)膠囊按鈕返回|首頁自定義導(dǎo)航欄功能 

而我們想要的效果則是,當(dāng)小程序原生的loading被當(dāng)時(shí),自己寫的loading就可以替代原生的loading

微信小程序如何實(shí)現(xiàn)膠囊按鈕返回|首頁自定義導(dǎo)航欄功能 

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%就正常了。

微信小程序如何實(shí)現(xiàn)膠囊按鈕返回|首頁自定義導(dǎo)航欄功能 

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。

微信小程序如何實(shí)現(xiàn)膠囊按鈕返回|首頁自定義導(dǎo)航欄功能

可以通過這張圖明顯看到差了幾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í)!

向AI問一下細(xì)節(jié)

免責(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)容。

AI