微信小程序头部导航经常会用到选项卡,一个会自动居中的选项卡的体验会比普通的选项卡要好很多。
效果示意图:
被选中的tab会始终居中显示。
利用微信小程序自带的组件scroll-view的scroll-left就很容易实现这个效果。
wxml代码:
<!-- 遮罩层 -->
<image wx:if="{{showMaskScroll}}" class='mask-scroll' src='../../static/images/slidemunu-r.png'></image>
<scroll-view scroll-x="true" class="nav {{showScroll ? 'showScroll' : ''}} " scroll-left="{{navScrollLeft}}" scroll-with-animation="{{true}}" scroll-into-view="{{toView}}" bindscrolltoupper="stopTimer" bindscroll="stopNewTimer">
<block wx:for="{{navData}}" wx:for-index="idx" wx:for-item="navItem" wx:key="idx">
<view id="navItem{{idx}}" class="nav-item navItem{{idx}} {{currentTab == idx ?'active':''}}" data-current="{{idx}}" data-id="{{navItem.id}}" data-url="{{navItem.cat_url}}" data-name="{{navItem.cat_name}}" bindtap="switchNav" style="margin-right:{{idx==navData.length-1?'60rpx':'0rpx'}};">
{{navItem.cat_name}}
<image class='hot' src='../../static/images/icon/icon_hot.png' wx:if="{{navItem.is_recommend == 1}}"></image>
</view>
</block>
<view class='slideLine' style="width:{{slideWidth}}px;left:{{sliedeLeft}}px;"></view>
</scroll-view>
遮罩层是右边提示可以滑动的一个遮罩图。
wxss代码:
/* 顶部导航条 */
.nav {
height: 100rpx;
width: 630rpx;
position: relative;
box-sizing: border-box;
overflow: hidden;
font-size: 0;
line-height: 100rpx;
white-space: nowrap;
opacity: 0;
transition: all 300ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;
}
.nav.showScroll {
opacity: 1;
}
.slideLine {
height: 8rpx;
/* width: 24px; */
position: absolute;
top: 94rpx;
/* top: 0; */
background: #e64340;
transition: all 300ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;
}
.nav-item {
/* padding: 0 5px; */
margin: 0 5px;
position: relative;
display: inline;
/* height: 100rpx; */
text-align: center;
font-size: 14px;
color: #666;
border-bottom: none;
/* background: green; */
transition: all 500ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;
}
.nav-item .hot{
width: 19rpx;
height: 19rpx;
position: absolute;
right: -5rpx;
top: -5rpx;
}
.nav-item.active {
color: #e64340;
/* height: 94rpx; *//* border-bottom: 8rpx solid #e64340; */
}
.page-top {
width: 100%;
position: relative;
background: white;
}
.page-top.top {
position: fixed;
top: 0;
left: 0;
z-index: 99999;
}
.search {
position: absolute;
right: 30rpx;
top: 20rpx;
width: 60rpx;
height: 60rpx;
z-index: 999999;
}
.mask-scroll {
position: absolute;
right: 120rpx;
top: 0;
width: 45rpx;
height: 100rpx;
z-index: 999999;
}
js代码:
data: {
slideWidth: 38, // 导航滑块长度
sliedeLeft: 5, // 导航滑块距离
showMaskScroll: true, // 是否显示顶部遮罩
},
switchNav(event) {
let that = this;
let listLength = that.data.navData.length;
let cur = home.getDataSet(event, 'current');
let id = home.getDataSet(event, 'id');
let name = home.getDataSet(event, 'name');
let onheadactive = event.currentTarget.offsetLeft; // 元素距离左侧的位置
let winweight = this.data.windowWidth; // 设备宽度
let domWidth = ''; // 元素的宽度
let query = wx.createSelectorQuery();
query.select('.navItem' + cur).boundingClientRect(function (rect) {
domWidth = rect.width;
let distance = onheadactive - winweight / 2 + domWidth / 2;
let sliedeLeft = onheadactive;
if (sliedeLeft <= 0) {
sliedeLeft = 0;
}
console.log('navScrollLeft', distance)
//tab选项居中
that.setData({
navScrollLeft: distance,
slideWidth: domWidth,
sliedeLeft,
currentIndex: 0
})
}).exec();
// 最后一个元素隐藏遮罩层
if (cur + 1 >= listLength) {
that.setData({
showMaskScroll: false
})
} else {
that.setData({
showMaskScroll: true
})
}
},