实现右边内容滑动,左边侧栏联动被选中
效果
小程序滑动效果.gif
实现方式
- wsml
<view class="container">
<view class='content'>
<view class="box">
<view class="left">
<scroll-view scroll-y="true" style="height:{{scrollHeight}}px;" scroll-top="{{scrollTopLeft}}">
<view wx:for="{{list}}" data-index="{{index}}" bindtap="toScrollView">
<view class="left-item {{selectedSub==index?'left-active':''}}">侧栏{{index+1}}</view>
</view>
</scroll-view>
</view>
<view class="right">
<scroll-view scroll-y="true" style="height:{{scrollHeight}}px;" scroll-into-view="{{toView}}" scroll-top="0" bindscroll="scrollTo" scroll-with-animation>
<view wx:for="{{list}}" id="position{{index}}">
<view class="right-item">
<view class="right-classify-title">分类名称{{index+1}}</view>
<view wx:for="{{item.list}}">
<view class="flex" style="height:80px;width:100%;">
<image src="/assets/images/recharge.jpg" style="width:100rpx;height:100rpx;"></image>
<view>内容{{index+1}}</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
</view>
-
// pages/purchase/index.js
let scrollDdirection = 0; // 用来计算滚动的方向
Page({
/**
* 页面的初始数据
*/
data: {
selectedSub: 0, // 选中的分类
scrollHeight: 0, // 滚动视图的高度
list: Array.from(Array(8), (item, index) => {
return {
title: "分类",
list: Array.from(Array(10))
}
}),
toView: 'position0' // 滚动视图跳转的位置
scrollTopLeft: 0, // 左边滚动位置随着右边分类而滚动
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
// 获取设备信息
wx.getSystemInfo({
success: res => {
this.setData({
scrollHeight: res.windowHeight
})
}
})
// 获取数据
this.getData();
},
// 获取数据
getData(){
setTimeout(() => {
// 异步请求数据,请求完毕并且渲染数据之后才可以执行lisenerScroll
this.setData({
// list:requestData // 得到请求的数据,并且渲染视图
},() => {
// 获取所有分类的头部偏移量
this.lisenerScroll();
})
},300)
},
/**
* 跳转滚动条位置
*/
toScrollView(e) {
const {
selectedSub
} = this.data
const {
index
} = e.currentTarget.dataset
let left_ = 0
if (index > 3) {
left_ = (index - 3) * 50 // 左边侧栏item高度为50,可以根据自己的item高度设置
}
this.setData({
selectedSub: index,
toView: `position${index}`,
scrollTopLeft: left_
})
},
/**
* 获取右边每个分类的头部偏移量
*/
lisenerScroll() {
// 获取各分类容器距离顶部的距离
new Promise(resolve => {
let query = wx.createSelectorQuery();
for (let i in this.data.list) {
query.select(`#position${i}`).boundingClientRect();
}
query.exec(function(res) {
resolve(res);
});
}).then(res => {
this.data.list.forEach((item, index) => {
item.offsetTop = res[index].top
})
this.setData({
scrollInfo: res,
list: this.data.list
})
});
},
/**
* 监听滚动条滚动事件
*/
scrollTo(e) {
const scrollTop = e.detail.scrollTop; //滚动的Y轴
const {
selectedSub,
list
} = this.data;
let left_ = 0
if (scrollDdirection < scrollTop) {
// 向上滑动
scrollDdirection = scrollTop
// 计算偏移位置
if (selectedSub < list.length - 1 && scrollTop >= list[selectedSub + 1].offsetTop) {
if (selectedSub > 2) {
left_ = (selectedSub - 2) * 50
}
this.setData({
selectedSub: selectedSub + 1,
scrollTopLeft: left_
})
}
} else {
// 向下滑动
scrollDdirection = scrollTop
// 计算偏移位置
if (selectedSub > 0 && scrollTop < list[selectedSub].offsetTop && scrollTop > 0) {
if (selectedSub > 3) {
left_ = (selectedSub - 4) * 50
}
this.setData({
selectedSub: selectedSub - 1,
scrollTopLeft: left_
})
}
}
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function() {
},
})
- wxss
/* pages/purchase/index.wxss */
.box {
display: flex;
}
.left {
width: 25vw;
}
.left-item {
padding: 30rpx 20rpx;
background-color: #eee;
}
.left-active {
background-color: #fff;
border-left: 6rpx solid red;
}
.right {
width: 75vw;
background: #fff;
padding: 0 20rpx;
}
.right-classify-title {
font-size: 0.9rem;
color: #777;
height: 50px;
line-height: 60px;
}
网友评论