-
Notifications
You must be signed in to change notification settings - Fork 183
/
Iframe.tsx
69 lines (61 loc) · 1.53 KB
/
Iframe.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import React, {
useState,
useEffect,
useRef,
AllHTMLAttributes,
MutableRefObject
} from 'react';
import { useIntersection } from 'react-use';
interface IframeProps extends AllHTMLAttributes<HTMLIFrameElement> {
src: string;
intersectionRootRef: MutableRefObject<Element | null>;
}
export default function Iframe({
intersectionRootRef,
style,
src,
...restProps
}: IframeProps) {
const [loaded, setLoaded] = useState(false);
const [renderedSrc, setRenderedSrc] = useState<string | null>(null);
const iframeRef = useRef<HTMLIFrameElement | null>(null);
const intersection = useIntersection(iframeRef, {
root: intersectionRootRef.current,
rootMargin: '800px',
threshold: 0
});
const intersectionRatio = intersection?.intersectionRatio ?? null;
useEffect(() => {
if (intersectionRatio === null) {
return;
}
if (intersectionRatio > 0 && src !== renderedSrc) {
setRenderedSrc(src);
}
}, [intersectionRatio, src, renderedSrc]);
useEffect(() => {
if (renderedSrc !== null) {
const location = iframeRef.current?.contentWindow?.location;
if (location) {
location.replace(renderedSrc);
}
}
}, [renderedSrc]);
return (
<iframe
ref={iframeRef}
onLoad={() => setLoaded(true)}
onMouseEnter={() => {
if (src !== renderedSrc) {
setRenderedSrc(src);
}
}}
style={{
...style,
transition: 'opacity .3s ease',
opacity: loaded ? 1 : 0
}}
{...restProps}
/>
);
}