likes
comments
collection
share

用vue实现动态锚点定位,页面滚动和点击菜单联动效果

作者站长头像
站长
· 阅读数 10

一、背景:

最近用 vue 做 H5 页面业务时有一个业务场景: 页面是很长很长的滚动页面,顶部有菜单按钮而且菜单按钮是动态获取的(效果大概如下图所示),接口动态获取有多少个我也不知道; 而且点击顶部菜单会滚动到对应点击菜单的地方,滚动到对应的地方顶部菜单也会自动显示当面区域的菜单为选中效果,互相联动。

用vue实现动态锚点定位,页面滚动和点击菜单联动效果

选择的实现思路:

把接口获取到的顶部菜单用 for 动态显示出来,滚动页面的内容区域也是 for 动态渲染,然后通过 监听滚动事件时刻知道当前位置 ,实现指定菜单与指定内容区域进行联动。

二、实现代码

(1)顶端菜单部分逻辑:

tab标签部分用for展示出来,然后当前显示的内容对应的顶端tab显示选中效果, 点击某个tab触发goAnchor事件直接滚动到对应的内容区域。

<div class="step-ul">
      <div 
        class="ul-li" 
        v-for="(item, index) in tabList" 
        :key="index"
        :class="{ 'isNew' ? activeBtn == index }"       // 当前选中的样式
        @click="goAnchor('anchor-'+index, index)"   // 点击菜单滚动到对应的地方
      >
        <div> {{ item }} </div>
      </div>
  </div>
goAnchor( selector, index) {
 // 点击后更新当前点击事件下标,显示选中样式
  this.isNew = index   
  
  // 页面内容滚动到对应锚点位置
  this.$refs[selector][0].scrollIntoView({ behavior: ' smooth' })
},

核心部分解释

:class="{ 'isNew' ? active == index }" : 当前选中的样式

@click="goAnchor('anchor-')+index, index" : 点击菜单滚动到对应的地方

(2)滚动正文区域部分逻辑:

标签部分for展示内容,并且每部分添加ref,用于和顶部tab一一对应实现联动

 <div ref="anchorRef" @scroll="handleScroll">
      <div 
           class="anchor-item" 
           v-for="(item, index) in mainList" 
           :key="index" 
           :ref="'anchor-'+index"
     >
        这里写是对应每个tab菜单的内容
      </div>
  </div>

只要发生滚动就时刻获取所有锚点信息,并通过scrollTop判断那个区域当前在屏幕显示,然后对应的顶部tab进行显示选中效果

// 滚动监听器
handleScroll(){   
  // 获取所有锚点信息
  const navContents = document.querySelectorAll( '.anchor-item')

  // 所有锚点元素的offsetTop
  const offsetTopArr =[]
  navContents.forEach( (item) => {
    offsetTopArr.push( item.offsetTop)
  })

  //获取当前文档流的scrollTop 
  const scrollTop = this.$refs.anchorRef.scrollTop
  offsetTopArr.forEach((item, index) => {
      //  当前显示内容对应顶部tab进行显示选中效果
    if (scrollTop >= item - 100) {
      this.isNew = index    
    }
  })
}

三、小结:

以上完成了锚点的动态联动效果,只写了实现逻辑没有写样式,毕竟样式不能通用的。

优化: 上述handleScroll滚动事件可以自行添加节流效果,这样触发事件减少性能会好很多,这里给个思路就不细说了