一,自定义导航栏的重点是高度的计算
从下图分析出来:导航栏高度 = (胶囊顶部距离 - 状态栏高度) 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="width: 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>
@import url("./class.css");
</style>
.page{
height: 100%;
width: 100%;
position: fixed;
top: 0rpx;
}
.search-box {
display: flex;
justify-content: center; /*水平居中*/
/* align-items: center; */ /*垂直居中*/
width: 100%;
background: #ffffff ;
}
.search-input {
width: 40%;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50rpx;
background: #efefef;
color: #666;
}
.serch-image{
height: 40rpx;
width: 40rpx;
margin-right: 10rpx;
}
.store{
display: flex;
flex-direction: column;
width: 94%;
margin-left: 20rpx;
}
.store-1{
height: 100rpx;
display: flex;
flex-direction: row;
justify-content: space-between; /*两边对齐*/
}
.store-right{
height: 50rpx;
width: 200rpx;
display: flex;
flex-direction: row;
background-color: #efefef;
border-radius: 50rpx;
margin: 10rpx;
}
.store-right-text{
height: 50rpx;
width: 100rpx;
display: flex;
justify-content: center; /*水平居中*/
align-items: center; /*垂直居中*/
background-color: #efefef;
border-radius: 50rpx;
}
.text-activity{
height: 50rpx;
width: 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;
width: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; /*展开后的高度*/
}