antd table 设置表格自动滚动

4,819 阅读1分钟

前言

antd table 设置表格自动滚动,不需要分页器

实现思路

  • 实现表格滚动定时改变,表格DOM的scrollTop值
  • 通过判断距上滚动的长度(scrollTop),大于滚动的高度(scrollHeight) 减去(-) 当前DOM的高度(clientHeight)说明当前的滚动已经到底了,需要将滚动条回到开头
  • 需要对当手动进行表格滚动的时候处理三种情况,
    • ①.鼠标移入表格(onmouseover)的时候将滚动的定时器取消
    • ②.鼠标移出表格的时候需要将滚动的定时器开启
    • ③.鼠标滚动的时候需要重新设置存储在state里面的scrollTop值,确保在滚动离开表格后,开启滚动的可以和当前滚动的位置一致

效果图

表格滚动效果图

封装组件源码

    import React, { Component } from 'react';
    import { Table } from 'antd';
    import PropTypes from 'prop-types';
    
    class Index extends Component {
      constructor() {
        super();
        this.state = {
          crowedScrollTop:0
        };
        this.divRef = React.createRef()
      }
    
      componentDidMount() {
        this.init()
        this.addScrollEvent()
      }
    
      componentWillUnmount() {
        this.clear()
      }
    
      init = () => {
        const that = this
        this.timeInterval = setInterval(() => {
          const dom = that.divRef.current.getElementsByClassName(
            'ant-table-body'
          )[0]
          const { crowedScrollTop } = that.state
          that.setState({
            crowedScrollTop:crowedScrollTop+1
          },() => {
            const { crowedScrollTop:newTop } = that.state
            dom.scrollTop = newTop
          })
            if (Math.ceil(dom.scrollTop) >= dom.scrollHeight - dom.clientHeight) {
              dom.scrollTop = 0
              that.setState({
                crowedScrollTop:0
              })
            }
        },100)
      }
    
      addScrollEvent = () => {
        const that = this
        const dom = this.divRef.current.getElementsByClassName(
          'ant-table-body'
        )[0]
        dom.onmouseover = () => {
          that.clear()
        }
        dom.onmouseout = () => {
          that.init()
        }
        dom.onscroll = () => {
          if (dom) {
            that.setState({
              crowedScrollTop:dom.scrollTop
            })
          }
        }
      }

  clear = () => {
    // eslint-disable-next-line no-unused-expressions
    this.timeInterval&&clearInterval(this.timeInterval)
  }

  render() {

    const {divStyle} = this.props
    return (
      <div  style={divStyle}  ref={this.divRef}>
        <Table
          {...this.props}
        />
      </div>
    );
  }
}

Index.propTypes = {
  dataSource: PropTypes.array,
  columns: PropTypes.array,
  scroll: PropTypes.object,
  divStyle: PropTypes.object,
  pagination:PropTypes.oneOfType([PropTypes.object, PropTypes.boolean]),
};

Index.defaultProps = {
  dataSource: [],
  columns:[],
  pagination:false,
  scroll:{},
  divStyle:{},
};

export default Index;

使用组件

    import React, { Component } from 'react';
    import Table from './Table';
    
    function randomNum(minNum, maxNum) {
      switch (arguments.length) {
        case 1:
          return parseInt(Math.random() * minNum + 1, 10);
          break;
        case 2:
          return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
          break;
        default:
          return 0;
          break;
      }
    }
    class Index extends Component {
    
      render() {
        return (
          <Table  {...{
          		dataSource:Array.from({ length: 20 }, (_, index) => {
                    return {
                      name: `test-${index}`,
                      makeAppointment: randomNum(20,100),
                      use: randomNum(20,100)
                    }
                  }),
    			columns:[
                      {
                        title: 'test1',
                        dataIndex: 'name',
                        key: 'name',
                        align:'left'
                      },
                      {
                        title: 'test2',
                        dataIndex: 'makeAppointment',
                        key: 'makeAppointment',
                        align:'center',
                      },
                      {
                        title: 'test3',
                        dataIndex: 'use',
                        key: 'use',
                        align:'center',
                      },
                  ],
                  scroll:{ x: '100%', y: 470 }
            
          }}/>
        );
      }
    }
    export default Index;