微信小程序自定義頭部導(dǎo)航欄和導(dǎo)航欄背景圖片 navigationStyle問(wèn)題
這兩天因?yàn)橐鲆粋€(gè)帶背景的小程序頭,哭了,小程序?qū)Ш綑谟斜尘耙簿退懔?,還得讓導(dǎo)航欄上的背景順下來(lái),心態(tài)小崩?,F(xiàn)在可以單獨(dú)設(shè)置一個(gè)頁(yè)面的小程序頭了,但是前提是要微信7.0以上的版本,考慮到兼容性問(wèn)題,還是不要貿(mào)然的上了,所以用老版本的替換所有頁(yè)面的小程序頭來(lái)做。
參考了其他篇的文章,但是沒(méi)有解決自定義背景的和返回按鈕的顏色的問(wèn)題,還有因?yàn)镮OS的橡皮筋效果,對(duì)IOS端不太友好,屏幕會(huì)亂劃。所以針對(duì)性的改動(dòng)了這些功能,因?yàn)椴艑W(xué)小程序兩三天,所以其中踩了很多坑,但好在最后效果還是達(dá)到了。
下面是效果圖:

原理其實(shí)就是通過(guò)將原來(lái)的頭禁用,然后PAGE自然而然的頂上去以后,定義一個(gè)頭的組件,將他設(shè)置成fixed布局固定在原來(lái)頭的部分,然后給page加上Margin-top,所以還原原來(lái)的感覺(jué)。背景待會(huì)再說(shuō)。
1.app配置
首先禁用所有頭導(dǎo)航,在app.json的window里加一行這個(gè),你會(huì)發(fā)現(xiàn)所有頭都消失了。然后禁止滑動(dòng)頁(yè)面,滑動(dòng)問(wèn)題用scroll-view解決
"window": {
"navigationStyle": "custom"
},
"disableScroll": true
然后在app.js里獲取導(dǎo)航頭的高度的全局?jǐn)?shù)據(jù)
// app.js
App({
globalData: {
statusBarHeight: wx.getSystemInfoSync()['statusBarHeight']
},
// 判斷是否由分享進(jìn)入小程序
if (e.scene == 1007 || e.scene == 1008) {
this.globalData.share = true
} else {
this.globalData.share = false
}
//獲取設(shè)備頂部窗口的高度(不同設(shè)備窗口高度不一樣,根據(jù)這個(gè)來(lái)設(shè)置自定義導(dǎo)航欄的高度)
//這個(gè)最初我是在組件中獲取,但是出現(xiàn)了一個(gè)問(wèn)題,當(dāng)?shù)谝淮芜M(jìn)入小程序時(shí)導(dǎo)航欄會(huì)把
//頁(yè)面內(nèi)容蓋住一部分,當(dāng)打開(kāi)調(diào)試重新進(jìn)入時(shí)就沒(méi)有問(wèn)題,這個(gè)問(wèn)題弄得我是莫名其妙
//雖然最后解決了,但是花費(fèi)了不少時(shí)間
wx.getSystemInfo({
success: res => {
this.globalData.height = res.statusBarHeight
}
})
},
globalData: {
userInfo: null,
share: false, // 分享默認(rèn)為false
height: 0 // 頂部高度
}
})
在app.wxss給page加一個(gè)高度百分之百。
/* app.wxss */
page {
height: 100%;
}
app配置到這里應(yīng)該完事了。
2.組件配置
組件結(jié)構(gòu):

放源碼吧
// navbar.wxml
<view class='nav-wrap' style='height: {{height*2 + 20}}px;'>
<!-- 導(dǎo)航欄背景圖片 -->
<image class="backgroundimg" src="{{navbarData.address}}" bindload="imgLoaded" style="width:{{imageWidth}}px;height:{{imageHeight}}px" />
<!-- // 導(dǎo)航欄 中間的標(biāo)題 -->
<view class='nav-title' wx:if='{{!navbarData.white}}' style='line-height: {{height*2 + 44}}px;'>
{{navbarData.title}}
</view>
<view class='nav-title' wx:else='{{!navbarData.white}}' style='line-height: {{height*2 + 44}}px; color:#ffffff'>
{{navbarData.title}}
</view>
<view style='display: flex; justify-content: space-around;flex-direction: column'>
<!-- // 導(dǎo)航欄 左上角的返回按鈕 -->
<!-- // 其中wx:if='{{navbarData.showCapsule}}' 是控制左上角按鈕的顯示隱藏,首頁(yè)不顯示 -->
<view class='nav-capsule' style='height: {{height*2 + 44}}px;' wx:if='{{navbarData.showCapsule}}'>
<!-- //左上角的返回按鈕,wx:if='{{!share}}'空制返回按鈕顯示 -->
<!-- //從分享進(jìn)入小程序時(shí) 返回上一級(jí)按鈕不應(yīng)該存在 -->
<!-- navbarData.white是控制按鈕顏色的,因?yàn)楸尘坝猩顪\色,返回按鈕自己找圖片 -->
<view bindtap='_navback' wx:if='{{!share&&navbarData.white}}'>
<image src='../../images/返 回 (1).svg' mode='aspectFit' class='back-pre'></image>
</view>
<view bindtap='_navback' wx:else='{{!share}}'>
<image src='../../images/返 回.svg' mode='aspectFit' class='back-pre'></image>
</view>
</view>
</view>
</view>
<!-- 導(dǎo)航欄下面的背景圖片 -->
<image class="backgroundimg" src="{{navbarData.address}}" bindload="imgLoaded" style="width:{{imageWidth}}px;height:{{imageHeight}}px" />
CSS:
/* navbar.wxss */
/* 頂部要固定定位 標(biāo)題要居中 自定義按鈕和標(biāo)題要和右邊微信原生的膠囊上下對(duì)齊 */
.nav-wrap {
/* display: none; */
position: fixed;
width: 100%;
top: 0;
background: #fff;
color: #000;
z-index: 9999999;
background: #000;
overflow: hidden;
}
/* 背景圖 */
.backgroundimg {
position: absolute;
z-index: -1;
}
/* 標(biāo)題要居中 */
.nav-title {
position: absolute;
text-align: center;
max-width: 400rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
font-size: 36rpx;
color: #2c2b2b;
font-weight: 450;
}
.nav-capsule {
display: flex;
align-items: center;
margin-left: 30rpx;
width: 140rpx;
justify-content: space-between;
height: 100%;
}
.back-pre {
width: 32rpx;
height: 36rpx;
margin-top: 4rpx;
padding: 10rpx;
}
.nav-capsule {
width: 36rpx;
height: 40rpx;
margin-top: 3rpx;
}
在JSON里聲明我是個(gè)組件
{
"component": true,
"usingComponents": {}
}
最后是js。
const app = getApp()
Component({
properties: {
navbarData: {
//navbarData 由父頁(yè)面?zhèn)鬟f的數(shù)據(jù),變量名字自命名
type: Object,
value: {},
observer: function(newVal, oldVal) {}
}
},
data: {
height: '',
//默認(rèn)值 默認(rèn)顯示左上角
navbarData: {
showCapsule: 1
},
imageWidth: wx.getSystemInfoSync().windowWidth, // 背景圖片的高度
imageHeight: '' // 背景圖片的長(zhǎng)度,通過(guò)計(jì)算獲取
},
attached: function() {
// 獲取是否是通過(guò)分享進(jìn)入的小程序
this.setData({
share: app.globalData.share
})
// 定義導(dǎo)航欄的高度 方便對(duì)齊
this.setData({
height: app.globalData.height
})
},
methods: {
// 返回上一頁(yè)面
_navback() {
wx.navigateBack()
},
// 計(jì)算圖片高度
imgLoaded(e) {
this.setData({
imageHeight:
e.detail.height *
(wx.getSystemInfoSync().windowWidth / e.detail.width)
})
}
//返回到首頁(yè)
// _backhome() {
// wx.switchTab({
// url: '/pages/index/index'
// })
// }
}
})
大概就是這么多,怎么在頁(yè)面上用呢
3.具體頁(yè)面配置
頁(yè)面的HTML,我是內(nèi)容里面放頁(yè)面的東西。
<nav-bar navbar-data='{{nvabarData}}'></nav-bar>
<scroll-view scroll-y style="height: 100%;">
<view class="scroll-view-item" style='padding-top: {{height}}px;'>我是內(nèi)容</view>
</scroll-view>
頁(yè)面的JSON,navigationBarTextStyle是用來(lái)配置膠囊顏色的,因?yàn)槟z囊是微信給的,不能自定義,只能改顏色,所以委屈一下從這里改一下吧
{
"usingComponents": {
"nav-bar": "../../components/navbar/navbar"
},
"navigationBarTextStyle": "white"
}
頁(yè)面JS,圖片自己填上地址就好了。注意getApp()不要省。
const app = getApp()
Page({
data: {
// 導(dǎo)航頭組件所需的參數(shù)
nvabarData: {
showCapsule: 1, //是否顯示左上角圖標(biāo) 1表示顯示 0表示不顯示
title: '標(biāo)題', //導(dǎo)航欄 中間的標(biāo)題
white: true, // 是就顯示白的,不是就顯示黑的。
address: '../../images/蒙版組 1@2x.png' // 加個(gè)背景 不加就是沒(méi)有
},
// 導(dǎo)航頭的高度
height: app.globalData.height * 2 + 20
}
})
4.存在的問(wèn)題
上拉刷新
我沒(méi)有試過(guò)哈,不過(guò)原生的微信上拉刷新這么用是準(zhǔn)定不行了,如果喜歡IOS橡皮筋模式的同學(xué)或者想要刷新的同學(xué)可以在具體頁(yè)面里刪掉scroll-view組件換成view(記得保留那個(gè)padding-top?。?,然后把a(bǔ)pp.json的禁用滑動(dòng)刪除掉。具體的我也沒(méi)有深入,大家自行解決吧。
5.踩的坑
單純分享下,不看也可以,首先就是設(shè)置頁(yè)面的背景的時(shí)候,我考慮過(guò)直接在css上設(shè)置background image,但是有一個(gè)問(wèn)題是,小程序的background image 只支持在線的地址或者是base64。我不知道為什么要這么做。真的很迷。但是線上的不穩(wěn)定,base64太長(zhǎng)了,代碼不好看也不好整理,所以考慮了一下還是用Image組件吧。
然后第二個(gè)坑又來(lái)了,image組件自帶寬高,而且用Mode里的任何值都不能完成需求。如果我設(shè)置成width:100%占滿父元素的話,他的長(zhǎng)還是默認(rèn)的340px,所以還是鼓搗了鼓搗,先設(shè)置寬度不是100%了,而是通過(guò)wx.**getSystemInfoSync**().windowWidth;來(lái)獲取的屏幕寬度。然后再通過(guò)image組件的事件獲取原圖的長(zhǎng)寬,探后計(jì)算屏幕寬和原圖寬的率,然后再將這個(gè)率乘上原圖長(zhǎng)度,就可以獲取到一個(gè)占滿父元素又對(duì)著比例的圖了,然后給父元素套上overflow:hidden就好了。
第三個(gè)坑,就是怎么做背景的拼接,想了想也不是個(gè)坑,直接在組件的最外層再加一個(gè)一模一樣的image標(biāo)簽就行了,這樣就做到了標(biāo)簽上顯示半個(gè)背景圖,然后在他的下層又能顯示一個(gè)完整的背景圖,因?yàn)樯厦姹簧w住了,所以地下的下半部分和導(dǎo)航欄的上半部分背景正好拼接起來(lái),所以問(wèn)題也就這么解決了。
總結(jié)
以上所述是小編給大家介紹的微信小程序自定義頭部導(dǎo)航欄和導(dǎo)航欄背景圖片 navigationStyle問(wèn)題,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
相關(guān)文章
JQuery,Extjs,YUI,Prototype,Dojo 等JS框架的區(qū)別和應(yīng)用場(chǎng)景簡(jiǎn)述
隨著web2.0的彪悍發(fā)展,以及瀏覽器端所承載的工作越來(lái)越大(在不是很影響性能的情況下,開(kāi)發(fā)者都習(xí)慣把能用瀏覽器做的事兒都讓瀏覽器做,以減輕服務(wù)器的壓力和帶寬費(fèi)用等)。2010-04-04
javascript基本數(shù)據(jù)類型及類型檢測(cè)常用方法小結(jié)
這篇文章主要介紹了javascript基本數(shù)據(jù)類型及類型檢測(cè)常用方法,總結(jié)分析了javascript的基本數(shù)據(jù)類型與類型檢測(cè)的常用操作方法,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-12-12
js實(shí)現(xiàn)簡(jiǎn)潔的滑動(dòng)門(mén)菜單(選項(xiàng)卡)效果代碼
這篇文章主要介紹了js實(shí)現(xiàn)簡(jiǎn)潔的滑動(dòng)門(mén)菜單(選項(xiàng)卡)效果代碼,涉及javascript鼠標(biāo)事件操作頁(yè)面元素樣式切換的實(shí)現(xiàn)技巧,簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-09-09
最全面的百度地圖JavaScript離線版開(kāi)發(fā)
最全面的百度地圖JavaScript離線版開(kāi)發(fā),這篇文章主要為大家詳細(xì)介紹了JavaScript離線版開(kāi)發(fā)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
JavaScript插件化開(kāi)發(fā)教程 (二)
本系列的開(kāi)篇文章我們一起探討了jQuery如何開(kāi)發(fā)插件,今天這篇文章,我們來(lái)繼續(xù)插件開(kāi)發(fā)之旅,希望大家能夠喜歡。2015-01-01
uniapp基礎(chǔ)篇之上傳圖片的實(shí)戰(zhàn)步驟
應(yīng)用uni-app開(kāi)發(fā)跨平臺(tái)App項(xiàng)目時(shí),上傳圖片、文檔等資源功能需求十分常見(jiàn),下面這篇文章主要給大家介紹了關(guān)于uniapp基礎(chǔ)篇之上傳圖片的相關(guān)資料,需要的朋友可以參考下2022-12-12
詳解JavaScript設(shè)計(jì)模式中的享元模式
享元模式是一種用于性能優(yōu)化的模式。享元模式的核心是運(yùn)用共享技術(shù)來(lái)有效支持大量細(xì)粒度的對(duì)象.如果系統(tǒng)中創(chuàng)建了大量類似的對(duì)象而導(dǎo)致內(nèi)存占用過(guò)高,本文通過(guò)介紹書(shū)中文件上傳的優(yōu)化案例來(lái)說(shuō)明享元模式的使用方式和作用,需要的朋友可以參考下2023-06-06

