vue3中使用锚点


 


html代码
      <
div class="cashierWrap"> <div class="projectNameNew"> <el-input class="projectNameSearch" v-model="keyword" placeholder="搜索项目名称/价格" maxlength="10" :prefix-icon="Search" clearable @input="searchPro" /> <div class="projectNameList"> <div class="projectNameListLeft"> <div :class="['projectNameListLeftTit', 'ellipsis', active == k ? 'activeTit' : '']" v-for="(v, k) in priceListData" :key="k" @click="HandlerItemGroupName(v, k)"><span v-if="active == k" class="spanLine"></span> {{ v.itemGroupName }}</div> </div> <div class="projectNameListRight" id="scrollContainer"> <div class="itemInfoList" :id="`itemInfoList${i}`" v-for="(v, i) in priceListData" :key="i"> <p class="itemName"> {{ v.itemGroupName }} </p> <div class="itemInfoWrap" v-if="v.shopItemList.length"> <div class="itemInfo" v-for="(v1, i1) in v.shopItemList" :key="i" @click="chooseProject(i, i1)"> <div class="proImg"> <img :src="v1.itemUrl" /> <img v-if="v1.choose" class="select" :src="proChoose" /> </div> <div class="proText"> <p class="ellipsis">{{ v1.shopItemName }}</p> <p class="mt0">¥{{ v1.shopItemPrice }}</p> </div> </div> </div> <div v-else class="itemInfoEmpty"> <div class="proImg"> <img class="select" :src="zanwu" /> </div> <div class="proText">暂无-</div> </div> </div> </div> </div> </div>

setup代码:
 const
chooseProjectArr = reactive({
    active:1
 })
  const isScroll = ref(true); // 点击导航栏时,暂时停止监听页面滚动
  //导航锚点
    const HandlerItemGroupName = (item: any, index: any) => {
      chooseProjectArr.active = index;

      let anchor: any = document.querySelector(`#itemInfoList${index}`);
      let scrollBox: any = document.getElementById("scrollContainer");
      nextTick(() => {
        scrollBox.scrollTo({
          top: anchor.offsetTop - 11,
          behavior: "smooth",
        });
      });

      isScroll.value = false;
      let timeId:any = "";
      clearTimeout(timeId);
      timeId = setTimeout(() => {
        isScroll.value = true;
      }, 2000);
    };
   // 滚动监听器
    const onScroll = () => {
      if (!isScroll.value) return;
      // 获取所有锚点元素
      const navContents = document.querySelectorAll(".projectNameListRight .itemInfoList");
      // 所有锚点元素的 offsetTop
      const offsetTopArr: any = [];
      navContents.forEach((item:any) => {
        offsetTopArr.push(item.offsetTop - 11);
      });
      // 获取当前文档流的 scrollTop
      const scrollTop = document.getElementById("scrollContainer").scrollTop;
      // 定义当前点亮的导航下标
      let navIndex = 0;
      for (let n = 0; n <= offsetTopArr.length; n++) {
        // 如果 scrollTop 大于等于第 n 个元素的 offsetTop 则说明 n-1 的内容已经完全不可见
        // 那么此时导航索引就应该是 n 了
        if (scrollTop >= offsetTopArr[n - 1]) {
          navIndex = n - 1;
        }
      }
      // 把下标赋值给 vue 的 data
      chooseProjectArr.active = navIndex;
    };

 // 组件加载后监听指定div的滚动事件(scrollContainer)
    onMounted(() => {
     nextTick(() => {
          document.getElementById("scrollContainer").addEventListener("scroll", onScroll);
        });
    });
   //卸载监听
     onBeforeUnmount(() => {
        document.getElementById("scrollContainer").removeEventListener("scroll", onScroll);
      });
 

 

posted @ 2024-06-19 09:42  小菜波  阅读(3)  评论(0编辑  收藏  举报