這兩天由於要作一個帶背景的小程序頭,哭了,小程序導航欄有背景也就算了,還得讓導航欄上的背景順下來,心態小崩。如今能夠單獨設置一個頁面的小程序頭了,可是前提是要微信7.0以上的版本,考慮到兼容性問題,仍是不要貿然的上了,因此用老版本的替換全部頁面的小程序頭來作。javascript
參考了jiuyucha的文章,可是沒有解決自定義背景的和返回按鈕的顏色的問題,還有由於IOS的橡皮筋效果,對IOS端不太友好,屏幕會亂劃。因此針對性的改動了這些功能,由於才學小程序兩三天,因此其中踩了不少坑,但好在最後效果仍是達到了。css
下面是效果圖:html
原理其實就是經過將原來的頭禁用,而後PAGE天然而然的頂上去之後,定義一個頭的組件,將他設置成fixed佈局固定在原來頭的部分,而後給page加上Margin-top,因此還原原來的感受。背景待會再說。java
首先禁用全部頭導航,在app.json的window里加一行這個,你會發現全部頭都消失了。而後禁止滑動頁面,滑動問題用scroll-view
解決json
"window": { "navigationStyle": "custom" }, "disableScroll": true
而後在app.js裏獲取導航頭的高度的全局數據小程序
// app.js App({ globalData: { statusBarHeight: wx.getSystemInfoSync()['statusBarHeight'] }, // 判斷是否由分享進入小程序 if (e.scene == 1007 || e.scene == 1008) { this.globalData.share = true } else { this.globalData.share = false } //獲取設備頂部窗口的高度(不一樣設備窗口高度不同,根據這個來設置自定義導航欄的高度) //這個最初我是在組件中獲取,可是出現了一個問題,當第一次進入小程序時導航欄會把 //頁面內容蓋住一部分,當打開調試從新進入時就沒有問題,這個問題弄得我是莫名其妙 //雖然最後解決了,可是花費了很多時間 wx.getSystemInfo({ success: res => { this.globalData.height = res.statusBarHeight } }) }, globalData: { userInfo: null, share: false, // 分享默認爲false height: 0 // 頂部高度 } })
在app.wxss給page加一個高度百分之百。微信
/* app.wxss */ page { height: 100%; }
app配置到這裏應該完事了。app
組件結構:xss
放源碼吧svg
// navbar.wxml <view class='nav-wrap' style='height: {{height*2 + 20}}px;'> <!-- 導航欄背景圖片 --> <image class="backgroundimg" src="{{navbarData.address}}" bindload="imgLoaded" style="width:{{imageWidth}}px;height:{{imageHeight}}px" /> <!-- // 導航欄 中間的標題 --> <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'> <!-- // 導航欄 左上角的返回按鈕 --> <!-- // 其中wx:if='{{navbarData.showCapsule}}' 是控制左上角按鈕的顯示隱藏,首頁不顯示 --> <view class='nav-capsule' style='height: {{height*2 + 44}}px;' wx:if='{{navbarData.showCapsule}}'> <!-- //左上角的返回按鈕,wx:if='{{!share}}'空制返回按鈕顯示 --> <!-- //從分享進入小程序時 返回上一級按鈕不該該存在 --> <!-- navbarData.white是控制按鈕顏色的,由於背景有深淺色,返回按鈕本身找圖片 --> <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> <!-- 導航欄下面的背景圖片 --> <image class="backgroundimg" src="{{navbarData.address}}" bindload="imgLoaded" style="width:{{imageWidth}}px;height:{{imageHeight}}px" />
CSS:
/* navbar.wxss */ /* 頂部要固定定位 標題要居中 自定義按鈕和標題要和右邊微信原生的膠囊上下對齊 */ .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; } /* 標題要居中 */ .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裏聲明我是個組件
{ "component": true, "usingComponents": {} }
最後是js。
const app = getApp() Component({ properties: { navbarData: { //navbarData 由父頁面傳遞的數據,變量名字自命名 type: Object, value: {}, observer: function(newVal, oldVal) {} } }, data: { height: '', //默認值 默認顯示左上角 navbarData: { showCapsule: 1 }, imageWidth: wx.getSystemInfoSync().windowWidth, // 背景圖片的高度 imageHeight: '' // 背景圖片的長度,經過計算獲取 }, attached: function() { // 獲取是不是經過分享進入的小程序 this.setData({ share: app.globalData.share }) // 定義導航欄的高度 方便對齊 this.setData({ height: app.globalData.height }) }, methods: { // 返回上一頁面 _navback() { wx.navigateBack() }, // 計算圖片高度 imgLoaded(e) { this.setData({ imageHeight: e.detail.height * (wx.getSystemInfoSync().windowWidth / e.detail.width) }) } //返回到首頁 // _backhome() { // wx.switchTab({ // url: '/pages/index/index' // }) // } } })
大概就是這麼多,怎麼在頁面上用呢
頁面的HTML,我是內容裏面放頁面的東西。
<nav-bar navbar-data='{{nvabarData}}'></nav-bar> <scroll-view scroll-y style="height: 100%;"> <view class="scroll-view-item" style='padding-top: {{height}}px;'>我是內容</view> </scroll-view>
頁面的JSON,navigationBarTextStyle
是用來配置膠囊顏色的,由於膠囊是微信給的,不能自定義,只能改顏色,因此委屈一下從這裏改一下吧
{ "usingComponents": { "nav-bar": "../../components/navbar/navbar" }, "navigationBarTextStyle": "white" }
頁面JS,圖片本身填上地址就行了。注意getApp()
不要省。
const app = getApp() Page({ data: { // 導航頭組件所需的參數 nvabarData: { showCapsule: 1, //是否顯示左上角圖標 1表示顯示 0表示不顯示 title: '標題', //導航欄 中間的標題 white: true, // 是就顯示白的,不是就顯示黑的。 address: '../../images/蒙版組 1@2x.png' // 加個背景 不加就是沒有 }, // 導航頭的高度 height: app.globalData.height * 2 + 20 } })
我沒有試過哈,不過原生的微信上拉刷新這麼用是準定不行了,若是喜歡IOS橡皮筋模式的同窗或者想要刷新的同窗能夠在具體頁面裏刪掉scroll-view組件換成view(記得保留那個padding-top!),而後把app.json的禁用滑動刪除掉。具體的我也沒有深刻,你們自行解決吧。
單純分享下,不看也能夠,首先就是設置頁面的背景的時候,我考慮過直接在css上設置background image,可是有一個問題是,小程序的background image 只支持在線的地址或者是base64。我不知道爲何要這麼作。真的很迷。可是線上的不穩定,base64太長了,代碼很差看也很差整理,因此考慮了一下仍是用Image組件吧。
而後第二個坑又來了,image組件自帶寬高,並且用Mode裏的任何值都不能完成需求。若是我設置成width:100%
佔滿父元素的話,他的長仍是默認的340px,因此仍是鼓搗了鼓搗,先設置寬度不是100%了,而是經過wx.**getSystemInfoSync**().windowWidth
;來獲取的屏幕寬度。而後再經過image組件的事件獲取原圖的長寬,探後計算屏幕寬和原圖寬的率,而後再將這個率乘上原圖長度,就能夠獲取到一個佔滿父元素又對着比例的圖了,而後給父元素套上overflow:hidden
就行了。
第三個坑,就是怎麼作背景的拼接,想了想也不是個坑,直接在組件的最外層再加一個如出一轍的image標籤就好了,這樣就作到了標籤上顯示半個背景圖,而後在他的下層又能顯示一個完整的背景圖,由於上面被蓋住了,因此地下的下半部分和導航欄的上半部分背景正好拼接起來,因此問題也就這麼解決了。
最後的話歡迎你們指正個人問題,畢竟小白一個,不是很懂小程序這方面。