-
效果
具体思路同 小程序scroll-view滚动组件,左边导航栏与右边内容联动效果实现
不同的是上面的文章为单选,这里是选择范围可以选择两个月份。
-
思路
主要是在选择月的时候通过判断一个数组,如果数组里有两个值,则再次点击会清空数组重新选择第一个push进数组;如果数组里有一个值,点击的时候会push进第二个;可以允许选择的两个值相等。 -
具体代码
<!--pages/monthOfficeModule/monSectCalendar/monSectCalendar.wxml--> <!-- 选择项目 --> <view class='cont-pro'> <!-- 左侧列表 --> <view class='pro-left font28 color9'> <scroll-view class='swipter-nav' scroll-y="true" style="height:100%;"> <view wx:for="{{serviceTypes}}" wx:key="index" class='pro-title {{index==currentLeft?"bgWhite":""}}' data-id='item{{index}}' bindtap='proItemTap' data-pos='{{index}}'>{{item.type}}</view> </scroll-view> </view> <!-- 右侧列表 --> <view class="content"> <scroll-view class='pro-right' scroll-y="true" scroll-with-animation="true" scroll-into-view="{{selectId}}" bindscroll="onScroll" style="height:{{winHeight}}px;" scroll-top="{{scrollVal}}"> <!-- id要用来实现点击左侧右侧滚动至相应位置的效果;class(pro-box)要用来计算右侧对应左侧某一分类的高度 --> <!-- id: item0, item1, item2... (注意:不能直接使用数字或汉字做id)--> <!-- class='pro-box' style="{{item.id=='2017' ? 'margin-bottom: 100rpx;' : ''}}" --> <view class='pro-box' wx:for="{{serviceTypes}}" wx:key="index" wx:for-index="index" wx:for-item="item" id="item{{index}}"> <!-- 右侧列表里的标题,高度为50px --> {{item.index}} <view class="item-title">{{item.type}}</view> <!-- <view class='pro-item {{ (item.id == startMonId || item.id == endMonId) ? "activeSelect" : "" }}' wx:for="{{item.services}}" wx:key="index" bindtap='selectMon' data-id="{{item.id}}"> --> <view class='pro-item {{ item.check ? "activeSelect" : "" }}' wx:for="{{item.services}}" wx:key="index" bindtap='selectMon' data-id="{{item.id}}"> <view class='pro-text'> {{item.index}} <view class='item-name'>{{item.name}}</view> </view> </view> </view> </scroll-view> </view> </view>
// pages/monthOfficeModule/monSectCalendar/monSectCalendar.js Page({ //右侧分类的高度累加数组 //比如:[洗车数组的高度,洗车+汽车美容的高度,洗车+汽车美容+精品的高度,...] heightArr: [], //记录scroll-view滚动过程中距离顶部的高度 distance: 0, /** * 页面的初始数据 */ data: { currentLeft: 0, //左侧选中的下标 selectId: "item0", //当前显示的元素id scrollTop: 0, //到顶部的距离 serviceTypes: [ { type: '2021年', id: '2021', services: [ // id,作为匹配选中状态的标识 { name: '4月', id: '202104', check: false, }, { name: '3月', id: '202103', check: false, }, { name: '2月', id: '202102', check: false, }, { name: '1月', id: '202101', check: false, }, ], }, { type: '2020年', id: '2020', services: [ { name: '12月', id: '202012', check: false, }, { name: '11月', id: '202011', check: false, }, { name: '10月', id: '202010', check: false, }, { name: '9月', id: '202009', check: false, }, { name: '8月', id: '202008', check: false, }, { name: '7月', id: '202007', check: false, }, { name: '6月', id: '202006', check: false, }, { name: '5月', id: '202005', check: false, }, { name: '4月', id: '202004', check: false, }, { name: '3月', id: '202003', check: false, }, { name: '2月', id: '202002', check: false, }, { name: '1月', id: '202001', check: false, }, ], }, { type: '2019年', id: '2019', services: [ { name: '12月', id: '201912', check: false, }, { name: '11月', id: '201911', check: false, }, { name: '10月', id: '201910', check: false, }, { name: '9月', id: '201909', check: false, }, { name: '8月', id: '201908', check: false, }, { name: '7月', id: '201907', check: false, }, { name: '6月', id: '201906', check: false, }, { name: '5月', id: '201905', check: false, }, { name: '4月', id: '201904', check: false, }, { name: '3月', id: '201903', check: false, }, { name: '2月', id: '201902', check: false, }, { name: '1月', id: '201901', check: false, }, ], }, ], //项目列表数据 staffList: [], coupons: [], heightArr: [], // perMonId: '202104', startMonId: '202104', endMonId: '202101', currindex: 0, scrollVal: 0, selectList: [], platformIdIndex: null }, //选择项目左侧点击事件 currentLeft:控制左侧选中样式 selectId:设置右侧应显示在顶部的id proItemTap(e) { this.setData({ currentLeft: e.currentTarget.dataset.pos, selectId: e.currentTarget.dataset.id }) }, selectMon (e) { let platformIdIndex = this.data.platformIdIndex let id = e.currentTarget.dataset.id let items = this.data.serviceTypes let startMonId = '' let endMonId = '' let selectList = this.data.selectList if (selectList.length == 2) { if (selectList[0] == selectList[1]) { selectList = selectList.slice(0, 1) items.forEach((item, i) => { item.services.forEach((item1, i) => { if (item1.id == id) { item1.check = true selectList.push(item1.id) } }) }) if (selectList[0] !== selectList[1]) { let startDate = selectList[1] let endDate = selectList[0] let startyear = startDate.substring(0,4) let startmonth = startDate.substring(4,6) let endyear = endDate.substring(0,4) let endmonth = endDate.substring(4,6) let startDateTime = startyear + '-' + startmonth let endDateTime = endyear + '-' + endmonth wx.redirectTo({ url: '/pages/monthOfficeModule/monthAnalysis/monthAnalysis?startDateTime=' + startDateTime + '&endDateTime=' + endDateTime + '&platformIdIndex=' + platformIdIndex }) } } else { selectList = [] items.forEach((item, i) => { item.services.forEach((item1, i) => { item1.check = false if (item1.id == id) { item1.check = true selectList.push(item1.id) } }) }) } } else { items.forEach((item, i) => { item.services.forEach((item1, i) => { if (item1.id == id) { item1.check = true selectList.push(item1.id) } }) }) let a = parseInt(selectList[1]) let b = parseInt(selectList[0]) let temp = null if (a > b) { temp = a.toString() a = b.toString() } else { temp = selectList[0] a = selectList[1] } let startDate = a let endDate = temp let startyear = startDate.substring(0,4) let startmonth = startDate.substring(4,6) let endyear = endDate.substring(0,4) let endmonth = endDate.substring(4,6) let startDateTime = startyear + '-' + startmonth let endDateTime = endyear + '-' + endmonth wx.redirectTo({ url: '/pages/monthOfficeModule/monthAnalysis/monthAnalysis?startDateTime=' + startDateTime + '&endDateTime=' + endDateTime + '&platformIdIndex=' + platformIdIndex }) } this.setData({ "perMonId": id, "serviceTypes": items, "selectList": selectList }) }, //计算右侧每一个分类的高度,在数据请求成功后请求即可 selectHeight() { let _this = this // 获得每个元素据顶部的高度,组成一个数组,通过高度与scrollTop的对比来知道目前滑动到那个区域 let heightArr = []; let h = 0; //创建节点选择器 const query = wx.createSelectorQuery(); //选择id query.selectAll('.pro-box').boundingClientRect() query.exec(function (res) { // console.log('res', res) //res就是 所有标签为contlist的元素的信息 的数组 res[0].forEach((item) => { h += item.height; heightArr.push(h); }) _this.setData({ heightArr: heightArr, "scrollVal": heightArr[_this.data.currindex - 1] }) // 算出每块区域到达的高度 // console.log('heightArr', heightArr) // [210, 800, 1390] }) }, onScroll:function(e){ const scrollTop = e.detail.scrollTop + 1; const scorllArr = this.data.heightArr; // console.log('scrollTop', scrollTop, this.data.winHeight) const _this = this; if (scrollTop + 5 >= scorllArr[scorllArr.length - 1 ] - (_this.data.winHeight)){ _this.setData({ currentLeft: scorllArr.length - 1, }) }else{ for(let i=0;i< scorllArr.length; i++){ // 如果滚动的高度大于0且小于第一个大元素的高度,左侧当前选中还是第一个 if(scrollTop >= 0 && scrollTop <scorllArr[0]){ _this.setData({ currentLeft: 0, }) }else if( scrollTop >=scorllArr[i-1] && scrollTop <scorllArr[i]){ // 如果滚动的高度大于等于上一个大元素的高度,且小于当前大元素最终所到达的高度,则左侧选中当前的 _this.setData({ currentLeft: i, }) } } } }, findIndex(l, o) { var objStr = JSON.stringify(o) // console.log('objStr', objStr) return l.reduce((index, ele, i) => { // console.log('index111', index, ele, i) if (JSON.stringify(ele.id) === objStr) { return i } else { return index } }, -1) }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { let startDate = options.startDate let endDate = options.endDate let getSelectList = [] let startyear = startDate.split('-')[0] let startmonth = startDate.split('-')[1] let endyear = endDate.split('-')[0] let endmonth = endDate.split('-')[1] let currindex = this.findIndex(this.data.serviceTypes, endyear) if (startDate == endDate) { getSelectList = [startyear + startmonth] } else { getSelectList = [startyear + startmonth, endyear + endmonth] } let items = this.data.serviceTypes items.forEach((item, i) => { item.services.forEach((item1, i) => { if (item1.id == getSelectList[0]) { item1.check = true } else if (item1.id == getSelectList[1]) { item1.check = true } }) }) this.setData({ "serviceTypes": items, "startMonId": startyear + startmonth, "endMonId": endyear + endmonth, "currentLeft": currindex, "currindex": currindex, "selectList": getSelectList, "platformIdIndex": options.platformIdIndex }) // console.log('scrollVal', this.data.heightArr, this.data.scrollVal) wx.getSystemInfo({ success: res => { this.setData({ winHeight: res.windowHeight }) } }) this.selectHeight() }, })
/* pages/monthOfficeModule/monSectCalendar/monSectCalendar.wxss */ .cont-pro { font-size: 24rpx; color: #333; } .bgWhite { background: #fff; } .cont-pro { height: 100%; display: flex; background-color: #fff; } .pro-left { width: 170rpx; flex-basis: 170rpx; background-color: #F2F2F2; overflow-y: scroll; } .pro-title { width: 100%; height: 80rpx; line-height: 80rpx; text-align: center; } .pro-right { flex: 1; background-color: #fff; overflow-y: scroll; } .content { flex: 1; } .item-title { width: 100%; height: 40rpx; line-height: 40rpx; padding: 0 32rpx; box-sizing: border-box; font-size: 20rpx; background-color: #F2F2F2; } .item-name { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1; overflow: hidden; word-break: break-all; } .pro-item { width: 100%; display: flex; padding: 30rpx; box-sizing: border-box; border-bottom: 1rpx solid #F2F2F2; } .activeSelect { background-color: #E8380D; color: #fff; } .pro-text { flex: 1; display: flex; flex-direction: column; justify-content: space-between; }
{ "navigationBarTitleText": "月榜", "usingComponents": { "van-tree-select": "@vant/weapp/tree-select/index" }, "navigationBarBackgroundColor": "#E8380D", "navigationBarTextStyle": "white" }
-
参考文章
微信小程序实现左右联动的菜单列表
微信小程序分类-左侧导航与右侧内容联动
小程序滚动组件,左边导航栏与右边内容联动效果实现
小程序滚动组件,左边导航栏与右边内容联动效果实现
scroll-view
小程序scroll-view滚动组件,左边导航栏与右边内容联动,选择区间实现
最新推荐文章于 2023-05-31 09:17:06 发布