小程序头部导航栏添加图片背景

Posted 小小淼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小程序头部导航栏添加图片背景相关的知识,希望对你有一定的参考价值。

原理其实就是通过将原来的头禁用,然后PAGE自然而然的顶上去以后,定义一个头的组件,将他设置成fixed布局固定在原来头的部分,然后给page加上Margin-top,所以还原原来的感觉。

1.app配置

​ 首先禁用所有头导航,在app.json的window里加一行这个,你会发现所有头都消失了。然后禁止滑动页面,滑动问题用scroll-view解决

"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配置到这里应该完事了。

2.组件配置

组件结构:

放源码吧

// 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\'
    //   })
    // }
  }
})

 

​ 大概就是这么多,怎么在页面上用呢

3.具体页面配置

​ 页面的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
  }
})

 

4.存在的问题

上拉刷新

​ 我没有试过哈,不过原生的微信上拉刷新这么用是准定不行了,如果喜欢ios橡皮筋模式的同学或者想要刷新的同学可以在具体页面里删掉scroll-view组件换成view(记得保留那个padding-top!),然后把app.json的禁用滑动删除掉。具体的我也没有深入,大家自行解决吧。

5.踩的坑

​ 单纯分享下,不看也可以,首先就是设置页面的背景的时候,我考虑过直接在css上设置background image,但是有一个问题是,小程序的background image 只支持在线的地址或者是base64。我不知道为什么要这么做。真的很迷。但是线上的不稳定,base64太长了,代码不好看也不好整理,所以考虑了一下还是用Image组件吧。

​ 然后第二个坑又来了,image组件自带宽高,而且用Mode里的任何值都不能完成需求。如果我设置成width:100%占满父元素的话,他的长还是默认的340px,所以还是鼓捣了鼓捣,先设置宽度不是100%了,而是通过wx.**getSystemInfoSync**().windowWidth;来获取的屏幕宽度。然后再通过image组件的事件获取原图的长宽,探后计算屏幕宽和原图宽的率,然后再将这个率乘上原图长度,就可以获取到一个占满父元素又对着比例的图了,然后给父元素套上overflow:hidden就好了。

​ 第三个坑,就是怎么做背景的拼接,想了想也不是个坑,直接在组件的最外层再加一个一模一样的image标签就行了,这样就做到了标签上显示半个背景图,然后在他的下层又能显示一个完整的背景图,因为上面被盖住了,所以地下的下半部分和导航栏的上半部分背景正好拼接起来,所以问题也就这么解决了。

转自:https://www.cnblogs.com/wangzirui98/p/11249317.html

以上是关于小程序头部导航栏添加图片背景的主要内容,如果未能解决你的问题,请参考以下文章

小程序自定义头部导航栏

小程序各种功能代码片段整理---持续更新

微信小程序添加底部自定义导航栏(tabBar)

微信小程序 导航栏切换视图

Android 全屏片段不显示导航和状态栏后面的元素

小程序--导航栏切换(tab切换)