一,自定义导航栏的重点是高度的计算
从下图分析出来:导航栏高度 = (胶囊顶部距离 - 状态栏高度) x 2 + 胶囊的高度
data() {
return {
system:[],
menu:[],
statusBarHeight: 0, //状态栏的高度
navigatorHeight: 0, //导航栏高度
menuHeight: 0, //胶囊高度
menuTop: 0, //胶囊与顶部的距离
totalHeight: 0, //总高度
}
},
onLoad() {
//获取系统信息
uni.getSystemInfo({
success: res => {
this.system = res
}
})
//获取胶囊信息
this.menu = uni.getMenuButtonBoundingClientRect()
//计算组件高度
this.statusBarHeight = this.system.statusBarHeight //状态栏高度
this.menuHeight = this.menu.height //胶囊高度
this.menuTop = this.menu.top //胶囊与顶部的距离
//导航栏高度= (胶囊顶部距离-状态栏高度) x 2 + 胶囊的高度
this.navigatorHeight = (this.menu.top - this.system.statusBarHeight) * 2 + this.menu.height
//总高度 = 状态栏的高度 + 导航栏高度
this.totalHeight = this.statusBarHeight + this.navigatorHeight
}
二,计算元素与导航栏底部的距离
先命名元素id ,再在onLoad生命周期调用 wx.createSelectorQuery()
onLoad() {
//监听元素与导航栏底部的距离
const query = wx.createSelectorQuery()
query.select('#more').boundingClientRect()
query.exec((res)=> {
console.log(res)
let top = res[0].top //id节点的上边界坐标
})
}
以下是完整代码
<template> <view class="page"> <!-- 搜索栏 --> <view class="search-box" :style="{'height':totalHeight +'px'}"> <view class="search-input" :style="{'margin-top':menuTop +'px','height':menuHeight +'px'}"> <image class="serch-image" src="../../../static/icon/png/search.png" ></image> <text>搜索</text> </view> </view> <!-- 选择店铺与更多 --> <view class="store"> <view class="store-1"> <view class="store-left"> <view class="store-name"> 广州番禺天河城店 > </view> <view style="font-size: 12px;color: #C7C7C7;">距离您 8.3KM</view> </view> <view class="store-right"> <view :class="[isActivity== 0 ? 'text-activity' :'store-right-text']" @click="takeIn" >自取</view> <view :class="[isActivity== 1 ? 'text-activity' :'store-right-text']" @click="takeOut" >外卖</view> </view> </view> <view id="more" class="store-2" style="font-size: 14px;color: #6d6d6d;"> <view class="">公告</view> <view class="" @click="showMore"> {{isShow ? '收起∧':'查看更多∨'}} </view> </view> </view> <!-- 更多弹框 --> <view > <view class="show-more" :class="[isShow ? 'show-more-click' : '']" :style="{'top': theMoreTop +'px'}"> <view class="" v-if="isShowText">第1行文字</view> <view class="" v-if="isShowText">第2行文字</view> <view class="" v-if="isShowText">第3行文字</view> <view class="" v-if="isShowText">第4行文字</view> <view class="" v-if="isShowText">第5行文字</view> <view class="" v-if="isShowText">第6行文字</view> </view> </view> <view class=""> <image src="../../../static/icon/png/ziqu.png" mode="" style=" 400rpx;height: 400rpx;"></image> </view> </view> </template> <script> export default { data() { return { windowWidth: 0, windowHeight: 0, statusBarHeight: 0, //状态栏的高度 navigatorHeight: 0, //导航栏高度 menuHeight: 0, //胶囊高度 menuTop: 0, //胶囊与顶部的距离 totalHeight: 0, //总高度 theMoreTop: 0, //更多那个组件距离屏幕顶部的距离 system:[], menu:[], isActivity:0, isShow:false, isShowText:false } }, onLoad() { //获取系统信息 uni.getSystemInfo({ success: res => { this.system = res } }) //获取胶囊信息 this.menu = uni.getMenuButtonBoundingClientRect() //计算组件高度 this.statusBarHeight = this.system.statusBarHeight //状态栏高度 this.navigatorHeight = (this.menu.top - this.system.statusBarHeight) * 2 + this.menu.height //导航栏高度 this.totalHeight = this.statusBarHeight + this.navigatorHeight //总高度 this.menuHeight = this.menu.height //胶囊高度 this.menuTop = this.menu.top //胶囊与顶部的距离 //监听【更多】组件距离顶部的距离 const query = wx.createSelectorQuery() query.select('#more').boundingClientRect() query.exec((res)=> { //console.log(res) let top = res[0].bottom //id节点的下边界坐标 this.theMoreTop = top + this.totalHeight }) }, methods: { takeIn(){ this.isActivity = 0 }, takeOut(){ this.isActivity = 1 }, showMore(){ this.isShow = !this.isShow // 先展开500毫秒后再显示文字,收缩100毫秒后再隐藏文字 if(this.isShowText){ setTimeout(()=>{ this.isShowText = !this.isShowText },200) }else{ setTimeout(()=>{ this.isShowText = !this.isShowText },500) } } } } </script> <style> .page{
height: 100%;
100%;
position: fixed;
top: 0rpx;
}
.search-box {
display: flex;
justify-content: center; /*水平居中*/
/* align-items: center; */ /*垂直居中*/
100%;
background: #ffffff ;
}
.search-input {
40%;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50rpx;
background: #efefef;
color: #666;
}
.serch-image{
height: 40rpx;
40rpx;
margin-right: 10rpx;
}
.store{
display: flex;
flex-direction: column;
94%;
margin-left: 20rpx;
}
.store-1{
height: 100rpx;
display: flex;
flex-direction: row;
justify-content: space-between; /*两边对齐*/
}
.store-right{
height: 50rpx;
200rpx;
display: flex;
flex-direction: row;
background-color: #efefef;
border-radius: 50rpx;
margin: 10rpx;
}
.store-right-text{
height: 50rpx;
100rpx;
display: flex;
justify-content: center; /*水平居中*/
align-items: center; /*垂直居中*/
background-color: #efefef;
border-radius: 50rpx;
}
.text-activity{
height: 50rpx;
100rpx;
display: flex;
justify-content: center; /*水平居中*/
align-items: center; /*垂直居中*/
border-radius: 50rpx;
background-color: #565656;
color: #ffffff;
}
.store-2{
height: 50rpx;
display: flex;
flex-direction: row;
justify-content: space-between;
}
/* 点击更多的样式 */
.show-more{
/*position: relative;*/ /*相对定位*/
/*position: absolute;*/ /*绝对定位*/
position: fixed; /*固定定位*/
z-index: 99;
100%;
height:2px;
background-color: #4CD964;
transition:height 1s;
-moz-transition:height 1s; /* Firefox 4 */
-webkit-transition:height 1s; /* Safari and Chrome */
-o-transition:height 1s; /* Opera */
}
.show-more-click{
height:300px; /*展开后的高度*/
}
</style>