微信小程序自定义顶部导航栏

1,742 阅读2分钟

1、去掉原生状态栏

在json文件中添加一下代码,去掉原生状态栏

"navigationStyle""custom"

2、获取原生状态栏各元素的宽度和高度

在app.js的onLaunch中利用wx.getSystemInfoSync获取系统的信息,然后利用wx.getMenuButtonBoundingClientRect()获取导航栏胶囊的位置

App({
  onLaunch () {
    const that = this;
    // 获取系统信息
    const systemInfo = wx.getSystemInfoSync();
    // 胶囊按钮位置信息
    const menuButtonInfo = wx.getMenuButtonBoundingClientRect();
    // 导航栏高度 = 状态栏到胶囊的间距(胶囊距上距离-状态栏高度) * 2 + 胶囊高度 + 状态栏高度
    that.globalData.navBarHeight = (menuButtonInfo.top - systemInfo.statusBarHeight) * 2 + menuButtonInfo.height + systemInfo.statusBarHeight;
    that.globalData.menuRight = systemInfo.screenWidth - menuButtonInfo.right;
    that.globalData.menuBotton = menuButtonInfo.top - systemInfo.statusBarHeight;
    that.globalData.menuHeight = menuButtonInfo.height;
    that.globalData.menuWidth = menuButtonInfo.width;
  },
  globalData: {
    userInfo: null,
    navBarHeight: 0, // 导航栏高度
    menuRight: 0, // 胶囊距右方间距(保持左、右间距一致)
    menuBotton: 0, // 胶囊距底部间距(保持底部间距一致)
    menuHeight: 0, // 胶囊高度(自定义内容可与胶囊高度保证一致)
    menuWidth: 0, // 胶囊宽度(自定义内容可与胶囊宽度保证一致)
  }
})

3、封装导航栏

js

const app = getApp()
Component({
  /** * 组件的属性列表 */
  properties: {
    backgroundColor: { type: String, value: "#fff", },//导航栏背景色
    title: { type: String, value: "", },//导航栏标题
    titleColor: { type: String, value: "#000", },//标题颜色
    hasBack: { type: Boolean, value: false },//是否显示返回图标
    isTop: { type: Boolean, value: false },//是否靠顶
  },

  /** * 组件的初始数据 */
  data: {
    navBarHeight: app.globalData.navBarHeight,
    menuRight: app.globalData.menuRight,
    menuBotton: app.globalData.menuBotton,
    menuHeight: app.globalData.menuHeight,
    menuWidth: app.globalData.menuWidth,
  },

  /** * 组件的方法列表 */
  methods: {
    goBack () {
      wx.navigateBack({ delta: 1 });
    },
  }
})

wxml

<view class="nav-bar-placeHolder" style="height:{{navBarHeight}}px;background:{{backgroundColor}}" wx:if="{{!isTop}}"></view>
<view class="nav-bar" style="height:{{navBarHeight}}px;background:{{backgroundColor}};padding-right:{{menuWidth}}px">
  <view style="height:{{menuHeight}}px;min-height:{{menuHeight}}px;line-height:{{menuHeight}}px;left:{{menuRight}}px;bottom:{{menuBotton}}px;" class="iconBg">
    <view class="backIcon" wx:if="{{hasBack}}" style="color:{{titleColor}}"></view>
  </view>
  <view class="title" style="height:{{menuHeight}}px;min-height:{{menuHeight}}px;line-height:{{menuHeight}}px;bottom:{{menuBotton}}px;color:{{titleColor}}">{{title}}</view>
</view>

wxss

.nav-bar{ 
  width: 100%; 
  color: #000; 
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed; 
  top: 0; 
}
.nav-bar .title{
  color: #000;
  font-size: 16px;
  position: absolute;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.backIcon{
  font-size:12px;
  width:1em;
  height:2em;
  -webkit-mask:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='24' viewBox='0 0 12 24'%3E  %3Cpath fill-opacity='.9' fill-rule='evenodd' d='M10 19.438L8.955 20.5l-7.666-7.79a1.02 1.02 0 0 1 0-1.42L8.955 3.5 10 4.563 2.682 12 10 19.438z'/%3E%3C/svg%3E") no-repeat 50% 50%;mask:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='24' viewBox='0 0 12 24'%3E  %3Cpath fill-opacity='.9' fill-rule='evenodd' d='M10 19.438L8.955 20.5l-7.666-7.79a1.02 1.02 0 0 1 0-1.42L8.955 3.5 10 4.563 2.682 12 10 19.438z'/%3E%3C/svg%3E") no-repeat 50% 50%;
  -webkit-mask-size:cover;
  mask-size:cover;
  background-color:currentColor
}
.iconBg{
  display: flex;
  align-items: center;
  justify-content: center;
  position: absolute;
}

4、使用

在json文件中引入组件,并且设置"navigationStyle": "custom",

json

{
  "usingComponents": {
    "nav-bar":"/com/navBar/index"
  },
  "navigationStyle": "custom"
}

wxml

<nav-bar title="导航栏" titleColor="#000" backgroundColor="{{isShowColor?'#fff':'transparent'}}" hasBack="{{true}}" isTop="{{true}}"></nav-bar>
<image class="" src="/images/bg.png" mode="widthFix" lazy-load="false" binderror="" bindload="" id="img" />
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>
<view class="" hover-class="none" hover-stop-propagation="false">自定义导航栏</view>

js

const app = getApp();
Page({
  data: {
    isShowColor: false,
    height: 0,
  },
  onShow () {
  //获取元素高度
    let _this = this;
    const query = wx.createSelectorQuery()
    query.select('#img').boundingClientRect()
    query.selectViewport().scrollOffset()
    query.exec(function (res) {
      console.log(res[0].height)
      _this.setData({ height: res[0].height, })
    })
  },
  // 获取滚动条当前位置
  onPageScroll: function (e) {
    // console.log(e)
    if (e.scrollTop >= (this.data.height - app.globalData.navBarHeight)) {//第一个元素的高度-导航栏的高度
      !this.data.isShowColor && this.setData({ isShowColor: true });
    } else {
      this.data.isShowColor && this.setData({ isShowColor: false });
    }
  },
})

5、效果

navBar.gif