自定义tabs锚点

53 篇文章 14 订阅
这段代码展示了如何在Vue.js应用中处理滚动条隐藏、点击tab锚点以及监听页面滚动。通过`<template>`标签中的结构,可以看到使用了Vue的条件渲染和事件绑定来管理表单和模块切换。`scroll`函数处理锚点点击时的滚动行为,而`onScroll`方法则监听窗口滚动事件,动态更新右侧导航的选中状态。
摘要由CSDN通过智能技术生成

目录​​​​​​​

 

隐藏滚动条

点击tab锚点

监听滚动​​​​​​​

<template>
  <div class="dataConfirm-create">
    <mds-loading :isLoading="detailLoading" type="ball-pulse" loadingText="正在努力加载中" />
    <div class="left-wrap">
          <!-- 配置模块 -->
          <mds-form-item class="mds-form-item-flex" label="配置模块" prop="moduleDataType">
            <mds-checkbox-group v-model="formData.moduleDataType">
              <mds-checkbox :disabled="showDetail" :value=2>任务确认配置</mds-checkbox>
              <mds-checkbox :disabled="showDetail" :value=1>业绩确认配置</mds-checkbox>
              <mds-checkbox :disabled="showDetail" :value=3>其他数据确认配置</mds-checkbox>
            </mds-checkbox-group>
          </mds-form-item>
          <div v-show="formData.moduleDataType.includes(2)" class="module-title" id="nav2">任务确认配置</div>
          <formComp v-if="formData.moduleDataType.includes(2)" :disabled="showDetail" ref="taskContent" />
          <div v-show="formData.moduleDataType.includes(1)" class="module-title" id="nav1">业绩确认配置</div>
          <formComp v-if="formData.moduleDataType.includes(1)" :disabled="showDetail" ref="scoreContent" />
          <div v-show="formData.moduleDataType.includes(3)" class="module-title" id="nav3">其他数据确认配置</div>
          <formComp v-if="formData.moduleDataType.includes(3)" :disabled="showDetail" ref="otherContent" />
          <mds-form-item class="bottom-wrap" label-width="0">
            <mds-button v-if="!showDetail" size="small" type="primary" @click="submit">保存</mds-button>
            <mds-button size="small" @click="cancel">取消</mds-button>
          </mds-form-item>
        </mds-form>
      </div>
    </div>
    <div class="right-wrap">
      <a :class="{ 'is-active': active == 'nav0' }" @click="scroll('nav0', $event)">基本信息</a>
      <a v-show="formData.moduleDataType.includes(2)" :class="{ 'is-active': active === 'nav2' }"
        @click="scroll('nav2', $event)">任务确认配置</a>
      <a v-show="formData.moduleDataType.includes(1)" :class="{ 'is-active': active === 'nav1' }"
        @click="scroll('nav1', $event)">业绩确认配置</a>
      <a v-show="formData.moduleDataType.includes(3)" :class="{ 'is-active': active === 'nav3' }"
        @click="scroll('nav3', $event)">其他数据确认配置</a>
    </div>
  </div>
</template>

  active:string = 'nav0'
  moduleNames: { name: string; val: string }[] =[
  { name: '基本信息', val: 'nav0' },
  { name: '任务确认配置', val: 'nav2' },
  { name: '业绩确认配置', val: 'nav1' },
  { name: '其他数据确认配置', val: 'nav3' }
]

.right-wrap {
    height: 100%;
    width: 200px;
    padding-top: 40px;
    padding-right: 40px;
    margin-left: auto;

    a {
      line-height: 40px;
      color: #5A5F68;
      display: block;
      padding: 0 22px;

      &:hover {
        color: #1f6dea;
      }

      &.is-active {
        box-shadow: inset 2px 0px #0364ff;
        color: #1f6dea;
      }
    }
  }

隐藏滚动条

.workbench-create {
  height: 100%;
  display: flex;

  .left-wrap {
    height: 100%;
    overflow: auto;
    flex: 1;
    padding-left: 40px;
    //隐藏元素的滚动条。这通常用于自定义滚动条样式。
    scrollbar-width: none;
    /* Firefox */
    -ms-overflow-style: none;

    /* IE 10+ */
    &::-webkit-scrollbar {
    //伪元素选择器,用于选择Webkit浏览器(如Chrome、Safari等)中的滚动条。
      display: none;
      /* Chrome Safari */
    }

  .right-wrap {
    height: 100%;
    width: 200px;
    padding-top: 40px;
    padding-right: 40px;
    margin-left: auto;
  }
}

点击tab锚点

// 锚点
  scroll(domId: string, e: any) {
    this.isClickScrolling = true;

    //延迟设置isClickScrolling,防止与监听滚动冲突
    clearTimeout(this.clickScrollTimer);
    this.clickScrollTimer = setTimeout(() => {
      this.isClickScrolling = false;
    }, 102);

    // 获取名为 '.right-wrap' 的元素,并将其子元素赋值给变量 'links'
    let links: any = document.querySelector('.right-wrap')?.childNodes;

    // 遍历 'links' 中的每个元素
    links.forEach((element: any) => {
      // 如果当前元素拥有类名属性(classList),则移除 'is-active' 类名
      element.classList && (element.classList.remove('is-active'));
    });

    // 给被点击的元素(事件目标 e.target)添加 'is-active' 类名
    e.target.classList.add('is-active');

    // 根据传入的 'domId' 获取对应的 DOM 元素
    const dom = document.querySelector(`#${domId}`);

    // 如果找到了该元素,则平滑滚动到该元素所在的视图区域
    if (dom) {
      dom.scrollIntoView({ behavior: 'smooth' });
    }
  }

auto: 默认值。滚动行为没有特殊效果,类似于传统的滚动方式,会立即滚动到目标位置。
soomth:在大多数浏览器适用
instant: 滚动到目标位置,但没有平滑效果,瞬间到达。

监听滚动

 mounted() {
    window.addEventListener('scroll', this.onScroll, true)
  }

  destroy() {
    // 移除滚动事件的监听器,防止内存泄漏
    window.removeEventListener('scroll', this.onScroll)
    clearTimeout(this.scrollTimer);
    clearTimeout(this.clickScrollTimer);
  }
  onScroll() {
    //是点击滚动则不用操作 
    if (this.isClickScrolling) return;
    // 清除之前的定时器
    clearTimeout(this.scrollTimer);
    //基本上停止滚动后才设置tabs
    this.scrollTimer = setTimeout(() => {
      const navContents = document.querySelectorAll('.module-title')
      const offsetTopArr: any = []
      // 存储各个元素相对于顶部的偏移量
      navContents.forEach((item: any) => {
        //60px>标头48px 留出一定的空间
        offsetTopArr.push(item.offsetTop - 60)
      })
      //获取 '.left-wrap' 元素的滚动距离
      const scrollTop = document.querySelector('.left-wrap')?.scrollTop

      let navIndex = 0
      for (let n = 0; n < offsetTopArr.length; n++) {
        if (scrollTop && scrollTop >= offsetTopArr[n]) {
          navIndex = n
        }
      }
      this.active = "nav" + navIndex

      let links: any = document.querySelector('.right-wrap')?.childNodes;

      // 遍历 'links' 中的每个元素
      for (let n = 0; n < links.length; n++) {
        // 如果当前元素拥有类名属性(classList),则移除 'is-active' 类名
        if (links[n].classList && n != navIndex) {
          links[n].classList.remove('is-active');
        }
      };

      if (navIndex == 2) navIndex = 1;
      else if (navIndex == 1) navIndex = 2;
      // console.log("nav" + navIndex);

      this.active = "nav" + navIndex
    }, 100);
// 时间要比isClickScrolling为true的时间短一点
  }
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值