大屏表格实现无限滚动效果

实现效果

hmgif3

实现思路

  1. 首先固定最外层的高度,并且设置超出高度后隐藏
  2. 设置每一行的高度为固定35PX,默认显示10行,所以最外层高度就是 35 * 10 + 表头的高度
  3. 遍历时克隆一份表格数据,用于视差效果显示
  4. 设置滚动动画,让表格行所在的父元素 tableTr 不断往上移动,当移动到末尾数据时,此时定义的移动距离 position 刚好时总高度的一半
  5. 然后重置 position 的距离为0,因为我们克隆了一份数据,此时便不会有闪跳的情况,给人的感觉就是继续往上滚动,从而实现无限滚动的效果

完整代码

<template>
  <div class="table-box">
    <!--表头-->
    <div class="table-th">
      <div style="width: 60px">排名</div>
      <div>区域</div>
      <div>总服务人数</div>
      <div>2023年</div>
      <div>2024年</div>
    </div>
    <!--表格数据-->
    <div class="table-tr" ref="tableTr" @mouseenter="pause" @mouseleave="resume">
      <!--克隆一份数据-->
      <div
        class="tr-item"
        v-for="(item, index) in [...tableData, ...tableData]"
        :key="index"
        :class="{ 'even-background': index < 15 ? index % 2 !== 0 : index % 2 === 0 }"
      >
        <div class="index-item">
          <div v-if="item.ranking <= 3" class="tab-index index-bg">
            {{ item.ranking }}
          </div>
          <div v-else class="tab-index">
            {{ item.ranking }}
          </div>
        </div>
        <div>{{ item.province }}</div>
        <div>{{ item.totalServiceNumber }}</div>
        <div>{{ item.yearNumber2 }}</div>
        <div>{{ item.yearNumber3 }}</div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'demo2',
  data() {
    return {
      tableData: [],
      position: 0,
      animationId: null,
    }
  },
  mounted() {
    this.getTableData()
    this.$nextTick(() => {
      this.animation()
    })
  },
  methods: {
    /**
     * 暂停动画。
     * 此方法通过取消动画帧请求来暂停动画的执行。
     * 当鼠标移入组件时调用,以暂停动画的播放。
     */
    pause() {
      cancelAnimationFrame(this.animationId) // 取消当前的动画帧请求
      this.animationId = null // 清空动画帧请求的ID
      this.isPaused = true // 标记动画为暂停状态
    },
    /**
     * 恢复动画。
     * 如果动画当前处于暂停状态,此方法会重新启动动画。
     * 当鼠标移出组件时调用,以恢复动画的播放。
     */
    resume() {
      if (this.isPaused) {
        // 当动画处于暂停状态时
        this.animation() // 重新调用动画函数
        this.isPaused = false // 将动画状态设置为播放
      }
    },
    /**
     * 启动一个动画,用于滚动表格中的行。
     * 此函数没有参数和返回值,因为它直接操作DOM并启动一个循环动画。
     * 动画效果是通过改变行的垂直偏移来实现的。
     */
    animation() {
      // 获取将要进行动画的ul元素
      let tableTr = this.$refs.tableTr
      // 获取ul元素的高度,用于计算动画的终点
      let tableTrHeight = tableTr.offsetHeight
      /**
       * 动画循环函数。
       * 不断调整元素的垂直偏移,创造向下滚动的效果。
       * 当元素偏移超过其高度的一半时,重置偏移值,实现循环滚动。
       */
      const animate = () => {
        this.position -= 2 // 每次循环减少的偏移量,控制动画速度
        if (this.position <= -(tableTrHeight / 2)) {
          this.position = 0 // 当偏移量小于等于负的一半高度时,重置偏移量,准备下一次循环
        }
        tableTr.style.transform = `translateY(${this.position}px)` // 应用偏移量到元素的transform属性上,实现动画效果
        this.animationId = requestAnimationFrame(animate) // 请求下一个动画帧继续执行此函数,保持动画运行
      }
      animate() // 初始化动画
    },
    getTableData() {
      const generatedData = []
      const provinces = [
        '北京',
        '上海',
        '广东',
        '江苏',
        '浙江',
        '山东',
        '河南',
        '湖南',
        '湖北',
        '四川',
        '福建',
        '安徽',
        '陕西',
        '重庆',
        '云南',
      ]
      const randomServiceNumber = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min
      for (let i = 0; i < 15; i++) {
        const province = provinces[Math.floor(Math.random() * provinces.length)]
        const totalServiceNumber = randomServiceNumber(1000, 10000).toString()
        const yearNumber2 = randomServiceNumber(500, 5000).toString()
        const yearNumber3 = randomServiceNumber(1000, 8000).toString()

        generatedData.push({
          ranking: i + 1,
          province,
          totalServiceNumber,
          yearNumber2,
          yearNumber3,
        })
      }

      this.tableData = generatedData
    },
  },
}
</script>

<style scoped lang="scss">
.table-box {
  background-color: #000;
  color: white;
  // 最外层父元素必须要定高
  width: 500px;
  height: 385px;
  overflow: hidden;
}

.table-th {
  display: flex;
  align-items: center;
  justify-content: space-around;
  background-color: #1a8dec;
  font-weight: 100;
  font-size: 14px;
  padding: 2px 0;
  height: 35px;
  line-height: 35px;
  position: sticky;
  z-index: 2;

  & > div {
    width: 120px;
    text-align: center;
  }
}

.table-tr {
  display: flex;
  flex-direction: column;

  .tr-item {
    display: flex;
    align-items: center;
    justify-content: space-around;
    font-weight: 100;
    font-size: 12px;
    height: 35px; // 每一行的高度也必须固定,用户计算滚动距离
    line-height: 35px;

    & > div {
      width: 120px;
      text-align: center;
    }

    .index-item {
      width: 60px;
      display: flex;
      align-items: center;
      justify-content: center;
    }
  }

  //.tr-item:nth-child(odd) {
  //  background-color: #322c5f;
  //}
}

.even-background {
  background-color: #322c5f;
}

.tab-index {
  width: 16px;
  height: 16px;
  line-height: 16px;

  text-align: center;
  border-radius: 50%;
  background-color: #4666ff;
}

.index-bg {
  background-color: #f43737;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/652933.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VMware vSphere Distributed Services Engine 和利用 DPU 实现网络加速

VMware相关学习专栏&#xff1a;虚拟化技术 vSphere 8.0 通过加速数据处理单元 (DPU) 上的网络功能实现了突破性的工作负载性能。 vSphere 8.0 通过加速 DPU 上的网络功能实现了突破性工作负载性能&#xff0c;从而满足现代分布式工作负载的吞吐量和延迟需求。借助 vSphere Dis…

GIGE 协议摘录

系列文章目录 GIGE 学习笔记 GIGE 协议摘录 文章目录 系列文章目录引言第 1 章 设备发现1.1 链路选择1.1.1 单链路配置1.1.2 多链路配置1.1.3 链路聚合组配置 LAG 1.2 IP配置1.2.1 协议选择1.2.2 静态IP1.2.3 DHCP1.2.4 链接本地地址 LLA 1.3 设备枚举1.3.1 GVCP设备发现 引言 …

4个月赚20万!一张图赚7500!多种变现方式,一个被忽视的暴力项目

大家好&#xff0c;今天给大家带来一个被很多人忽视&#xff0c;不起眼确很暴力的项目。 大胆放心干 课程获取&#xff1a; https://hsgww.com/https://hsgww.com/

停车场变综合楼,结构分析助力低碳设计

PLAXIS 和 RAM 助力确定更有效的结构设计并大幅降低施工成本 总部和周边区域 桑坦德银行位于英国的新总部将现有的四个英国办事处合并到米尔顿凯恩斯的一个中心枢纽&#xff0c;位于伦敦以北 50 英里。 Unity Place 将作为桑坦德银行约 5,000 名员工的办公场所。该项目总投资 …

SpringBoot——整合RabbitMQ收发消息

目录 RabbitMQ消息队列 项目总结 新建一个SpringBoot项目 pom.xml application.properties配置文件 index.html前端页面 RabbitMQConfig配置类 RabbitMQProducer生产者 RabbitMQConsumer消费者 IndexController控制器 SpringbootRabbitmqApplication启动类 测试 Ra…

Linux 删除SSH密钥(id_ed25519),重新生成

在Linux系统中&#xff0c;重新生成SSH密钥&#xff08;比如id_ed25519&#xff09;的过程包括删除现有的密钥文件并生成一个新的。 以下是具体的步骤&#xff1a; 0. 查看下是否有密钥 1. 删除原有的id_ed25519密钥 默认情况下&#xff0c;SSH密钥存储在用户的主目录下的 .…

【Pandas】深入解析`pd.read_sql()`函数

【Pandas】深入解析pd.read_sql()函数 &#x1f308; 欢迎莅临我的个人主页&#x1f448;这里是我深耕Python编程、机器学习和自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;并乐于分享知识与经验的小天地&#xff01;&#x1f387; &#x1f393; 博主简介&#xf…

一机实现All in one,NAS如何玩转虚拟机!

常言道&#xff0c;中年男人玩具有三宝 充电器、路由器、NAS 你问我NAS的魔力在哪里&#xff1f; 一机实现All in one洒洒水啦 那NAS又如何玩转虚拟机呢? 跟我来 0基础也能轻松get! NAS如何玩转虚拟机 铁威马NAS的VirtualBox的简单易用&#xff0c;可虚拟的系统包括Win…

基础8 探索JAVA图形编程桌面:邮件操作组件详解

在一个静谧的午后&#xff0c;卧龙和凤雏相邀来到一家古朴典雅的茶馆。茶馆内环境清幽&#xff0c;袅袅的茶香与悠扬的古筝声交织在一起&#xff0c;营造出一种宁静而祥和的氛围。 卧龙和凤雏坐在茶馆的一角&#xff0c;面前的桌子上摆放着一套精致的茶具。茶香四溢&#xff0c…

【机器学习】探究DQN通过训练来解决AI序列决策问题

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

白酒:不同产地白酒的风格特点与比较

云仓酒庄豪迈白酒&#xff0c;作为中国白酒的一部分&#xff0c;其风格特点深受产区的影响。不同产地的白酒&#xff0c;由于自然环境、酿造工艺等因素的差异&#xff0c;形成了各自与众不同的风味和特点。下面让云仓酒庄豪迈白酒来比较一下不同产地白酒的风格特点。 首先&…

iPhone“已删除”照片被恢复,苹果到底有没有后门?

继微软本周推出的Windows“回忆”功能引发隐私焦虑&#xff0c;遭马斯克和安全大咖们猛烈抨击后&#xff0c;苹果iPhone手机近日也曝出了类似的“记忆门”。 删除十几年的iPhone照片被恢复 近日&#xff0c;有苹果手机用户更新了苹果上周发布的iOS 17.5系统后&#xff0c;意外…

大数据开发面试题【ClickHouse篇】

170、clickhouse介绍以及架构 clickhouse一个分布式列式存储数据库&#xff0c;主要用于在线分析查询 171、列式存储和行式存储有什么区别&#xff1f; 行式存储&#xff1a; 1、数据是按行存储的 2、没有建立索引的查询消耗很大的IO 3、建立索引和视图花费一定的物理空间和…

摩尔投票法——代码实现及注释(力扣169题:找出列表中多数元素)

题源&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 目录 一、摩尔投票法 1.1 关键思想 1.2 时空复杂度 1.3 算法详细步骤 1.4 代码 1.5 算法理解 一、摩尔投票法 摩尔投票法&#xff08;Boyer–Moore Majority Vote Algorithm&#xff09;&#xff0c;也被称为…

【MySQL】SQL 基础

文章目录 【 1. SQL 的书写规则 】1.1 大小写规则1.2 常量的表示1.3 注释1.4 HELP 系统帮助 【 2. 常用数据库函数 】2.1 SHOW DATABASES 显示数据库2.2 CREATE DATABASE 创建数据库2.3 ALTER DATABASE 修改数据库2.4 DROP DATABASE 删除数据库2.5 USE 选择数据库 【 3. RDBMS …

Python基于PyQt6制作GUI界面——多选框

QCheckBox 是 PyQt6 中的一个复选框控件&#xff0c;它允许用户通过单击来选择或取消选择某个选项。与 QRadioButton 不同&#xff0c;QCheckBox 控件并不互斥&#xff0c;这意味着用户可以同时选择多个 QCheckBox。示例对应的制作的 ui文件 界面如下所示。 <?xml version…

惯性测量单元M-G370系列广泛用于工业系统各个领域

爱普生现已推出型号为M-G370系列的高稳定性、高精度及极小尺寸封装的惯性测量单元(IMU)&#xff0c;可广泛应用于工业系统的各个领域。 为了节省PCB的面积和产品空间&#xff0c;M-G370系列性测量单元设计精巧&#xff0c;且具有6个自由度:三轴角速率和三轴线性加速度&…

5个将文本转语音的工具,高考复习的绝佳助手

高考倒计时10天&#xff01; 在这最后的冲刺阶段&#xff0c;同学们都在拼命刷题&#xff0c;但面对已经整理好的知识点&#xff0c;时间紧迫&#xff0c;如何高效复习呢&#xff1f; 别急&#xff0c;今天我要和大家分享一个绝佳的复习方法——文字转语音。这个方法可以让你…

JVM 内存布局深度解析,你所不知道的一面

作为Java开发者&#xff0c;想要写出高质量的代码&#xff0c;理解JVM的内存结构是必修课。本文将为您深度解析 Java 虚拟机(JVM)中的内存布局及其细节分析&#xff0c;让你在内存管理的道路上行稳致远。希望通过本文能让你彻底理解其中的奥秘。 一、内存布局概览 在我们深入具…

【C++】牛客——BC157 素数回文

✨题目链接&#xff1a; BC157 素数回文 ✨题目描述 现在给出一个素数&#xff0c;这个素数满足两点&#xff1a; 只由1-9组成&#xff0c;并且每个数只出现一次&#xff0c;如13,23,1289。 位数从高到低为递减或递增&#xff0c;如2459&#xff0c;87631。 请你判断一下&…