小程序scroll-view滚动组件,左边导航栏与右边内容联动,选择区间实现

  • 效果
    具体思路同 小程序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

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值