Docs

19.3-Intersection-Observer

19.3 Intersection Observer

Overview

IntersectionObserver efficiently tracks when elements enter or exit the viewport or another element's visible area.

How Intersection Observer Works

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                    Intersection Observer                                │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│                                                                         │
│  Viewport (Root)                                                        │
│  ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”         │
│  │                                                           │         │
│  │   ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”                                             │         │
│  │   │ Element │ ← intersectionRatio: 1.0 (fully visible)   │         │
│  │   ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜                                             │         │
│  │                                                           │         │
│  ā”œ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│         │
│  │   ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”                                             │         │
│  │   │ Element │ ← intersectionRatio: 0.5 (half visible)    │         │
│  ā””ā”€ā”€ā”€ā”‚ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”‚ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜         │
│      │         │                                                        │
│      ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ← intersectionRatio: 0 (outside viewport)             │
│                                                                         │
│      ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”                                                        │
│      │ Element │ ← Not yet observed (outside)                          │
│      ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜                                                        │
│                                                                         │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Configuration Options

OptionTypeDefaultDescription
rootElement/nullnull (viewport)Container to check intersection against
rootMarginstring"0px"Margin around root (like CSS margin)
thresholdnumber/number[]0Intersection ratios to trigger callback

IntersectionObserverEntry Properties

PropertyDescription
boundingClientRectTarget's bounding box
intersectionRatioRatio of intersection (0-1)
intersectionRectArea of intersection
isIntersectingWhether target is intersecting
rootBoundsRoot's bounding box
targetThe observed element
timeTimestamp of intersection

Threshold Examples

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│  threshold: [0]           → Callback when ANY part enters/exits        │
│  threshold: [0.5]         → Callback when 50% visible                  │
│  threshold: [1.0]         → Callback when 100% visible                 │
│  threshold: [0, 0.5, 1.0] → Callback at 0%, 50%, and 100%             │
│  threshold: [0.25, 0.5, 0.75, 1.0] → Fine-grained tracking            │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Basic Usage

// Create observer
const observer = new IntersectionObserver(
  (entries) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        console.log('Element visible:', entry.target);
        console.log('Visibility:', entry.intersectionRatio);
      }
    });
  },
  {
    root: null, // viewport
    rootMargin: '0px',
    threshold: 0.5, // 50% visible
  }
);

// Observe elements
observer.observe(element);

// Stop observing
observer.unobserve(element);
observer.disconnect();

Common Use Cases

  • •Lazy Loading: Load images/content when near viewport
  • •Infinite Scroll: Load more content at page bottom
  • •Analytics: Track which content users actually see
  • •Animations: Trigger animations on scroll
  • •Ad Viewability: Track if ads are actually seen

Summary

  • •More performant than scroll event listeners
  • •Asynchronous and non-blocking
  • •Can observe multiple elements efficiently
  • •Use rootMargin for preloading content
  • •Multiple thresholds for fine-grained control
.3 Intersection Observer - JavaScript Tutorial | DeepML