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

runOnDocumentReady

Runs the provided function once the DOM is fully loaded.

TypeScript
Copied!
1/**
2 * Runs the provided function once the DOM is fully loaded.
3 *
4 * @param callback - The function to run when the document is ready.
5 */
6export function runOnDocumentReady(callback: () => void): void {
7  if (
8    document.readyState === 'complete' || document.readyState === 'interactive'
9  ) {
10    callback();
11  } else {
12    document.addEventListener('DOMContentLoaded', callback, { once: true });
13  }
14}
  • Simplified DOM Readiness Handling

    Eliminates the need to manually check document.readyState or wire up event listeners every time.

  • Supports All Loading States

    Works seamlessly whether the script is executed before or after the DOM has loaded.

  • Avoids Redundant Calls

    Uses the { once: true } option to ensure the callback is invoked only once, preventing unexpected side effects.

  • Zero Dependencies

    A lightweight utility that avoids jQuery or other DOM libraries while providing similar convenience.

Tests | Examples

TypeScript
Copied!
1let originalReadyState: PropertyDescriptor | undefined;
2
3beforeEach(() => {
4  originalReadyState = Object.getOwnPropertyDescriptor(document, 'readyState');
5});
6
7afterEach(() => {
8  if (originalReadyState) {
9    Object.defineProperty(document, 'readyState', originalReadyState);
10  }
11});
12
13test('executes immediately if document is already "complete"', () => {
14  Object.defineProperty(document, 'readyState', {
15    configurable: true,
16    get: () => 'complete',
17  });
18
19  const mockFn = jest.fn();
20  runOnDocumentReady(mockFn);
21
22  expect(mockFn).toHaveBeenCalledTimes(1);
23});
24
25test('executes immediately if document is already "interactive"', () => {
26  Object.defineProperty(document, 'readyState', {
27    configurable: true,
28    get: () => 'interactive',
29  });
30
31  const mockFn = jest.fn();
32  runOnDocumentReady(mockFn);
33
34  expect(mockFn).toHaveBeenCalledTimes(1);
35});
36
37test('adds DOMContentLoaded listener if document is "loading"', () => {
38  Object.defineProperty(document, 'readyState', {
39    configurable: true,
40    get: () => 'loading',
41  });
42
43  const mockFn = jest.fn();
44  runOnDocumentReady(mockFn);
45
46  document.dispatchEvent(new Event('DOMContentLoaded'));
47
48  expect(mockFn).toHaveBeenCalledTimes(1);
49});

Common Use Cases

  • Initializing UI Components

    Run setup logic for widgets, tooltips, carousels, or modals after the DOM is ready.

  • DOM Query and Manipulation

    Safely access and modify elements without risking null references.

  • Analytics and Tracking Scripts

    Start tracking page interactions or impressions only after DOM is available.

  • Polyfill or Fallback Injection

    Apply compatibility fixes or style patches once the base layout is guaranteed to be in place.

Codebase: Utilities -> Browser & DOM -> runOnDocumentReady | Yevhen Klymentiev