為網站加上過場效果,會大大地提升網站體驗,用戶也願意花更多時間在網站上停留。互動式的效果通常會透過以下鼠標事件來觸發:
在這我想和大家分享一段可重覆使用的程式碼,讓每個 React 元件都能很簡易地加上「滾動顯示」的過場效果。過去我們需要透過偵測網站大小和 Body dom 裡面的不同屬性 (如 scrollHeight),來計算目前用戶滾動到的位置,需要顯示哪些對應的元件。現在我們有一個非常方便的 IntersectionObserver API 可以處理這些和「可視範圍」(viewport) 有關的計算。
讓我們直接來看這段程式碼
import { useEffect, useRef, useState } from 'react';
function useScrollToReveal(): {
domRef: React.MutableRefObject<any>;
fadeInStyle: React.CSSProperties;
} {
const domRef = useRef<any>(null);
const [isVisible, setVisible] = useState(false);
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
if (!domRef || !domRef.current) return;
// In your case there's only one element to observe:
if (entries[0].isIntersecting) {
setTimeout(() => setVisible(true), 450);
// No need to keep observing:
observer.unobserve(domRef.current);
}
},
{ rootMargin: '48px' }
);
if (domRef && domRef.current) {
observer.observe(domRef && domRef.current);
}
return () => {
if (domRef && domRef.current) {
observer.unobserve(domRef.current);
}
};
}, []);
return {
domRef,
fadeInStyle: { transition: 'all .8s ease-in', opacity: isVisible ? 1 : 0 },
};
}
export default useScrollToReveal;
import useScrollToReveal from '@hooks/useScrollToReveal';
function RevealBlock({ title }) {
const { domRef, fadeInStyle } = useScrollToReveal();
return (
<div
{/* Assign the domRef from useScrollToReveal hook, allow the hook know which component to observe */}
ref={domRef}
style={{
...fadeInStyle,
height: '300px',
fontSize: '1.25rem',
backgroundColor: '#FCD9B8',
color: '#222',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginBottom: '72px',
}}
>
{title}
</div>
);
}
function ScrollToRevealExample() {
return (
<>
<RevealBlock title="Title 1" />
<RevealBlock title="Title 2" />
<RevealBlock title="Title 3" />
<RevealBlock title="Title 4" />
</>
);
}
export default ScrollToRevealExample;