列表加锚点定位

14 篇文章 0 订阅
14 篇文章 0 订阅

有时候会有一些特别的需求,比如说想实现一个列表,而且列表里面有多条同类型的数据,想区分他们,但是普通的table实现不了,只能自己另辟蹊径了,滚动的时候固定当前的头部,横向滚动固定左侧数据等;如下图: 

代码例子如下:

<template>
  <div class="app-container">
    <div class="num-box">
      <div ref="numBoxLoading">
        <div id="srcoll-wrap" ref="numBox" class="content" style="height:400px;width: 800px" @scroll="tableBodyLeftScroll">
          <div v-for="(n, index) in numPoolTableData" :key="index">
            <div class="num-title">
              <div class="left">title1</div>
              <div class="left">title2</div>
              <div class="scrollTime">
                <div v-for="(t, index) in n.header" :key="index" class="time">{{ t }}</div>
              </div>
            </div>
            <div v-for="num in n.list" class="num-content">
              <div class="left">{{ num.title1 }}</div>
              <div class="left">{{ num.title2 }}</div>
              <div class="scrollTime">
                <div v-for="(t, index) in num.sourceList" :key="index" class="time">
                  <div >{{t}}</div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>

export default {
  data() {
    return {
      numPoolTableData: [],
      offsetTopList: []
    }
  },
  created() {
    this.getNumList()
  },
  methods: {
    tableBodyLeftScroll() {
      const scrollLeft = document.getElementById('srcoll-wrap').scrollLeft
      const scrollTop = document.getElementById('srcoll-wrap').scrollTop
      const numTitle = document.querySelectorAll('.num-title')
      // 头部固定,纵向滚动
      this.offsetTopList.forEach((v, index) => {
        if (scrollTop >= v) {
          for (let n = 0; n < numTitle.length; n++) {
            numTitle[n].style.top = null
          }
          numTitle[index].style.top = (scrollTop -  v) + 'px'
        }
      })
      // 横向滚动
      const scrollTimeContent = document.querySelectorAll('.scrollTime')
      for (let j = 0; j < scrollTimeContent.length; j++) {
        scrollTimeContent[j].style.left = -scrollLeft + 'px'
      }
      const scrollNumContent = document.querySelectorAll('.left')
      for (let i = 0; i < scrollNumContent.length; i++) {
        scrollNumContent[i].style.left = scrollLeft + 'px'
      }
    },
    getNumList() {
      const _this = this
      _this.offsetTopList = []
      _this.numPoolTableData = [
        {
          header: ["08:00-09:00", "09:00-10:00", "10:00-11:00", "11:00-12:00", "13:00-14:00", "14:00-15:00"],
          list: [
            {
              title1: 'title1',
              title2: 'title2',
              sourceList: [1, 2, 3, 4, 5, 6]
            },
            {
              title1: 'title1',
              title2: 'title2',
              sourceList: [1, 2, 3, 4, 5, 6]
            },
            {
              title1: 'title1',
              title2: 'title2',
              sourceList: [1, 2, 3, 4, 5, 6]
            }
          ]
        },
        {
          header: ["08:00-09:00", "09:00-10:00", "10:00-11:00", "11:00-12:00", "13:00-14:00", "14:00-15:00"],
          list: [
            {
              title1: 'title1',
              title2: 'title2',
              sourceList: [1, 2, 3, 4, 5, 6]
            },
            {
              title1: 'title1',
              title2: 'title2',
              sourceList: [1, 2, 3, 4, 5, 6]
            },
            {
              title1: 'title1',
              title2: 'title2',
              sourceList: [1, 2, 3, 4, 5, 6]
            },
            {
              title1: 'title1',
              title2: 'title2',
              sourceList: [1, 2, 3, 4, 5, 6]
            }
          ]
        },
        {
          header: ["05:00-06:00", "06:00-07:00", "07:00-08:00", "08:00-09:00", "09:00-10:00", "11:00-12:00"],
          list: [
            {
              title1: 'title1',
              title2: 'title2',
              sourceList: [1, 2, 3, 4, 5, 6]
            },
            {
              title1: 'title1',
              title2: 'title2',
              sourceList: [1, 2, 3, 4, 5, 6]
            },
            {
              title1: 'title1',
              title2: 'title2',
              sourceList: [1, 2, 3, 4, 5, 6]
            },
            {
              title1: 'title1',
              title2: 'title2',
              sourceList: [1, 2, 3, 4, 5, 6]
            }
          ]
        },
        {
          header: ["08:00-09:00", "09:00-10:00", "10:00-11:00", "11:00-12:00", "13:00-14:00", "14:00-15:00"],
          list: [
            {
              title1: 'title1',
              title2: 'title2',
              sourceList: [1, 2, 3, 4, 5, 6]
            },
            {
              title1: 'title1',
              title2: 'title2',
              sourceList: [1, 2, 3, 4, 5, 6]
            },
            {
              title1: 'title1',
              title2: 'title2',
              sourceList: [1, 2, 3, 4, 5, 6]
            },
            {
              title1: 'title1',
              title2: 'title2',
              sourceList: [1, 2, 3, 4, 5, 6]
            }
          ]
        }
      ]
      // 初始化数据的时候,先记录offsetTop
      this.$nextTick(() => {
        const numTitle = document.querySelectorAll('.num-title')
        for (let n = 0; n < numTitle.length; n++) {
          _this.offsetTopList.push(numTitle[n].offsetTop)
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>
  .num-box{
    .left,.right{
      min-width: 140px;
      max-width: 140px;
      text-align: center;
      padding: 0px 5px;
      background: #fff;
      z-index: 1;
      &:nth-of-type(2){
        border-right: 1px solid #e1e1e1;
      }
    }
    .time{
      color: #42424D;
      text-align: center;
      width: 140px;
      padding: 0px 5px;
    }
    .num-title{
      color: #A2A2B2;
      font-size:14px;
      display: flex;
      display: -webkit-flex;
      align-items: center;
      position: relative;
      z-index: 2;
      .left{
        position: relative;
      }
      .left,.time{
        display: flex;
        display: -webkit-flex;
        align-items: center;
        justify-content: center;
        height: 50px;
        border-top: 1px solid #e1e1e1;
        border-bottom: 1px solid #e1e1e1;
        background-color: #ddeeff;
        color: #4b6a9c;
      }
    }
    .content{
      overflow: auto;
      position: relative;
      .num-content{
        color: #787880;
        font-size:14px;
        display: flex;
        display: -webkit-flex;
        align-items: center;
        cursor: pointer;
        .left{
          position: relative;
        }
        .left,.time{
          display: flex;
          display: -webkit-flex;
          align-items: center;
          justify-content: center;
          height: 60px;
        }
      }
    }
  }
  .scrollTime{
    display: flex;
    flex: 1;
    float: left;
    z-index: 0;
    margin-right: 8px;
  }
</style>

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值