Vue 动态锚点

2023-10-27

这是封装的组件 判断容器的滚动

接收父组件传来的Tab参数

<template>
  <div class="tab-container">
    <div class="tab-item" v-for="(item, index) in tabList" :key="index" :class="{ active: index === active }" @click="toggleTab(index)">
      <img class="icon" :src="index === active ? item.icon_active : item.icon" alt="" />
      {{ item.name }}
    </div>
  </div>
</template>
<script>
export default {
  props: {
    tabList: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      active: 0,
      offsetLeft: 0,
      timer: null,
    };
  },
  watch: {
    // active(newVal) {
    //   this.toggleTab(newVal);
    // },
    offsetLeft: {
      handler(newVal) {
        const container = document.querySelector(".tab-container");
        container.scrollLeft = this.offsetLeft;
      },
    },
  },
  created() {},
  mounted() {
    // 监听滚动事件
    window.addEventListener("scroll", this.onScroll, false);
  },
  destroy() {
    // 必须移除监听器,不然当该vue组件被销毁了,监听器还在就会出错
    window.removeEventListener("scroll", this.onScroll);
  },
  methods: {
    // 滚动监听器
    onScroll() {
      const activeTab = document.querySelector(".tab-item.active");
      this.offsetLeft = activeTab.offsetLeft;
      const navContents = document.querySelectorAll(".row");
      const offsetTopArr = [];
      navContents.forEach((item) => {
        offsetTopArr.push(item.offsetTop);
      });
      const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
      let navIndex = 0;
      for (let n = 0; n < offsetTopArr.length; n++) {
        if (scrollTop >= offsetTopArr[n]) {
          navIndex = n;
        }
      }
      if (scrollTop + document.documentElement.clientHeight === document.documentElement.scrollHeight) {
        navIndex = offsetTopArr.length - 1;
        setTimeout(() => {
          const activeTab = document.querySelector(".tab-item.active");
          const container = document.querySelector(".tab-container");
          container.scrollLeft = activeTab.offsetLeft;
        }, 10);
      }
      this.active = navIndex;
    },
    toggleTab(index) {
      window.removeEventListener("scroll", this.onScroll);
      this.active = index;
      this.$nextTick(() => {
        const activeTab = document.querySelector(".tab-item.active");
        const container = document.querySelector(".tab-container");
        container.scrollLeft = activeTab.offsetLeft;
      });
      let jump = document.querySelectorAll(".row");
      let total = jump[index].offsetTop;
      let distance = document.documentElement.scrollTop || document.body.scrollTop;
      // 平滑滚动,时长500ms,每10ms一跳,共50跳
      let that = this;
      let step = total / 50;
      if (total > distance) {
        smoothDown();
      } else {
        let newTotal = distance - total;
        step = newTotal / 50;
        smoothUp();
      }
      function smoothDown() {
        if (distance < total) {
          distance += step;
          document.body.scrollTop = distance;
          document.documentElement.scrollTop = distance;
          setTimeout(smoothDown, 10);
        } else {
          document.body.scrollTop = total;
          document.documentElement.scrollTop = total;
          window.addEventListener("scroll", that.onScroll, false);
        }
      }
      function smoothUp() {
        if (distance > total) {
          distance -= step;
          document.body.scrollTop = distance;
          document.documentElement.scrollTop = distance;
          setTimeout(smoothUp, 10);
        } else {
          document.body.scrollTop = total;
          document.documentElement.scrollTop = total;
          window.addEventListener("scroll", that.onScroll, false);
        }
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.tab-container {
  width: 100%;
  height: 17.067vw;
  border-radius: 2.667vw 2.667vw 0 0;
  background: #fff;
  overflow-y: auto;
  display: -webkit-box;
  -webkit-overflow-scrolling: touch;
  box-shadow: 0px 2px 9px 0px RGB(129 128 128 / 50%);
  scroll-behavior: smooth;
}
.tab-container::-webkit-scrollbar {
  display: none;
}

.tab-item {
  display: flex;
  align-items: center;
  position: relative;
  padding: 0px 30px;
  text-align: center;
  color: #999;
  font-size: 3.733vw;
  letter-spacing: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  .icon {
    width: 3.733vw;
    height: 3.733vw;
    margin-right: 1.333vw;
  }
}

.tab-item.active {
  color: #0084ff;
}
</style>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vue 动态锚点 的相关文章

  • Google reCaptcha 永远加载

    我在我的网站上使用 Google 的 reCaptcha 2 0 它曾经运行良好 但自从我向公众开放我的网站并获得了更多用户后 recaptcha 不再适用于大多数用户 它加载得很好 但一旦用户单击 我不是机器人 复选框 它会永远加载并且从
  • 使用 npm 作为构建工具连接文件

    我最近发现我可以使用 npm 作为任务运行程序 而不是 gulp 或 grunt 到目前为止 一切都很棒 lint stylus jade uglify watch 等 但串联部分 我似乎无法实现 gulp 是这样的 gulp task s
  • 无法填充名为“status”的数组

    我正在尝试做一些非常简单的事情 在 Javascript 中初始化一个数组 而且它在 Google Chrome 中不起作用 这是代码 status for i 0 i lt 8 i status i false alert status
  • 如果浏览器在 asp .net 中关闭,请从浏览器中注销?

    我的要求有点复杂 用户正在使用 Web 浏览器访问数据库 而在访问数据库时 如果用户关闭活动页面而不是注销会话 该会话需要自动注销 有人可以指导我如何做这个吗 我在母版页中使用了jquery onbeforeunload 我收到消息离开页面
  • ngx-DataTable 对列进行排序无法正常工作 Angular 4

    虽然我对角度非常陌生 但我在使用 ngx DataTable 时遇到了一些困难 我使用简单的 ngx DataTable 进行简单的操作 问题出在列上 尽管我已将 attr 声明为 sortable true 但排序不起作用 这是代码 表定
  • React/Redux bundle.js 太大

    我有一个小型的 React 项目 Webpack生成的bundle js大小为6 3Mb 如何将大小减小到 github webpack config js module exports devtool inline source map
  • 光滑的旋转木马不工作

    我一直在尝试简单地实现 Slick Carousel 的工作 我已按照 Git 页面上的说明进行操作 https github com kenwheeler slick https github com kenwheeler slick 这
  • 改进 D3 序列旭日示例

    This D3示例作为我的出发点 http bl ocks org kerryrodden 7090426 http bl ocks org kerryrodden 7090426 我想更改提供图表的数据 并且我做了以下新示例 http j
  • 删除 Laravel Mix 中的临时文件

    我想在 laravel mix 构建期间或之后删除临时构建文件 这是我目前拥有的一些代码 但是del不工作 const mix require laravel mix const del require del compile sass i
  • 在 jQuery AJAX 成功中从 MySql 获取特定响应

    好吧 我有这个 ajax 代码 它将在 Success 块中返回 MySql 的结果 ajax type POST url index php success function data alert data My Query sql SE
  • 浏览器默认区域设置 - Intl.DateTimeFormat 与 navigator.language

    在对网站进行编码并格式化日期时 我想使用用户在浏览器中设置的区域设置 例如 如果用户定制了他们的chrome settings languages在 Chrome 中设置为非默认值 这就是我想要使用的值 但是 当我在此类浏览器的控制台中运行
  • Phonegap facebook 插件:android 的各种问题

    我正在尝试将 Phonegap 3 1 与 Phonegap facebook plugin 集成 以使我的应用程序能够使用 facebook 登录 https github com phonegap phonegap facebook p
  • (0, eval) () 的作用是什么? [复制]

    这个问题在这里已经有答案了 以下内容来自这个问题 https stackoverflow com questions 14119988 return this 0 evalthis 14120023 14120023 function q
  • ReferenceError 和全局对象

    在浏览器中的 JavaScript 中window是全局对象 这意味着在全局范围内定义的每个变量都是window 那么为什么我会得到这个结果 console log window foo No error logs undefined co
  • 如何生成 JavaScript 堆栈跟踪? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 关于如何以跨浏览器的方式在 javascript 中生成堆栈跟踪有什么建议吗 较新的浏览器 Chrome 和 Firefox 公开了一个允
  • `ie9` - contenteditable false 在父级可编辑时不起作用

    我正在尝试制作内容可编辑和不可编辑的容器 用户可以通过 3 种方式使用它 他们可以将内容与non editable 他们可以将内容与editable 他们可以在不选择其中之一的情况下放置内容 可编辑 我正在努力实现以下目标 content
  • JavaScript 中最长的通用前缀

    我正在尝试解决 Leet Code 挑战14 最长公共前缀 https leetcode com problems longest common prefix 编写一个函数来查找字符串数组中最长的公共前缀字符串 如果没有公共前缀 则返回空字
  • 跨浏览器:禁用输入字段的不同行为(文本可以/不能复制)

    我有一个被禁用的输入 html 字段 在某些浏览器 Chrome Edge Internet Explorer 和 Opera 中可以选择并复制文本 但至少在 Firefox 中这是不可能的 您可以通过在不同浏览器中执行以下代码来测试
  • openssl_pkey_get_details($res) 不返回公共指数

    我在用着这个例子 https stackoverflow com a 12575951 2016196使用 php 生成的密钥进行 javascript 加密openssl图书馆 但是 details openssl pkey get de
  • 使用 JQuery 预填充选择字段的下拉选项验证

    我有这个 JQuery 片段来防止选择已在另一个字段中选择的下拉选项 var coll select name service on change function coll each function var val this value

随机推荐

  • 【PSO-LSTM】基于PSO优化LSTM网络的电力负荷预测(Python代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 1 1 LSTM神经网络算法 1 2 PSO算法 1 3 PSO LSTM负荷预测模型 2 运行结果 2
  • excel 中如何使用python操作

    在Excel中使用Python可以通过两种方式实现 使用Python插件 您可以使用一些Excel插件 如PyXLL xlwings等 这些插件可以将Python代码嵌入到Excel工作簿中 以便在Excel中运行Python代码 使用Py
  • 服务器带宽测试

    服务器带宽 简单地说 就是同一时间段能传输的数据总量 服务器带宽越小那么可容纳数据吞吐量越小 同一时间段可容纳的用户访问量也越少 单位时间内从服务器拉取的数据量就越小 服务器带宽越大 可容纳同一时间访问数据越大 单位时间内从服务器拉取的数据
  • 1.8 C++ string

    string基本概念 本质 string是C 风格的字符串 而string本质上是一个类 string和char 区别 char 是一个指针string是一个类 类内部封装了char 管理这个字符串 是一个char 型的容器 特点 stri
  • MATLAB人工神经网络ANN代码

    本文介绍基于MATLAB实现人工神经网络 ANN 回归的详细代码与操作 目录 1 分解代码 1 1 循环准备 1 2 神经网络构建 1 3 数据处理 1 4 模型训练参数配置 1 5 神经网络实现 1 6 精度衡量 1 7 保存模型 2 完
  • android_使用ViewPager和Fragment实现滑动导航

    ViewPage是android support v4 jar包提供的用于页面滑动的库 这里没有将整个实现过程记录 只是把知识点摘出来单独解释 可参照代码自己实现 1 在xml布局文件中添加android support v4 view V
  • Keil 5使用JLink直接调试正在运行的CPU

    原文链接 环境 目标CPU STM32F429 连接工具 JLink V9 连接方式 SWD 调试工具 Keil MDK 5 20 使用场景 目标板正在运行 但是出BUG了 需要调试 而当前又没有在线debug 于是就需要用调试器在不复位C
  • C++ Streams

    1 fstream File table data txt 的内容为 137 2 71828 42 3 14159 7897987 1 608 1337 01101010001 从上述文件中读取第一个整数和第二个小数 ifstream in
  • 一篇文章学懂ADB命令和Monkey命令

    一篇文章学懂ADB命令和Monkey命令 1 adb命令 1 1 查看连接设备 1 2 查看adb版本 1 3 查看手机当前启动App的应用名和包名 1 4 使用aapt使用aapt 查看app的包名和启动名 查看app的包名和启动名 1
  • Element框架更换主题色

    Element 默认的主题色是鲜艳 友好的蓝色 但是UI小姐姐在设计的时候会为了更贴合项目主旨设计出其他颜色的主题色 比如新能源项目一般选用绿色做为主题色 此时我们就需要更改Element框架的主题色 一开始博主的想法是全局修改框架默认样式
  • JDBC连接各种数据库

    ConnectHSQLDB java Java代码 ConnectHSQLDB java package com javaworkspace connecthsqldb import java sql Connection import j
  • /usr/lib64/sa/sa2脚本解释

    文章目录 前言 脚本原文 脚本解释 前言 usr lib64 sa sa1脚本和 usr lib64 sa sa2脚本都是Linux 系统上的 sysstat 工具的一部分 在 etc cron d sysstat这个定时任务下执行 用来收
  • arm+linux swap出错问题

    今天 程序跑了两个小时 忽然出现如下信息 swap dup Bad swap file entry 002fdf80 VM killing process intrusion test swap free Bad swap file ent
  • Android-S模拟器

    0 前言 参考资料 1 基于Android P对Emulator的使用进行了说明 Android S情况有变 因此撰写本文进行记录 1 编译 根据参考资料 1 的方法编译 aosp x86 64 eng 完成后执行emulator无法正常进
  • 南京美食,为吃遍天下做准备~~

    标点美食地址 1 羊肉泡馍 长白街348号有家 老陕家 面馆 郑和公园北面 肉加馍 2 蓝空饭店 三条巷那边 稻香鸭 红烧老鹅 韭香脆皮鸡 是很好的还有一个叫什么牛肉粒的也好吃昏的了 3 山西炸酱面馆 顺着流行青年广场旁的天桥走到马路对面
  • 【阅读笔记】联邦学习实战——构建公平的大数据交易市场

    联邦学习实战 构建公平的大数据交易市场 前言 1 大数据交易 1 1 数据交易定义 1 2 数据确权 1 3 数据定价 2 基于联邦学习构建新一代大数据交易市场 3 联邦学习激励机制助力数据交易 4 FedCoin支付系统设计 4 1 Po
  • stm32 SystemInit函数详解

    官方固件库中的对应函数为 void SystemInit void Reset the RCC clock configuration to the default reset state for debug purpose Set HSI
  • 终于明白协方差的意义了

    转自 https blog csdn net GoodShot article details 79940438 协方差其意义 度量各个维度偏离其均值的程度 协方差的值如果为正值 则说明两者是正相关的 从协方差可以引出 相关系数 的定义 结
  • 程序员必读书目推荐

    1 Effective Java Joschua 稍许过时 但没有替代java方面的书 2 Effectvie C Scott Meyer 3 More Effective C Scott Meyer的书是非常非常好书 每次读都感到汗颜 自
  • Vue 动态锚点

    这是封装的组件 判断容器的滚动 接收父组件传来的Tab参数