美文网首页
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