Skip to content

Commit

Permalink
fix: 修复scrollIntoView的参数behavior设置为smooth时引导面板定位异常的问题 #50509
Browse files Browse the repository at this point in the history
  • Loading branch information
Neumann615 committed Aug 23, 2024
1 parent 4a2d593 commit 6cdcbba
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 4 deletions.
4 changes: 2 additions & 2 deletions docs/examples/scrollIntoView.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useRef, useState } from 'react';
import React, {useRef, useState} from 'react';
import Tour from '../../src/index';
import './basic.less';

Expand Down Expand Up @@ -65,7 +65,7 @@ const App = () => {
),
target: () => updateBtnRef.current,
scrollIntoViewOptions: {
block: 'start'
block: 'start', behavior:'smooth'
}
},
{
Expand Down
9 changes: 7 additions & 2 deletions src/hooks/useTarget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import useEvent from 'rc-util/lib/hooks/useEvent';
import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect';
import { useMemo, useState } from 'react';
import type { TourStepInfo } from '..';
import { isInViewPort } from '../util';
import { isInViewPort,debounce } from '../util';

export interface Gap {
offset?: number | [number, number];
Expand Down Expand Up @@ -44,8 +44,8 @@ export default function useTarget(
// Exist target element. We should scroll and get target position
if (!isInViewPort(targetElement) && open) {
targetElement.scrollIntoView(scrollIntoViewOptions);
return;
}

const { left, top, width, height } =
targetElement.getBoundingClientRect();
const nextPosInfo: PosInfo = { left, top, width, height, radius: 0 };
Expand All @@ -62,15 +62,20 @@ export default function useTarget(
}
});

const debounceUpdatePos = debounce(updatePos, 16)

const getGapOffset = (index: number) =>
(Array.isArray(gap?.offset) ? gap?.offset[index] : gap?.offset) ?? 6;

useLayoutEffect(() => {
updatePos();
// update when window resize
window.addEventListener('resize', updatePos);
// update when window scroll stop
window.addEventListener('scroll',debounceUpdatePos)
return () => {
window.removeEventListener('resize', updatePos);
window.removeEventListener('scroll', debounceUpdatePos);
};
}, [targetElement, open, updatePos]);

Expand Down
13 changes: 13 additions & 0 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,16 @@ export function getPlacement(
stepPlacement ?? placement ?? (targetElement === null ? 'center' : 'bottom')
);
}

export function debounce<T extends (...args: any[]) => any>(func: T, wait: number): T {
let timeoutId: ReturnType<typeof setTimeout>;

const debouncedFunc = (...args: Parameters<T>): void => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func(...args);
}, wait);
};

return debouncedFunc as T;
}

0 comments on commit 6cdcbba

Please sign in to comment.