侧边导航栏随窗口滚动切换选中,点击对应内容元素滚动到浏览器窗口的可视区域内

<template>
  <div class="sideBar">
    <div class="side_wrap">
      <div
        class="side_item"
        @click="handleClick(item, index)"
        v-for="(item, index) in sideList"
        :class="{ active: item.active }"
        :key="index"
      >
        {{ item.text }}
      </div>
    </div>
    <div class="side_content">
      <div
        class="content_item"
        :id="`content${index}`"
        v-for="(item, index) in contentList"
        :key="index"
        :style="{ background: item.color }"
      >
        {{ item.text }}
      </div>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      sideList: [
        {
          text: "side1"
        },
        {
          text: "side2"
        },
        {
          text: "side3"
        },
        {
          text: "side4"
        },
        {
          text: "side5"
        },
        {
          text: "side6"
        }
      ],
      contentList: [
        {
          text: "content1",
          color: "red"
        },
        {
          text: "content2",
          color: "yellow"
        },
        {
          text: "content3",
          color: "pink"
        },
        {
          text: "content4",
          color: "skyblue"
        },
        {
          text: "content5",
          color: "greenyellow"
        },
        {
          text: "content6",
          color: "blanchedalmond"
        }
      ],
      clicked: false
    };
  },
  methods: {
    //   侧边栏点击
    handleClick(item, index) {
      this.clicked = true;
      this.resetSide();
      this.$set(this.sideList[index], "active", true);

      var element = document.getElementById(`content${index}`);
      // 让id为content${index}的元素滚动到浏览器窗口的可视区域内
      element.scrollIntoView();
    },
    // 重置侧边栏选中
    resetSide() {
      this.sideList.forEach((side, ind) => {
        this.$set(this.sideList[ind], "active", false);
      });
    },
    handleScroll() {
      let scrollTop =
        document.body.offsetTop || document.documentElement.scrollTop; // 获取滚动条位置
      if (this.clicked) {
        this.clicked = false;
        return;
      }
      for (let i = 0; i < this.list.length; i++) {
        //未达到标题最低高度时
        // if (scrollTop < this.list[0].offsetTop) {
        //   break;
        // }
        //在标题区间中
        //最后一个标题
        if (i == this.list.length - 1) {
          this.resetSide();
          this.$set(this.sideList[i], "active", true);
          break;
        } else if (
          scrollTop >= this.list[i].offsetTop &&
          scrollTop < this.list[i + 1].offsetTop
        ) {
          this.resetSide();
          this.$set(this.sideList[i], "active", true);
          break;
        }
      }
    }
  },
  mounted() {
    this.resetSide();
    this.$set(this.sideList[0], "active", true);
    // 获取每个大div的offsetTop
    this.list = [];
    this.contentList.forEach((item, ind) => {
      let obj = {
        offsetTop: document.querySelector(`#content${ind}`).offsetTop
      };
      this.list.push(obj);
    });
    // 监听滚动事件
    window.addEventListener("scroll", this.handleScroll);
  }
};
</script>

<style scoped>
.side_wrap {
  width: 100px;
  position: fixed;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  cursor: pointer;
}
.side_item {
  height: 30px;
}
.content_item {
  height: 100vh;
  width: 100vh;
}
.active {
  background: pink;
}
</style>

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值