Vue2——监听页面滚动实现菜单和页面对应

发布时间 2023-09-12 10:47:07作者: 。思索

前言

如题,监听页面的滚动并激活相应的菜单,一个老项目的维护,后面反正要全部重构,这里就先实现功能就好了;

内容

元素内容

主要是添加相应的id,生成目录后直接通过锚点来跳转

监听滚动

 window.addEventListener('scroll', () => {
      const sections = document.getElementsByClassName('card-item')
      for (let i = 0; i < sections.length; i++) {
        const top = sections[i].getBoundingClientRect().top
        if (top < 100 && top > 0) this.activeIndex = i
        if (i === 4 && top < 0) this.activeIndex = 6
      }
    }, true)

DEMO示例

<template>
  <div>
    <el-row :gutter="24">
      <el-col
        :span="4"
        style="position: sticky;top: 10px;"
      >
        <el-card
          class="card-item-menu"
          shadow="hover"
        >
          <div class="menu">项目计划</div>
          <ul>
            <li
              v-for="(item, index) in menu"
              :key="item.href"
              class="sub-item"
            >
              <el-link
                :class="{active: index == activeIndex}"
                :href="item.href"
                :underline="false"
              >{{ item.title }}</el-link>
            </li>
          </ul>
        </el-card>
      </el-col>
      <el-col :span="20">
        <el-form
          ref="form"
          :model="form"
          :rules="rules"
          label-width="80px"
        >
          <!-- 营销目标和场景 -->
          <el-card
            id="p1"
            class="card-item"
            shadow="hover"
            header="营销目标与场景"
          >
          </el-card>

          <!-- 投放内容与目标 -->
          <el-card
            id="p2"
            class="card-item"
            shadow="hover"
            header="投放内容与目标"
          >
          </el-card>

          <!-- 投放版位 -->
          <el-card
            id="p3"
            class="card-item"
            shadow="hover"
            header="投放版位"
          >
          </el-card>

          <!-- 投放定向 -->
          <AudienceTarget
            id="p4"
            :form-data="formData"
            @data="handleFormData"
          />

          <!-- 排期与预算 -->
          <el-card
            id="p5"
            class="card-item"
            shadow="hover"
            header="排期与预算"
          >
          </el-card>

          <!-- 搜索快投 -->
          <el-card
            id="p6"
            class="card-item"
            shadow="hover"
            header="搜索快投"
          >
          </el-card>

          <!-- 项目名称 -->
          <el-card
            id="p7"
            class="card-item"
            shadow="hover"
            header="项目名称"
          >
          </el-card>
          <el-form-item>
            <el-button
              type="primary"
              @click="onSubmit"
            >立即创建</el-button>
            <el-button>取消</el-button>
          </el-form-item>
        </el-form>
      </el-col>
    </el-row>

  </div>
</template>

<script>


export default {
  data() {
    return {
      activeIndex: 0,
      menu: [
        { href: '#p1', title: '营销目标与场景' },
        { href: '#p2', title: '投放内容与目标' },
        { href: '#p3', title: '投放版位' },
        { href: '#p4', title: '用户定向' },
        { href: '#p5', title: '排期与预算' },
        { href: '#p6', title: '搜索快投' },
        { href: '#p7', title: '项目名称' }
      ],
    }
  },
  mounted() {
    window.addEventListener('scroll', () => {
      const sections = document.getElementsByClassName('card-item')
      for (let i = 0; i < sections.length; i++) {
        const top = sections[i].getBoundingClientRect().top
        if (top < 100 && top > 0) this.activeIndex = i
        if (i === 4 && top < 0) this.activeIndex = 6
      }
    }, true)
  },
  methods: {
  }
}

</script>

<style scoped>

.card-item-menu {
    margin: 15px;
    height: 800px;
    cursor: pointer;
    .menu {
        color: #2a55e5;
        font-weight: 800;
        height: 22px;
        line-height: 22px;
    }
    .active {
          color: #2a55e5;
    }
    .sub-item {
        display: flex;
        min-height: 40px;
        padding: 8px 0px;
        color: #64666b;
        padding-left: 40px;
        padding-right: 9px;
        align-items: center;
        font-size: 14px;
        cursor: pointer;
        position: relative;
    }

    .sub-item:before {
        content: "";
        width: 4px;
        height: 4px;
        display: block;
        border-radius: 4px;
        background-color: #64666b;
        position: relative;
        right: 18px;
        transition: all 0.2s;
    }
}
.card-item {
    /* width: 800px; */
    margin: 10px;
}

:deep(.el-select .el-input__inner) {
    width: 300px;
}

:deep(.el-input__inner) {
    width: 300px;
}

</style>