先上案例最终效果:
案例实现功能:
1.导航栏横向滚动效果
2.当前元素有下划线标识
3.点击元素,导航栏滚动到相应位置
以下将分步骤逐步完善陈述这些功能,最终会呈现所有代码
1.引用组件scroll-view,达到滚动效果
万丈高楼平地起,首先要达到横向滚动的效果
wxml
<view>
<scroll-view scroll-x="true" enable-flex="true" class="scroll">
<block wx:for="{{ nav }}" wx:for-item="item" wx:for-index="index" wx:key="index">
<view class="nav-item">
{{ item }}
</view>
</block>
</scroll-view>
</view>
scroll-view:小程序原生组件,使得里面的元素可以左右或上下滚动,scroll-x设置内容横向滚动,enable-flex允许内容使用flex布局(这里只是允许,还需要在相应的class中还需要添加flex布局语句,即display:flex;)
block与view:在小程序中block是不做数据渲染的,它本身在页面中不占据任何空间,它用于做逻辑处理的容器,与wx:for,wx:if等属性联用。以上代码把for放到view最终效果是一样的。
wxss
.scroll {
width: 90%;
height: 80rpx;
line-height: 80rpx;
margin: 0 auto;
display: flex;
/* 超出部分隐藏 */
overflow: hidden;
/* 文本不换行 */
white-space: nowrap;
}
.nav-item {
margin-right: 20rpx;
}
截至到此处只引用了js代码中一个nav数组
2.点击元素时添加下划线标识,并滚动到相应位置(最终效果)
实现思路:
1.添加下滑线标识:给元素添加点击事件,并动态绑定class,点击某个元素,传递此元素的下标到绑定方法中,该表变量current的值为当前下标,如此一来,在动态绑定的class中current对应某个index,触发current-nav样式
2.滚动位置:在点击元素之后,动态设置scroll-left的值,即可控制滚动条滚动距离。问题在于我们要滚动多少距离?我的设置是滚动距离为使得每个项的左边界位于手机屏幕的中间,若距离不够则保留默认滚动距离。微信小程序的特殊优势,点击事件方法的参数(events)中包含点击元素的横向滚动宽度,我们拿到这个值,再获取手机宽度即可
wxml
<view>
<scroll-view scroll-x="true" enable-flex="true" class="scroll" scroll-left="{{ scrollLeft }}" scroll-with-animation="true">
<block wx:for="{{ nav }}" wx:for-item="item" wx:for-index="index" wx:key="index">
<view class="nav-item {{ current==index?'current-nav':'' }}" bindtap="currentNav" data-index="{{ index }}" >
{{ item }}
</view>
</block>
</scroll-view>
</view>
scroll-left:控制滚动条向左滚动距离,默认为0;
scroll-with-animation:滚动效果
data-index="{{ index }}":传递点击元素的下标
js
// pages/nav/nav.js
Page({
/**
* 页面的初始数据
*/
data: {
nav: ['全部','水果蔬菜','家电','图书','生活用品','测试','还是测试','依然是测试'],
// 当前项目
current: 0,
// 滚动栏滚动距离
scrollLeft: 0,
// 窗体宽度
windowWidth: 0
},
onLoad: function (options) {
// 设置标题
wx.setNavigationBarTitle({
title: '导航栏案例',
});
// 获取窗体宽度
wx.getSystemInfo({
success: (result) => {
this.setData({
windowWidth: result.windowWidth
})
},
})
},
/**
*
* 导航栏点击响应事件
*
* 1.点击项目出现下滑线
* 2.点击项目,导航栏滚动,使得项目出现再屏幕固定位置
*
*/
currentNav: function (e) {
console.log(e);
let index = e.currentTarget.dataset.index;
let scrollLeft = e.currentTarget.offsetLeft - ( this.data.windowWidth * 0.9 ) / 2;
this.setData({
current: index,
scrollLeft: scrollLeft
})
}
})
因为我的滚动条设置宽度为屏幕的90%,所以计算滚动位置时略有不同,逻辑跟上面的陈述一致
打印currentNav的参数:
offsetLeft:点击元素的横向距离
index:元素的下标(我点击了第二个元素)
wxss
.scroll {
width: 90%;
height: 80rpx;
line-height: 80rpx;
margin: 0 auto;
display: flex;
/* 超出部分隐藏 */
overflow: hidden;
/* 文本不换行 */
white-space: nowrap;
}
.nav-item {
margin-right: 20rpx;
}
// 添加下边界
.current-nav {
border-bottom: 1px solid #f86442;
}
无论是小程序还是web项目,做相似的功能时,实现的思路是一致的,只是使用的工具不同。解决问题的思路是一切的开始,也是最重要的部分。