Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(table): table footer may not be displayed when switching tabs #3370

Merged
merged 2 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 29 additions & 14 deletions src/table/hooks/useFixed.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useState, useMemo, useRef, WheelEvent } from 'react';
import { get , pick , xorWith } from 'lodash-es';
import { useEffect, useState, useMemo, useRef, WheelEvent, useCallback } from 'react';
import { get, pick, xorWith } from 'lodash-es';
import { getIEVersion } from '../../_common/js/utils/helper';
import log from '../../_common/js/log';
import { ClassName, Styles } from '../../common';
Expand All @@ -9,6 +9,7 @@ import { on, off } from '../../_util/dom';
import { FixedColumnInfo, TableRowFixedClasses, RowAndColFixedPosition, TableColFixedClasses } from '../interface';
import useDebounce from '../../hooks/useDebounce';
import usePrevious from '../../hooks/usePrevious';
import { resizeObserverElement, isLessThanIE11OrNotHaveResizeObserver } from '../utils';

// 固定列相关类名处理
export function getColumnFixedStyles(
Expand Down Expand Up @@ -342,9 +343,11 @@ export default function useFixed(
};
};

const updateFixedHeader = () => {
// 使用 useCallback 来优化性能
const updateFixedHeader = useCallback(() => {
const tRef = tableContentRef?.current;
if (!tRef) return;

const isHeightOverflow = tRef.scrollHeight > tRef.clientHeight;
setIsFixedHeader(isHeightOverflow);
setIsWidthOverflow(tRef.scrollWidth > tRef.clientWidth);
Expand All @@ -356,7 +359,7 @@ export default function useFixed(

// updateTableWidth(isHeightOverflow);
// updateThWidthListHandler();
};
}, []);

const setTableElmWidth = (width: number) => {
if (tableElmWidth.current === width) return;
Expand Down Expand Up @@ -490,8 +493,22 @@ export default function useFixed(
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isFixedColumn, columns, tableContentRef]);

// 使用防抖函数,避免频繁触发
const updateFixedHeaderByUseDebounce = useDebounce(() => {
updateFixedHeader();
}, 30);

/**
* 通过监测表格大小变化,来调用 updateFixedHeader 修改状态
*/
useEffect(() => {
if (tableContentRef.current) {
return resizeObserverElement(tableContentRef.current, updateFixedHeaderByUseDebounce);
}
}, [updateFixedHeaderByUseDebounce]);

// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(updateFixedHeader, [maxHeight, data, columns, bordered, tableContentRef]);
useEffect(updateFixedHeaderByUseDebounce, [maxHeight, data, columns, bordered, tableContentRef]);

useEffect(() => {
updateTableElmWidthOnColumnChange(finalColumns, preFinalColumns);
Expand Down Expand Up @@ -537,22 +554,20 @@ export default function useFixed(
}, 30);

function addTableResizeObserver(tableElement: HTMLDivElement) {
// IE 11 以下使用 window resize;IE 11 以上使用 ResizeObserver
if (typeof window === 'undefined') return;
if (getIEVersion() < 11 || typeof window.ResizeObserver === 'undefined') return;
/**
* IE 11 以下使用 window resize;IE 11 以上使用 ResizeObserver
* 抽离相关判断为单独的方法
*/
if (isLessThanIE11OrNotHaveResizeObserver()) return;
off(window, 'resize', onResize);
if (!tableElmWidth.current) return;
const resizeObserver = new window.ResizeObserver(() => {
// 抽离 resize 为单独的方法,通过回调来执行操作
return resizeObserverElement(tableElement, () => {
const timer = setTimeout(() => {
refreshTable();
clearTimeout(timer);
}, 60);
});
resizeObserver.observe(tableElement);
return () => {
resizeObserver?.unobserve?.(tableElement);
resizeObserver?.disconnect?.();
};
}

useEffect(() => {
Expand Down
29 changes: 28 additions & 1 deletion src/table/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isFunction , get , isObject } from 'lodash-es';
import { isFunction, get, isObject } from 'lodash-es';
import {
BaseTableCellParams,
CellData,
Expand All @@ -9,6 +9,7 @@ import {
} from './type';
import { ClassName, HTMLElementAttributes } from '../common';
import { AffixProps } from '../affix';
import { getIEVersion } from '../_common/js/utils/helper';

export function toString(obj: any): string {
return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
Expand Down Expand Up @@ -111,3 +112,29 @@ export function getAffixProps(mainAffixProps: boolean | Partial<AffixProps>, sub
if (typeof subAffixProps === 'object') return subAffixProps;
return {};
}

// 判断是否小于 ie11 版本 或者没有 ResizeObserver 对象
export const isLessThanIE11OrNotHaveResizeObserver = () =>
typeof window === 'undefined' || getIEVersion() < 11 || typeof window.ResizeObserver === 'undefined';

/**
* IE 11 版本以上或者支持 ResizeObserver API 的浏览器中,
* 使用 ResizeObserver API 来监听元素的尺寸变化
*
* 注意:建议 callback 使用前经过 useDebounce 包裹
*
* @param tableElement - 要监听的表格元素
* @param callback - 尺寸变化时调用的回调函数
*/
export const resizeObserverElement = (tableElement: HTMLDivElement, callback: () => void) => {
if (isLessThanIE11OrNotHaveResizeObserver()) return;
const resizeObserver = new window.ResizeObserver(() => {
// 注意:这里的回调会比较频繁,建议 callback 使用前经过 useDebounce 包裹
callback?.();
});
resizeObserver.observe(tableElement);
return () => {
resizeObserver?.unobserve?.(tableElement);
resizeObserver?.disconnect?.();
};
};