vue-antdesign【封装时间轴定位滚动】

效果图:

在这里插入图片描述

<a-timeline>
      <a-timeline-item v-for="(item,index) in newdirectoryArr" :key="index" :class="currentClass(index)" @click="currentInfo(index)">
        {{item.timeLineName}}
      </a-timeline-item>
 </a-timeline>
newdirectoryArr:
[
    {
        "timeLineName": "基本信息",
        "timeLineIdx": 0
    },
    {
        "timeLineName": "作者简介",
        "timeLineIdx": 2
    },
    {
        "timeLineName": "创作背景",
        "timeLineIdx": 3
    },
    {
        "timeLineName": "历代版本及传刻情况",
        "timeLineIdx": 4
    },
    {
        "timeLineName": "文献价值",
        "timeLineIdx": 5
    },
    {
        "timeLineName": "相关推荐",
        "timeLineIdx": 6
    },
    {
        "timeLineName": "文献目录",
        "timeLineIdx": 1
    }
]

根据timeLineIdx排序然后渲染至时间线

let newArr = JSON.parse(JSON.stringify(this.newdirectoryArr))
      newArr.sort((a, b) => {
         return a.timeLineIdx - b.timeLineIdx
       })
this.newdirectoryArr = newArr 

设置一个默认目录位置,从0开始,也就是第一个,根据点击的下标与值相匹配时显示对应class样式

  newCurrentNum: 0, //当前目录

// 样式名切换
    currentClass (index) {

      return [this.newCurrentNum == index ? 'isActive' : 'noActive'];
    },

两种情况
1.点击目录相应位置时,直接定位到对应位置,并且高亮当前目录

//目录选中样式
    currentInfo (index) {
      this.newCurrentNum = index;
      // 添加锚点
      let jump = document.querySelectorAll(".lit_item");
      let total = jump[index].offsetTop;
      let distance =
        document.documentElement.scrollTop || document.body.scrollTop;
      // 平滑滚动,时长500ms,每10ms一跳,共50跳
      let step = total / 50;
      if (total > distance) {
        smoothDown();
      } else {
        let newTotal = distance - total;
        step = newTotal / 50;
        smoothUp();
      }
      function smoothDown () {
        if (distance < total) {
          distance += step;
          document.body.scrollTop = distance;
          document.documentElement.scrollTop = distance;
          setTimeout(smoothDown, 10);
        } else {
          document.body.scrollTop = total;
          document.documentElement.scrollTop = total;
        }
      }
      function smoothUp () {
        if (distance > total) {
          distance -= step;
          document.body.scrollTop = distance;
          document.documentElement.scrollTop = distance;
          setTimeout(smoothUp, 10);
        } else {
          document.body.scrollTop = total;
          document.documentElement.scrollTop = total;
        }
      }
    },
    

2.鼠标滚动页面浏览时,显示到相应目录内容时,高亮其目录

1.先在method中定义滚动事件

// 滚动事件
    onScroll (e) {
      let scrolled =
        document.documentElement.scrollTop || document.body.scrollTop;
      // if (scrolled > 470) {
      //   console.log(scrolled)
      //   this.currentNumber = 0;
      // }

      // 滚动选中锚点
      let scrollItems = document.querySelectorAll('.lit_item');
      for (let i = scrollItems.length - 1; i >= 0; i--) {
        // 判断滚动条滚动距离是否大于当前滚动项可滚动距离
        let scrolled = document.documentElement.scrollTop || document.body.scrollTop;
        let judge = scrolled >= scrollItems[i].offsetTop - scrollItems[0].offsetTop
        if (judge) {
          this.newCurrentNum = i
          break
        }
      }
    },
 2.在mounted中定义监听滚动事件
 mounted: function () {
    this.$nextTick(function () {
      window.addEventListener("scroll", this.onScroll);
    });
  },
 this.$nextTick:官方解释
				将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。
				它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。
					
				个人理解
				等待DOM加载完成后再执行
---------------------------------
	
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值