vue中锚点的设置 定位滚动界面

2,317 阅读2分钟

前情提要 项目中需要点击按钮定位到对应的位置,有两种方案可以实现。

  • 计算出每个点的在界面中距离,使用jqueryanimation方法定位。
  • 世界使用id,

第一种

提醒 这种很繁琐,想快速使用,可直接看第二种。

  • 文件package.json中引入"jquery": "^3.5.1"
  • webpack.base.conf.jsmodule.exports里加入代码
plugins:[
    new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery",
      "windows.jQuery": "jquery"
    })
  ]
  • 需要的vue文件里地方引入import $ from 'jquery';
  • 需求是实现按模块向上自动滚动,滚动到最底部,再重头开始。所以需要计算每个子模块的高度,并且不可重复。如下图所示,虽然是4个子模块,但是滚动的时候其中两个模块只能算一个。需要去重,去重使用Set()方法。

image.png

提醒 如果滚动最后一屏,则位置只能是最后一屏的滚动距离。

// 获取scrollTopArr
calculateScrollTopArr() {
  var scrollSet = new Set();
  const liArr = this.$refs['scrollBox'].children;
  for(let i = 0; i < liArr.length; i++) {
    if (liArr[i].offsetTop < (this.boxSH - this.boxCH)) {
      scrollSet.add(liArr[i].offsetTop);
    }
  }
  this.scrollTopArr = _.sortBy([...scrollSet, this.boxSH - this.boxCH]);
},
scrollTopAction(index) {
  this.sTimer = setInterval(() => {
      var sT = document.getElementById('scrollBox').scrollTop;
      if (this.scrollTopArr.indexOf(sT) == -1) {
        index =_.findIndex(_.sortBy([...this.scrollTopArr, sT]), e => {
          return e === sT
        })
      } else if (index !== 0 && sT === 0) {
          index = 1;
      } else if ( index != this.scrollTopArr.length -1 && index !== 0 && sT == this.scrollTopArr[this.scrollTopArr.length - 1]) {
        index = this.scrollTopArr.length - 1;
      }
      $("#scrollBox").animate({"scrollTop":  this.scrollTopArr[index]});
      index = (index + 1) % this.scrollTopArr.length;
    }, this.intervalS / this.scrollTopArr.length);
}

总结 只需要计算出offsetTop,放入一个数组,就可以根据自己的需求随便滚动了。这里的animation可以更换成第二种方法中的scroll方法。此处注意timer的使用,避免多次设置,使界面乱跳。

第二种

  • 第二种很简单,形如下图所示。设置父组件id,和子组件的id。 image.png
  • 方法1 scroll(value),滚动到指定的位置value
  • 方法2 handleClick(name) name是子组件的id。通过id获取到子组件的offsetTop,是子组件在父组件中的位置。将offsetTop的值传给scroll()发放即可。
  • 方法3 onscroll() 滚动scrollBox的内容,获取内容所属的区域,让对应的文字高亮。
scroll(value) {
    document.getElementById('scrollBox').scroll({
        left: 0,
        top: value,
        behavior: 'smooth'
    })
},
onscroll() {
    const element = document.getElementById('scrollBox');
    element.onscroll = () => {
        this.realTimeList.forEach(e => {
            const child = document.getElementById(e.type)
            if (element.scrollTop > child.offsetTop - 50) this.activeType = e.type;
        })
    }
},
handleClick(name) {
  this.activeType = name;
  this.scroll(document.getElementById(name).offsetTop - 15)
}

左右两边是联动的,滑动左边,会高亮右边对应的文字。点击右边文字会滑动到对应的区域。

image.png