vue菜单与内容区域形成类似楼层导航效果思路-菜单随着窗口滚动自动高亮-适用于菜单下含有这个页面的子项

1.给页面添加滚动监听

window.addEventListener("scroll", this.handleScroll);
//this.handleScroll 滚动时会触发的方法

2.创建handleScroll方法

3.在页面最下方添加一个div,用于判断页面是否到了底部

<div
   class="seefooter"
   ref="seefooter"
   style="height: 10px; background-color: transparent"
></div>

4.监测这个div的位置

handleScroll() {
    const seefooter = this.$refs.seefooter;
    if (seefooter.getBoundingClientRect().bottom < window.innerHeight) {
       console.log("触底");
       return;//阻止后面的事件继续执行,不然会有问题
    }
},
//监测条件如果不适合可以自行调整

5.获取需要监测的元素,可根据实际情况调整,这里的是根据数据循环出来的,循环数据从而选中每个元素-记得给这些元素加上相应的ref

 <!-- 类似这样的  -->
 <div v-for="item in listData" :key="item.id" :ref="`content-box${item.id}`">{{ item.name }}</div>

数据长这样:

listData: [
   {
      id: "1",
      name: "菜单1",
   },
   {
      id: "2",
      name: "菜单2",
  },
],

获取元素

this.listData.forEach((item) => {
    const content = this.$refs[`content-box${item.id}`];//循环获取
});

6.获取到之后就需要监测每个元素了

this.listData.forEach((item) => {
  const content = this.$refs[`content-box${item.id}`]; //循环获取
  if (content) {
     const rect = content[0].getBoundingClientRect();
     if (rect.top <= 100 && rect.top >= -10) { //判断是否在可视范围内,这个可视范围可以自行调整
        console.log("到" + item.id + "高亮了");
        // 可以在这去改变菜单的高亮
     }
  }
});

7.监测到满足条件的元素根据关联关系去修改菜单的高亮。

方法大致的代码大概就长这个样子了:

  handleScroll() {
     const seefooter = this.$refs.seefooter;
     if (seefooter.getBoundingClientRect().bottom < window.innerHeight) {
         console.log("触底");
         return; //阻止后面的事件继续执行,不然会有问题
      }
      this.listData.forEach((item) => {
         const content = this.$refs[`content-box${item.id}`]; //循环获取
         if (content) {
            const rect = content[0].getBoundingClientRect();
            if (rect.top <= 100 && rect.top >= -10) {
                //判断是否在可视范围内,这个可视范围可以自行调整
                console.log("到" + item.id + "高亮了");
                // 可以在这去改变菜单的高亮
            }
          }
     });
,

8.准备点击菜单滑动到指定元素那里(还有点问题,如果不满足还需另行寻找方法)

9.切记点击之后在执行滚动方法之前一定要取消页面的滚动监听,结束之后再加上,或者执行其他操作时加上,不取消掉会有冲突

代码如下

toScroll(newval) {
      new Promise((resolve) => {
        setTimeout(() => {
          this.$nextTick(() => {
            try {
              // 移除window滚动事件
              window.removeEventListener("scroll", this.handleScroll);
              // 首次进入会获取不到元素
              this.$refs[`content-box${newval}`][0].scrollIntoView({
                behavior: "smooth",
                block: "center",
              });
              this.scrollId = "";
            } catch (error) {
              this.scrollId = newval;
            }
          });
          resolve();
        }, 100);
      }).then(() => {
        setTimeout(() => {
          window.addEventListener("scroll", this.handleScroll);
        }, 500);
     });
},

以上只是一种思路,还有bug,但是能力有限只能想到这了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值