欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

antd4里table滾動的實(shí)現(xiàn)

 更新時間:2023年03月02日 10:46:29   作者:caicsama  
本文主要介紹了antd4里table滾動的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

首先antd4的table的底層實(shí)現(xiàn)是rc-table,就從rc-table來看看。

一、rc-table里Header、Footer、TableBody實(shí)現(xiàn)保持同頻滾動的方法

場景:Table內(nèi)容區(qū)域大于容器Table寬度,并且Table設(shè)置了scrollX,Header、Footer都有, 才關(guān)注同頻滾動

那么是如何實(shí)現(xiàn)的?

  • 監(jiān)聽onScroll方法獲取到滾動條向左的滾動的距離scrollLeft;
  • 同時給三個dom設(shè)置scrollLeft

二、 rc-table里的onScroll實(shí)現(xiàn)

先看一般的onScroll實(shí)現(xiàn)

  • 監(jiān)聽onScroll獲取scrollLeft
  • 設(shè)置header、footer、tableBody的scrollLeft

下面是偽代碼哈

const onScroll = (e: ScrollEvent) => {
    // 拿到scrollLeft
    const scrollLeft = e.target.scrollLeft
    // 給所有的header、footer、table-body設(shè)置scrollLeft
    header.scrollLeft = scrollLeft
    footer.scrollLeft = scrollLeft
    tableBody.scrollLeft = scrollLeft
}

源碼里onScroll的實(shí)現(xiàn)

?const onScroll = ({
? ? currentTarget,
? ? scrollLeft,
? }: {
? ? currentTarget: HTMLElement;
? ? scrollLeft?: number;
? }) => {
? ? const mergedScrollLeft = typeof scrollLeft === 'number' ? scrollLeft : currentTarget.scrollLeft;

? ? const compareTarget = currentTarget || EMPTY_SCROLL_TARGET;?
? ? if (!getScrollTarget() || getScrollTarget() === compareTarget) {?
? ? ? setScrollTarget(compareTarget);
? ? ? //一個 滾動需要 控制 header、body、summary、stickyScrollBar所有同步滾動
?? ??? ??? ?// header設(shè)置scrollLeft
?? ??? ??? ?scrollHeaderRef.current = mergedScrollLeft
?? ??? ??? ?// body 設(shè)置scrollLeft
?? ??? ??? ?scrollBodyRef.current = mergedScrollLeft
? ? }
? };

 對比兩個的實(shí)現(xiàn),可以看到rc-table里的實(shí)現(xiàn)多了一個入?yún)crollLeft和一個if判斷;
為什么多了一個入?yún)?、一個判斷?繼續(xù)往下看?

三、 Header、Footer的滾動監(jiān)聽

  • 用組件FixedHolder實(shí)現(xiàn),給FixedHolder綁定ref;
  • 監(jiān)聽的是onWheel, 不是onScroll;

為什么監(jiān)聽onWheel不是onScroll?

React.useEffect(() => {
? ? ? function onWheel(e: WheelEvent) {
? ? ? ? // deltaX: Returns a double representing the horizontal scroll amount
? ? ? ? const { currentTarget, deltaX } = e as unknown as React.WheelEvent<HTMLDivElement>;
? ? ? ? // 避免觸發(fā)不必要滾動, 是一種優(yōu)化
? ? ? ? if (deltaX) {
? ? ? ? ? onScroll({ currentTarget, scrollLeft: currentTarget.scrollLeft + deltaX });
? ? ? ? ? e.preventDefault();
? ? ? ? }
? ? ? }
? ? ? fixHolder.current?.addEventListener('wheel', onWheel);

? ? ? return () => {
? ? ? ? fixHolder.current?.removeEventListener('wheel', onWheel);
? ? ? };
? ? }, []);

不要將 onscroll 與 onwheel混淆。onwheel 是鼠標(biāo)滾輪旋轉(zhuǎn),而 onscroll 處理的是對象內(nèi)部內(nèi)容區(qū)的滾動事件。
當(dāng)dom滿足下面任意一條的時候,不會觸發(fā)onScroll;

  • overflow:hidden
  • 滾動條不存在

FixHolder組件

設(shè)置了樣式overflow:hidden;

<div
        style={{
          overflow: 'hidden',
          ...(isSticky ? { top: stickyTopOffset, bottom: stickyBottomOffset } : {}),
        }}
        ref={setScrollRef}
        className={classNames(className, {
          [stickyClassName]: !!stickyClassName,
        })}
                />
                <table
          style={{
            tableLayout: 'fixed',
            visibility: noData || mergedColumnWidth ? null : 'hidden',
          }}
        >
          {(!noData || !maxContentScroll || allFlattenColumnsWithWidth) && (
            <ColGroup
              colWidths={mergedColumnWidth ? [...mergedColumnWidth, combinationScrollBarSize] : []}
              columCount={columCount + 1}
              columns={flattenColumnsWithScrollbar}
            />
          )}
          {children({
            ...props,
            stickyOffsets: headerStickyOffsets,
            columns: columnsWithScrollbar,
            flattenColumns: flattenColumnsWithScrollbar,
          })}
        </table>
                </div>

通過ref,調(diào)用useCallback賦值dom;利用scrollRef.current監(jiān)聽wheel事件,轉(zhuǎn)成onScroll,增加入?yún)crollLeft;

const setScrollRef = React.useCallback((element: HTMLElement) => {
      scrollRef.current = element;
    }, []);

四、TableBody的滾動

當(dāng)然是監(jiān)聽onScroll事件;
給Tables設(shè)置scrollX的情況下,TableBody設(shè)置樣式{overflow-x: auto}這樣會有同頻滾動

<div
  style={
    ...scrollXStyle,
    ...scrollYStyle
  }
          onScroll={onScroll}
          ref={scrollBodyRef}
        >
          <TableComponent>
            {bodyColGroup}
            {bodyTable}
          </TableComponent>
        </div>

五、很nice的點(diǎn)

獲得當(dāng)前正在執(zhí)行的dom

const [setScrollTarget, getScrollTarget] = useTimeoutLock(null);

getScrollTarget用來獲得當(dāng)前正在執(zhí)行的dom
使用useState來存儲正在執(zhí)行的dom; 當(dāng)組件重新渲染,dom更新,此時正在執(zhí)行的dom,在下一個render的時候,就變了;useRef在下一次渲染之前不重新賦值,還是保留和上一次一樣的值;
源碼里使用useRef + setTimeout實(shí)現(xiàn);useRef是用來存放當(dāng)前正在執(zhí)行的dom;setTimeout用來節(jié)流;
其中g(shù)etState獲取正在執(zhí)行當(dāng)前state,可能是空的;setState設(shè)置當(dāng)前的State,并且在100ms以后清空設(shè)置的狀態(tài);

export function useTimeoutLock<State>(defaultState?: State): [(state: State) => void, () => State | null] {
? const frameRef = useRef<State | null>(defaultState || null);
? const timeoutRef = useRef<number>();

? function cleanUp() {
? ? window.clearTimeout(timeoutRef.current);
? }

? function setState(newState: State) {
? ? frameRef.current = newState;
?? ??? ?// 清空上一次的定時器
? ? cleanUp();
? ??
? ? timeoutRef.current = window.setTimeout(() => {
? ? ? frameRef.current = null;
? ? ? timeoutRef.current = undefined;
? ? }, 100);
? }

? function getState() {
? ? return frameRef.current;
? }

? useEffect(() => cleanUp, []);

? return [setState, getState];
}

onScroll為什么設(shè)置if判斷

getScrollTarget()調(diào)用onScroll的之前,是否有滾動的dom; 沒有就更新;有,判斷是否和觸發(fā)onScroll是相同Dom;是,更新;目的是為了避免執(zhí)行上一個onScroll的時候,下一個onScroll執(zhí)行,陷入循環(huán),就相當(dāng)于節(jié)流了;hooks版本的節(jié)流

const compareTarget = currentTarget || EMPTY_SCROLL_TARGET; 
// 固定滾動項
// 在處理上一個滾動的時候,禁止下一個也滾動執(zhí)行onScroll
if (!getScrollTarget() || getScrollTarget() === compareTarget) {
    setScrollTarget(compareTarget);
}

看這塊邏輯的時候,優(yōu)化細(xì)節(jié)??;從hooks的角度,實(shí)現(xiàn)節(jié)流;wheel和scroll都是滾動,但是也有區(qū)別;并且在react里支持dom綁定onScroll、onWheel;

相關(guān)鏈接:

rc-table: https://github.com/react-component/table
antd-table: https://ant.design/components/table-cn#components-table-demo-fixed-columns

到此這篇關(guān)于antd4里table滾動的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)antd4 table滾動內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • ahooks正式發(fā)布React?Hooks工具庫

    ahooks正式發(fā)布React?Hooks工具庫

    這篇文章主要為大家介紹了ahooks正式發(fā)布值得擁有的React?Hooks工具庫使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • React使用useImperativeHandle自定義暴露給父組件的示例詳解

    React使用useImperativeHandle自定義暴露給父組件的示例詳解

    useImperativeHandle?是?React?提供的一個自定義?Hook,用于在函數(shù)組件中顯式地暴露給父組件特定實(shí)例的方法,本文將介紹?useImperativeHandle的基本用法、常見應(yīng)用場景,需要的可以參考下
    2024-03-03
  • React中項目路由配置與跳轉(zhuǎn)方法詳解

    React中項目路由配置與跳轉(zhuǎn)方法詳解

    這篇文章主要為大家詳細(xì)介紹了React中項目路由配置與跳轉(zhuǎn)方法的相關(guān)資料,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價值,感興趣的小伙伴可以了解一下
    2023-08-08
  • Next.js實(shí)現(xiàn)react服務(wù)器端渲染的方法示例

    Next.js實(shí)現(xiàn)react服務(wù)器端渲染的方法示例

    這篇文章主要介紹了Next.js實(shí)現(xiàn)react服務(wù)器端渲染的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • React Draggable插件如何實(shí)現(xiàn)拖拽功能

    React Draggable插件如何實(shí)現(xiàn)拖拽功能

    這篇文章主要介紹了React Draggable插件如何實(shí)現(xiàn)拖拽功能問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • 基于React編寫一個全局Toast的示例代碼

    基于React編寫一個全局Toast的示例代碼

    前些日子在做項目的時候,需要封裝一個Toast組件,我想起之前用過的庫,只要在入口文件中引入就可以在全局中使用,還是很方便的,借這次機(jī)會也來實(shí)現(xiàn)一下,所以本文介紹了React中如何編寫一個全局Toast,需要的朋友可以參考下
    2024-05-05
  • react實(shí)現(xiàn)復(fù)選框全選和反選組件效果

    react實(shí)現(xiàn)復(fù)選框全選和反選組件效果

    這篇文章主要為大家詳細(xì)介紹了react實(shí)現(xiàn)復(fù)選框全選和反選組件效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • React中井字棋游戲的實(shí)現(xiàn)示例

    React中井字棋游戲的實(shí)現(xiàn)示例

    本文主要介紹了React中井字棋游戲的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • react中事件處理與柯里化的實(shí)現(xiàn)

    react中事件處理與柯里化的實(shí)現(xiàn)

    本文主要介紹了react中事件處理與柯里化的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • React實(shí)現(xiàn)路由鑒權(quán)的實(shí)例詳解

    React實(shí)現(xiàn)路由鑒權(quán)的實(shí)例詳解

    React應(yīng)用中的路由鑒權(quán)是確保用戶僅能訪問其授權(quán)頁面的方式,用于已登錄或具有訪問特定頁面所需的權(quán)限,這篇文章就來記錄下React實(shí)現(xiàn)路由鑒權(quán)的流程,需要的朋友可以參考下
    2024-07-07

最新評論