diff --git a/src/hooks/useTarget.ts b/src/hooks/useTarget.ts index 432c3b2..3ac058d 100644 --- a/src/hooks/useTarget.ts +++ b/src/hooks/useTarget.ts @@ -42,20 +42,36 @@ export default function useTarget( const updatePos = useEvent(() => { if (targetElement) { // Exist target element. We should scroll and get target position + const calculatePosition = () => { + const { left, top, width, height } = + targetElement.getBoundingClientRect(); + const nextPosInfo: PosInfo = { left, top, width, height, radius: 0 }; + setPosInfo(origin => { + if (JSON.stringify(origin) !== JSON.stringify(nextPosInfo)) { + return nextPosInfo; + } + return origin; + }); + }; + if (!isInViewPort(targetElement) && open) { targetElement.scrollIntoView(scrollIntoViewOptions); - } - const { left, top, width, height } = - targetElement.getBoundingClientRect(); - const nextPosInfo: PosInfo = { left, top, width, height, radius: 0 }; + const observer = new IntersectionObserver( + (entries, observer) => { + const [entry] = entries; + if (entry.isIntersecting) { + setTimeout(() => calculatePosition(), 300); // debounce to let scroll finish + observer.disconnect(); + } + }, + { threshold: 1 }, + ); - setPosInfo(origin => { - if (JSON.stringify(origin) !== JSON.stringify(nextPosInfo)) { - return nextPosInfo; - } - return origin; - }); + observer.observe(targetElement); + } else { + calculatePosition(); + } } else { // Not exist target which means we just show in center setPosInfo(null);