Yevhen Klymentiev
dark
light
console
darkness
y.klymentiev@gmail.com
Reusable Snippets|Practical utility code for everyday use — custom-built and ready to share

supportsIO

Checks if the current environment supports IntersectionObserver.

TypeScript
Copied!
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 verifying IntersectionObserverEntry and intersectionRatio 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

TypeScript
Copied!
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.

Codebase: Utilities -> Platforms -> supportsIO | Yevhen Klymentiev