supportsIO
Checks if the current environment supports IntersectionObserver.
1/**
2 * Checks if the current environment supports IntersectionObserver.
3 *
4 * @returns True if supported, false otherwise.
5 */
6export function supportsIO(): boolean {
7 return typeof window !== 'undefined' &&
8 'IntersectionObserver' in window &&
9 'IntersectionObserverEntry' in window &&
10 'intersectionRatio' in IntersectionObserverEntry.prototype;
11}
Comprehensive Capability Check
Goes beyond basic
'IntersectionObserver' in window
by also verifyingIntersectionObserverEntry
andintersectionRatio
support for broader reliability.Environment-Safe
Includes a
typeof window !== 'undefined'
guard to ensure safe usage in server-side or non-browser environments.Zero Dependencies
Lightweight implementation that avoids external polyfills or helper libraries.
Useful for Feature Gating
Enables graceful fallback logic or conditional polyfill loading in environments lacking IntersectionObserver support.
Tests | Examples
1const originalWindow = globalThis.window;
2
3afterEach(() => {
4 globalThis.window = originalWindow;
5});
6
7test('returns true if IntersectionObserver is supported', () => {
8 globalThis.window = {
9 IntersectionObserver: function () {},
10 IntersectionObserverEntry: function () {},
11 } as any;
12 (globalThis.window.IntersectionObserverEntry.prototype as any) = {
13 intersectionRatio: 0,
14 };
15
16 expect(supportsIO()).toBe(true);
17});
18
19test('returns false if IntersectionObserver is missing', () => {
20 globalThis.window = {
21 IntersectionObserverEntry: function () {},
22 } as any;
23 (globalThis.window.IntersectionObserverEntry.prototype as any) = {
24 intersectionRatio: 0,
25 };
26
27 expect(supportsIO()).toBe(false);
28});
29
30test('returns false if IntersectionObserverEntry is missing', () => {
31 globalThis.window = {
32 IntersectionObserver: function () {},
33 } as any;
34
35 expect(supportsIO()).toBe(false);
36});
37
38test('returns false if not in a browser environment', () => {
39 // @ts-expect-error
40 delete globalThis.window;
41 expect(supportsIO()).toBe(false);
42});
Common Use Cases
Lazy-Loading Content or Images
Detect if IntersectionObserver can be used to implement scroll-triggered loading strategies.
Scroll-Based Animations
Validate support before initializing in-view animations to avoid runtime errors.
Analytics and Visibility Tracking
Confirm feature availability for tracking when elements enter or exit the viewport.
Progressive Enhancement
Conditionally enhance features like infinite scroll or sticky elements in browsers with full IntersectionObserver support.