vue.js封装锚点组件

记录一下使用vue.js封装锚点组件的代码。项目中存在固定头部的情况。
主要思路为在组件初始化时,将锚点列表中的位置一次性获取,在点击锚点时,直接使用document.documentElement.scrollTop进行定位。添加页面滑动事件,在页面滑动时判断当前页面展示部分属于哪个锚点,动态渲染锚点高亮。
完整组件地址:传送门

// 分步滑动页面进行定位
    byStepShow: function(scrollTop) {
      let top = Math.abs(document.documentElement.scrollTop - scrollTop)
      const $this = this
      const animationCallback = function() {
        top -= $this.stepHeight
        if (top <= 0) {
          document.documentElement.scrollTop = scrollTop
          return
        } else {
          requestAnimationFrame(animationCallback)
          if (document.documentElement.scrollTop > scrollTop) {
            document.documentElement.scrollTop = document.documentElement.scrollTop - top
          } else {
            document.documentElement.scrollTop = document.documentElement.scrollTop + top
          }
        }
      }
      animationCallback()
    },
    // 滚动页面时的监听回调函数
    onScroll: function() {
      if (this.anchorList.length === 0) {
        return
      }
      if (this.anchorPosition.length === 0 || this.scrollAlwaysComputePosition) {
        this.anchorList.forEach(anchor => {
          const toElement = document.querySelector('#' + anchor.id)
          if (toElement) {
            this.anchorPosition.push({
              id: anchor.id,
              position: toElement.offsetTop + (this.fixedHeader ? -this.headerHeight : this.headerHeight)
            })
          }
        })
      }
      // 因为页面头部信息是固定高度的,需要在浏览器滚动条滚动页面时,加上头部高度计算定位位置
      const headerHeight = this.fixedHeader ? -this.headerHeight : this.headerHeight
      let scrolled = document.documentElement.scrollTop || document.body.scrollTop
      scrolled = Math.ceil(headerHeight + scrolled)
      // 将锚点位置列表根据锚点位置排序
      this.anchorPosition.sort(function(pre, next) { return pre.position - next.position })
      // 根据页面位置进行当前锚点高亮
      for (let i = 0; i < this.anchorPosition.length - 1; i++) {
        if (scrolled >= this.anchorPosition[i].position && scrolled < this.anchorPosition[i + 1].position) {
          this.activeAnchor = this.anchorPosition[i].id
        }
      }
      if (this.anchorPosition.length === 0) {
        return
      }
      if (scrolled >= this.anchorPosition[this.anchorPosition.length - 1].position) {
        this.activeAnchor = this.anchorPosition[this.anchorPosition.length - 1].id
      }
    }

你可能感兴趣的:(vue.js封装锚点组件)