Ant Design Table实现ScrollBoard组件的轮播表效果,无缝轮播

需求:

使用react项目表格内容轮播,DataV-React轮播表的使用-优快云博客的时候,文本内容较长时,设置溢出隐藏,完整的文本内容通过span的title属性来设置,想要使用ant design tooltip文本提示的样式来呈现完整的文本内容,使用DataV-React无法满足要求,改成通过结合 setInterval 和 Table 的 scroll 属性来实现类似 ScrollBoard 的轮播效果。以下是实现代码:

import React, { useState, useRef, useEffect } from 'react';
import { Table, Tooltip } from 'antd';

const Index = () => {
  const originalData = [
    { key: '1', id: 'TES-0001-202501108', subject: '轮播表可以单条轮播也可以整页轮播,支持点击事件,展示数据使用1', abnormal: '是' },
    { key: '2', id: 'TES-0001-202501107', subject: '轮播表可以单条轮播也可以整页轮播,支持点击事件,展示数据使用2', abnormal: '是' },
    { key: '3', id: 'TES-0001-202501106', subject: '轮播表可以单条轮播也可以整页轮播,支持点击事件,展示数据使用3', abnormal: '否' },
    { key: '4', id: 'TES-0001-202501095', subject: '轮播表可以单条轮播也可以整页轮播,支持点击事件,展示数据使用4', abnormal: '否' },
    { key: '5', id: 'TES-0001-202501094', subject: '轮播表可以单条轮播也可以整页轮播,支持点击事件,展示数据使用5', abnormal: '否' },
    { key: '6', id: 'TES-0001-202501093', subject: '轮播表可以单条轮播也可以整页轮播,支持点击事件,展示数据使用6', abnormal: '否' },
  ];

  // 复制一份数据,实现无缝轮播
  const [dataSource, setDataSource] = useState([...originalData, ...originalData]);

  const tableRef = useRef(null);
  const intervalRef = useRef(null);
  const [isHovered, setIsHovered] = useState(false);

  useEffect(() => {
    const startScroll = () => {
      intervalRef.current = setInterval(() => {
        if (tableRef.current && !isHovered) {
          const tableBody = tableRef.current.querySelector('.ant-table-body');
          if (tableBody) {
            // 每次滚动 1 行的高度
            tableBody.scrollTop += 36; // 36 是每行的高度

            // 如果滚动到复制的数据部分,无缝跳转回原始数据部分
            if (tableBody.scrollTop >= tableBody.scrollHeight / 2) {
              tableBody.scrollTop = 0;
            }
          }
        }
      }, 2000); // 2 秒滚动一次
    };

    startScroll();
    return () => clearInterval(intervalRef.current); // 组件卸载时清除定时器
  }, [isHovered]);

  // 鼠标悬停暂停
  const handleMouseEnter = () => {
    setIsHovered(true);
    clearInterval(intervalRef.current); // 暂停轮播
  };

  const handleMouseLeave = () => {
    setIsHovered(false);
    // 重新开始轮播
    intervalRef.current = setInterval(() => {
      if (tableRef.current) {
        const tableBody = tableRef.current.querySelector('.ant-table-body');
        if (tableBody) {
          tableBody.scrollTop += 36; // 每次滚动 1 行的高度
          if (tableBody.scrollTop >= tableBody.scrollHeight / 2) {
            tableBody.scrollTop = 0;
          }
        }
      }
    }, 2000);
  };

  const columns = [
    {
      title: '工单编号',
      dataIndex: 'id',
      key: 'id',
      ellipsis: true, // 启用省略号
      align: 'center',
      render: (text) => (
        <Tooltip title={text}>
          <span style={{ display: 'inline-block', width: '100%' }}>{text}</span>
        </Tooltip>
      ),
    },
    {
      title: '工单主题',
      dataIndex: 'subject',
      key: 'subject',
      ellipsis: true, // 启用省略号
      align: 'center',
      render: (text) => (
        <Tooltip title={text}>
          <span style={{ display: 'inline-block', width: '100%' }}>{text}</span>
        </Tooltip>
      ),
    },
    {
      title: '是否异常',
      dataIndex: 'abnormal',
      key: 'abnormal',
      align: 'center',
    },
  ];

  return (
    <div
      ref={tableRef}
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
      style={{ width: '100%', height: '166px', overflow: 'hidden' }}
    >
      <Table
        dataSource={dataSource}
        columns={columns}
        pagination={false}
        scroll={{ y: 166 }} // 设置表格的可滚动高度
        style={{ width: '100%' }}
      />
    </div>
  );
};

export default Index;

实现思路

  1. 轮播逻辑

    • 使用 setInterval 定时更新表格的滚动位置。

    • 通过 ref 获取表格的 DOM 元素,动态修改其 scrollTop 值。

  2. 表格滚动

    • 使用 Table 的 scroll 属性设置表格的可滚动区域。

    • 通过 CSS 控制表格的高度和样式。

  3. 鼠标悬停暂停

    • 监听表格的 onMouseEnter 和 onMouseLeave 事件,暂停和恢复轮播。

效果

  • 表格会每隔 2 秒自动滚动一行。

  • 鼠标悬停时,轮播暂停;鼠标离开时,轮播恢复。

  • 滚动到底部时,自动回到顶部,实现循环滚动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值