vue点击div按钮滚动跳转定位到对应的元素模块(自定义滚动动画)

这里写自定义目录标题

html部分

  <!-- 按钮(根据数据循环) -->
<div class="nav">
  <div v-for="(item, index) in data" :key="item[0] + 1" :index="index" :class="{ chosen: index == 0 }">
    {{ item[0] }}
  </div>
</div>

<div id="content">
 <!-- 你的具体模块(根据数据循环) -->
  <section v-for="item in data" :key="item[0]">
     <!-- 模块的内容。。。 -->
  </section>
</div>


js处理部分

// 滚动事件
let content = document.getElementById('content')
let aSec = content.querySelectorAll('section')
let oNav = document.querySelector('.nav')
let aBtn = document.querySelectorAll('.nav>div')
let scrollTime = null //定时器
//点击按钮,事件委托绑定滚动事件
//我的项目中这块的数据需要实时更新,所以每次取到数据需要重新循环渲染界面,为避免重复绑定,不使用addeventlistener
oNav.onclick = e => {
//此处判断点击不为父元素和点击当前位置按钮不滚动
  if (e.target != oNav && Array.prototype.indexOf.call(e.target.classList, 'chosen') == -1) {
    Array.prototype.forEach.call(aBtn, item => {
      item.classList.remove('chosen')
    })
    e.target.classList.add('chosen')
    //点击按钮,对应到相同顺序的模块上
    this.scrollMove(content, aSec[e.target.getAttribute('index')].offsetTop, 200)
  }
}
//js滚动动画
scrollMove(obj, topValue, time) {//滚动对象,要滚到的top值,动画时间
  let speed = Math.round((topValue - obj.scrollTop) / Math.round(time / 10))
  clearInterval(scrollTime)
  scrollTime = null
  scrollTime = setInterval(() => {
    if (
      Math.abs(obj.scrollTop - topValue) >= Math.abs(speed) &&
      obj.scrollTop + speed < obj.scrollHeight - obj.clientHeight
    ) {
      obj.scrollTo(0, obj.scrollTop + speed)
    } else {
      obj.scrollTo(0, topValue)
      clearInterval(scrollTime)
      scrollTime = null
    }
  }, 10)
}
//同时,监听滚动事件,在滚到相应的位置时,切换按钮样式
content.onscroll = () => {
  if (!scrollTime) {
    Array.prototype.forEach.call(aSec, (item, index) => {
      if (content.scrollTop + content.clientHeight == content.scrollHeight) {
        Array.prototype.forEach.call(aBtn, item2 => {
          item2.classList.remove('chosen')
        })
        aBtn[aSec.length - 1].classList.add('chosen')
      } else {
        if (index != aSec.length - 1) {
          if (
            content.scrollTop + 100 >= aSec[index].offsetTop &&
            content.scrollTop + 100 < aSec[index + 1].offsetTop
          ) {
            Array.prototype.forEach.call(aBtn, item2 => {
              item2.classList.remove('chosen')
            })
            aBtn[index].classList.add('chosen')
          }
        } else {
          if (content.scrollTop + 100 >= aSec[index].offsetTop) {
            Array.prototype.forEach.call(aBtn, item2 => {
              item2.classList.remove('chosen')
            })
            aBtn[index].classList.add('chosen')
          }
        }
      }
    })
  }
}

上一篇:很少用的前端基础知识---id直接在js中使用


下一篇:原生JS实现多重选项卡切换轮播图制作