• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

点击按钮页面滚动到对应位置锚点

武飞扬头像
别来…无恙
帮助1

前言

回到顶部,相信大家都不陌生吧,这个功能可谓是随处可见,也是作为一名前端开发工程师手到擒来的一个功能点。但前几天刚刚好有一个类似于回到顶部(锚点)的功能点把我卡住了,就是点击锚点按钮页面滚到对应位置。如果说直接显示到对应位置那可真是太简单了,但过程需要点过渡的动画就难到我了,硬生生做了两个小时(说到底还是自己技术不过关)。

需求

点击锚点按钮页面带过渡动画显示到对应位置

HTML

因后期需实现页面滚动到对应位置时锚点高亮,故使用 View Design 框架的步骤条实现锚点按钮样式,为后期功能实现打好基础。

<Steps class="Steps" direction="vertical">
   <Step status="wait" class="stepItem" :key="index" @click.native="changAnchor(item)" v-for="(item, index) in teacherData.groupList" :content="item.groupName"></Step>
</Steps>

失败思路

首次实现时的思路是,如果目前的滚动条高度大于锚点盒子顶部距离页面顶部的高度,便以每10毫秒的速度往上滚(减20),同理若小于则往下滚(加20)。等两则高度相等时则结束此方法(清除计时器),注意 : 一定要清除计时器。(此思路存在问题,好奇的同学可以先思考一下错在哪再往下看)。

失败方法

/**
   * changAnchor 点击切换锚点
   * (this.$refs['scroll'] as any).wrap.scrollTop为本项目自己编写的一个页面滚动条,故此代码不能直接copy复用。
   * 此处代码有些庸余,本应该在计时器前声明一下(this.$refs['scroll'] as any).wrap.scrollTop,但声明之后报了一下莫名其妙的错误,就没有继续往下深究。
  */
  changAnchor(item: any){
    if(this.clickShow === true){
      this.clickShow = false // 用于判断上一次滚动是否执行完毕,如若不执行完毕不执行下一次滚动,否则多次点击动画会出现错乱
      const targetbox: any = document.getElementById(item.firstStepId); // 获取对应锚点盒子
      const target = targetbox.offsetTop - 110;
      this.timeTop = setInterval(() => {
        if((this.$refs['scroll'] as any).wrap.scrollTop > target){
          (this.$refs['scroll'] as any).wrap.scrollTop -= 20
        }
        if((this.$refs['scroll'] as any).wrap.scrollTop < target) {
          (this.$refs['scroll'] as any).wrap.scrollTop  = 20
        }
        if((this.$refs['scroll'] as any).wrap.scrollTop === target){
          clearInterval(this.timeTop);
          this.clickShow = true
        }
      }, 1);
    }
  }
学新通

失败思路解析

细心的同学可能就会发现这个方法的漏洞,相加相减实现它的动画效果没毛病,但以每次20为间距来相加相减,若此时相加后或者相减后的最后一次距离小于20,那再执行一次相加相减岂不是刚好跳过了它们相等时的值?此时函数会继续往下执行,页面便会一直向上滚或者往下滚,并且因为没有清除计时器边永久执行此方法。

可行思路

继续延用上诉的思路,但在此基础上进行优化。当相加或相减的距离小于20时,将滚动条高度直接赋值成锚点盒子的高度。

可行方法

/**
   * changAnchor 点击切换锚点
  */
  changAnchor(item: any){
    if(this.clickShow === true){
      this.clickShow = false // 用于判断上一次滚动是否执行完毕,如若不执行完毕不执行下一次滚动,否则多次点击动画会出现错乱
      const targetbox: any = document.getElementById(item.firstStepId); // 获取对应锚点盒子
      const target = targetbox.offsetTop - 110;
      this.timeTop = setInterval(() => {
        if((this.$refs['scroll'] as any).wrap.scrollTop > target   20){
          (this.$refs['scroll'] as any).wrap.scrollTop -= 20
        } else if((this.$refs['scroll'] as any).wrap.scrollTop <= target  20 && (this.$refs['scroll'] as any).wrap.scrollTop >= target){
          (this.$refs['scroll'] as any).wrap.scrollTop = target
        }
        if((this.$refs['scroll'] as any).wrap.scrollTop < target - 20) {
          (this.$refs['scroll'] as any).wrap.scrollTop  = 20
        } else if((this.$refs['scroll'] as any).wrap.scrollTop >= target - 20 && (this.$refs['scroll'] as any).wrap.scrollTop <= target){
          (this.$refs['scroll'] as any).wrap.scrollTop = target
        }
        if((this.$refs['scroll'] as any).wrap.scrollTop === target){
          clearInterval(this.timeTop);
          this.clickShow = true
        }
      }, 1);
    }
  }
学新通

效果图:
学新通

总结

本题的思路其实跟循环差不多,只是单纯的把循环事件变成计时器来使用,所以其他同学若是感兴趣也可以试着使用循环的方式来实现。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbcjjh
系列文章
更多 icon
同类精品
更多 icon
继续加载