最终效果如下:(注意需要做锚点联动的部分并不在页面的顶部而是页面的某个div内)-chrome

完成这个功能需要注意:

1、点击导航平滑滚动到导航内容处

2、div内滚动时当前导航需要做响应

代码如下:

1、html结构(因为从项目里截取代码,allMenuList数据内容就不贴出来了,不算难点,这个可以根据自己的项目进行调整,相应的方法和类名别弄错就行)

<div class="all-title">
        全部应用
        <p class="fr">
          <span v-for="(item, index) in allMenuList" :key="item.id" :class="[index===activeMenu?'active':'']" @click="jump(index)">{{ item.name }}</span>
        </p>
      </div>
      <div id="scrollBox" class="applications-content">
        <div v-for="(val, index) in allMenuList" :key="val.id" class="all-list do-jump">
          <p class="applications-title">{{ val.name }}</p>
          <ul class="applications-list">
            <li v-for="item in val.children" :key="item.id" class="applications-item" @click="changeRouterForRight(item.pathName,item.menuCode)">
              <img src="">
              <span>{{ item.name }}</span>
              <template v-if="showEdit">
                <i v-if="addOrRemove(item.menuCode)==0" class="el-icon-circle-plus add-btn" @click="addMenu(item.menuCode)" />
                <i v-if="addOrRemove(item.menuCode)==1" class="el-icon-remove remove-btn" @click="removeMenu(item.menuCode)" />
              </template>
            </li>
          </ul>
        </div>
      </div>

需要说明的数据:activeMenu-当前导航序号,scrollBox-需要在里面滚动的元素即设为overflow-y:scroll的父元素div

2、点击导航平滑滚动的方法:jump(index)

// 跳转
    jump(index) {
      this.activeMenu = index // 当前导航
      const jump = jQuery('.do-jump').eq(index)
      const scrollTop = jump.position().top + this.scrollBox.scrollTop // 获取需要滚动的距离
      // Chrome
      this.scrollBox.scrollTo({
        top: scrollTop,
        behavior: 'smooth' // 平滑滚动
      })
    }

这里有两点需要说明:一是因为我vue项目里装了jquery所以这里直接用了jquery的position().top来获取元素到父元素的距离,如果项目里没装jquery需要把这里换成js的方法来获取元素到父元素的距离(万事有Google和度娘),二是点击之后需要滚动的距离计算时别忘了加上当前div已经滚动的距离即已经被卷起的高度

-----到这里我们就可以实现1的功能

3、监听scrollBox的滚动:

写在mounted里

// 获取滚动dom元素
    this.scrollBox = document.getElementById('scrollBox')
    const jump = jQuery('.do-jump')
    const topArr = []
    for (let i = 0; i < jump.length; i++) {
      topArr.push(jump.eq(i).position().top)
    }
    // 监听dom元素的scroll事件
    this.scrollBox.addEventListener('scroll', () => {
      const current_offset_top = that.scrollBox.scrollTop
      for (let i = 0; i < topArr.length; i++) {
        if (current_offset_top <= topArr[i]) { // 根据滚动距离判断应该滚动到第几个导航的位置
          that.activeMenu = i
          break
        }
      }
    }, true)

这里需要注意addEventListener里有三个参数:'scroll' 、function、true

Logo

前往低代码交流专区

更多推荐