js+css 锚点菜单

<template>
  <div class="nav">
    <div class="navBox">
      <div
        v-for="(item, index) in navList"
        :key="index"
        class="nav-item"
        @click="clickNav(item, index)"
        :class="{ active: currentIndex === index }"
      >
        {{ item.label }}
      </div>
    </div>
    <div class="nav-content">
      <div class="nav-content-item" id="content-0">我是内容1</div>
      <div class="nav-content-item" id="content-1">我是内容2</div>
      <div class="nav-content-item" id="content-2">我是内容3</div>
      <div class="nav-content-item" id="content-3">我是内容4</div>
      <div class="nav-content-item" id="content-4">我是内容5</div>
    </div>
  </div>
</template>

<script>
export default {
  name: "",
  components: {},
  mixins: [],
  props: {},
  computed: {},
  watch: {},
  data() {
    return {
      // 初始化菜单
      navList: [
        {
          label: "菜单1",
        },
        {
          label: "菜单2",
        },
        {
          label: "菜单3",
        },
        {
          label: "菜单4",
        },
        {
          label: "菜单5",
        },
      ],
      currentIndex: 0,
    };
  },
  created() {},
  mounted() {
    // 绑定滚动事件
    document
      .getElementsByClassName("nav-content")[0]
      .addEventListener("scroll", this.getScroll);
  },
  methods: {
    clickNav(item, index) {
      document
        .querySelector(`#content-${index}`)
        .scrollIntoView({ behavior: "smooth" });
    },
    getScroll() {
      const ele = document.querySelector(".nav-content");
      const isbottom = ele.scrollTop + ele.clientHeight - ele.scrollHeight;
      this.onScroll(ele.scrollTop, isbottom);
    },
    // 监听滚动 高亮当前菜单
    // 避免重复设置currentIndex触发高亮状态导致不断跳转
    // 在点击的时候不高亮 高亮效果通过滚动事件去反显
    onScroll(currentScrollTop, isbottom) {
      const items = document.querySelectorAll(".nav-content-item");
      const offSetTopArr = [];
      this.$nextTick(() => {
        items.forEach((item) => {
          offSetTopArr.push(item.offsetTop);
        });
        offSetTopArr.push(currentScrollTop);
        offSetTopArr.sort((a, b) => a - b);
        const index = offSetTopArr.indexOf(currentScrollTop);

        // 如果触底 则高亮最后一个菜单
        if (isbottom >= 0) {
          this.currentIndex = this.navList.length - 1;
        } else {
          // 否则通过index高亮菜单
          this.currentIndex = index;
        }
      });
    },
  },
};
</script>
<style lang="less" scoped>
/* stylelint-disable */
.nav {
  position: relative;
  .navBox {
    position: absolute;
    right: 100px;
    top: 20px;
    border-radius: 4px;
    .nav-item {
      height: 32px;
      line-height: 32px;
      cursor: pointer;
    }
    .active {
      color: pink;
    }
  }
  .nav-content {
    width: 1280px;
    margin: auto;
    height: 100%;
    overflow: auto;
    .nav-content-item {
      min-height: 300px;
    }
  }
}
</style>

你可能感兴趣的:(javascript,css,开发语言)