美文网首页
vue实现吸顶、锚点和滚动高亮按钮效果

vue实现吸顶、锚点和滚动高亮按钮效果

作者: zZ_d205 | 来源:发表于2022-04-11 10:12 被阅读0次

html代码

  <div id="stationCon" ref="stationCon" @scroll="handleScroll"></div>

js关键代码

 data() {
    return {
      isFixed: false,
      active: 0,
      bg11,
      scrollTop: 0,
      navgatorIndex: 0,
      listBoxState: true// 点击导航栏时,暂时停止监听页面滚动
    }
  },
  mounted() {
  //  顶部是否显示
    this.handleFixed()
    let timeId = '';
    document.getElementById('stationCon').addEventListener('scroll', () => {
      // 页面滚动停止100毫秒后才会执行下面的函数。
      clearTimeout(timeId);
      timeId = setTimeout(() => {
        this.handleScroll()
      }, 100);
    }, true);
  },
  destroyed() {
    let timeId = '';
    // 离开该页面需要移除这个监听的事件
    document.getElementById('stationCon').removeEventListener('scroll', () => {
      // 页面滚动停止100毫秒后才会执行下面的函数。
      clearTimeout(timeId);
      timeId = setTimeout(() => {
        this.handleScroll()
      }, 100);
    }, true);
  },
  methods: {
    handleTab(index) {
      this.active = index
    },
    jump(index) {
      this.navgatorIndex = index;
      const jump = document.getElementsByClassName('navBox');
      jump[index].scrollIntoView({
        behavior: 'smooth' // 平滑过渡
        // block: 'center'
        // block:    "start"  // 上边框与视窗顶部平齐。默认值
      })
      this.listBoxState = false;
      let timeId = '';
      clearTimeout(timeId);
      timeId = setTimeout(() => {
        this.listBoxState = true;
      }, 2000);
    },
    /** 滚动事件 */
    handleScroll(e) {
      this.handleJump()
      // 导航栏吸顶
      this.handleFixed()
    },
    // 跳转
    handleJump() {
      // 获取页面滚动条的高度
      const scrollTop = this.$refs.stationCon.scrollTop;
      this.scrollTop = scrollTop
      const jumps = document.getElementsByClassName('navBox');
      console.log(this.listBoxState);
      if (this.listBoxState) { // 作用是点击导航栏时,延迟这里执行。
        for (let i = 0;i < jumps.length;i++) {
          // 获取监听元素距离视窗顶部距离
          const offsetTop = jumps[i].offsetTop;
          // 获取监听元素本身高度
          var scrollHeight = jumps[i].scrollHeight;
          // 如果 dom滚动位置 >= 元素距离视窗距离 && dom滚动位置 <= 元素距离视窗距离+元素本身高度
          // 则表示页面已经滚动到可视区了。
          if (scrollTop >= offsetTop - 72 && scrollTop <= (offsetTop + scrollHeight)) {
            // 导航栏背景色选中
            this.navgatorIndex = i;
          }
        }
      }
    },
    // 吸顶
    handleFixed() {
      // 获取页面滚动条的高度
      const scrollTop = this.$refs.stationCon.scrollTop;
      const header = document.getElementById('header');
      const headerBox = document.getElementById('headerBox');
      const router_contenter = document.querySelector('.router_contenter');
      const offsetTop = this.getOffsetTop(this.$refs.wrapperTab) - headerBox.clientHeight;
      if (scrollTop > offsetTop || scrollTop === offsetTop) {
        header.style.display = 'none'
        headerBox.style.display = 'none'
        router_contenter.style.height = '100%'
      } else {
        header.style.display = 'block'
        headerBox.style.display = 'block'
        router_contenter.style.height = 'calc(100% - 60px)'
      }
      this.isFixed = scrollTop > offsetTop || scrollTop === offsetTop;
    },
    // 获取当前元素的offsetTop
    getOffsetTop(obj) {
      let offsetTop = 0;
      while (obj !== window.document.body && obj != null) {
        offsetTop += obj.offsetTop;
        obj = obj.offsetParent;
      }
      return offsetTop;
    }
  }

参考网址:https://www.cnblogs.com/ljy-/articles/12857280.html

![image.png](https://img.haomeiwen.com/i20331012/c3f7e49d4cdccafc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


<template>
  <div>
    <div class="div">
      <ul class="navgator">
        <li class="navgatorLi" :class="{'isActive': index===navgatorIndex}" @click="handleLeft(index)" v-for="(item,index) in navgator" :key="item">{{item}}</li>
      </ul>
      <ul class="rightList">
        <li :id="'id'+index" v-for="(item,index) in listBox" :key="item">{{item}}</li>
      </ul>
    </div>
  </div>
</template>

<script> export default {
  data() { return {
      navgator: [ '列表A', '列表B', '列表C', '列表D',
      ],
      navgatorIndex: 0,
      listBox: [ 'A','B','C','D' ],
      listBoxState: true,//点击导航栏时,暂时停止监听页面滚动
 };
  },
  created() {

  },
  mounted() {
    let timeId;
    window.addEventListener('scroll', () => { // 页面滚动停止100毫秒后才会执行下面的函数。
 clearTimeout(timeId);
      timeId = setTimeout(() => { this.scrollToTop();
        console.log('执行完了哦');
      }, 100);
    } , true);
  },
  methods: { // 点击导航菜单,页面滚动到指定位置
 handleLeft(index) { this.navgatorIndex = index; this.$el.querySelector(`#id${index}`).scrollIntoView({
        behavior: "smooth",  // 平滑过渡
        block:    "start"  // 上边框与视窗顶部平齐。默认值
 }); this.listBoxState=false;

      let timeId;
      clearTimeout(timeId);
      timeId = setTimeout(() => { this.listBoxState=true;
      },200);
    }, // 监听页面元素滚动,改变导航栏选中
 scrollToTop() { // 获取视窗高度
      var domHight = document.body.offsetHeight; // dom滚动位置
      var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; if (this.listBoxState) {//作用是点击导航栏时,延迟这里执行。
        this.listBox.map((v,i) => { // 获取监听元素距离视窗顶部距离
          var offsetTop = document.getElementById(`id${i}`).offsetTop; // 获取监听元素本身高度
          var scrollHeight = document.getElementById(`id${i}`).scrollHeight; // 如果 dom滚动位置 >= 元素距离视窗距离 && dom滚动位置 <= 元素距离视窗距离+元素本身高度 // 则表示页面已经滚动到可视区了。
          if (scrollTop >= offsetTop && scrollTop<=(offsetTop+scrollHeight)) { // 导航栏背景色选中
            this.navgatorIndex = i;
          }
        })
      }
    },
  },
} </script>

<style lang='less' scoped> .div {
    width: 100%;
    background: #ededed;
  }
  .navgator {
    width: 200px;
    position: fixed;
    top: 0;
    .navgatorLi {
      width: 100%;
      height: 1rem;
      display: flex;
      justify-content: center;
      align-items: center;
      border: 1px solid #ccc;
      border-top: none;
    }
    .isActive {
      color: #fff;
      background: darkseagreen;
    }
  }
  .rightList {
    width: 560px;
    margin-left : 200px;
    li {
      width: 100%;
      height: 10rem;
      display: flex;
      justify-content: center;
      align-items: center;
      border: 1px solid #ccc;
    }
  } </style>

相关文章

网友评论

      本文标题:vue实现吸顶、锚点和滚动高亮按钮效果

      本文链接:https://www.haomeiwen.com/subject/wuwclrtx.html