Suggest an editImprove this articleRefine the answer for “What does IntersectionObserver do?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`IntersectionObserver`** is a powerful built-in browser API that lets you track when an element enters or leaves the viewport, without heavy `scroll` handlers. **Key point:** it works asynchronously and efficiently, replacing manual `getBoundingClientRect()` checks and expensive `onscroll` handlers.Shown above the full answer for quick recall.Answer (EN)Image`IntersectionObserver` is a powerful built-in browser API that lets you **track when an element enters the viewport** or leaves it, without heavy `scroll` handlers. --- ## A simple definition > `IntersectionObserver` is an object that "watches" an element and reports > when it **intersects with the viewport** (or with another container). It's a great alternative to: - `scroll` events, - manual `getBoundingClientRect()` checks, - or `window.onscroll` handlers, which put a heavy load on the page. --- ## 1. A simple example ```javascript <div style="height: 120vh;"></div> <div id="target" style="height: 100px; background: coral;">I'm the target</div> <div style="height: 120vh;"></div> <script> const target = document.querySelector('#target'); const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { console.log('The element entered the viewport!'); } else { console.log('The element left the viewport!'); } }); }); observer.observe(target); // start observing </script> ``` When you scroll the page and the block enters the screen, the console prints: ```javascript The element entered the viewport! ``` --- ## 2. Constructor parameters ```javascript new IntersectionObserver(callback, options); ``` | Parameter | What it does | |---|---| | `callback` | The function called on every intersection change | | `options.root` | The container to observe inside (defaults to the browser viewport) | | `options.rootMargin` | Margins (for example `'0px 0px -100px 0px'`), like CSS `margin` | | `options.threshold` | The trigger threshold: the fraction of the element visible (from 0 to 1) | --- ### Example with options: ```javascript const observer = new IntersectionObserver(callback, { root: null, // the browser viewport rootMargin: '0px 0px -100px 0px', // fires a bit earlier threshold: 0.5 // when 50% of the element is visible }); ``` --- ## 3. The `entry` object in the callback Each element being observed is represented by an `IntersectionObserverEntry` object: ```javascript entry.isIntersecting // true / false entry.intersectionRatio // the visible fraction (0-1) entry.boundingClientRect // the element's position entry.rootBounds // the viewport's bounds entry.target // the element itself ``` --- ## 4. Example: fading elements into view ```javascript const items = document.querySelectorAll('.fade'); const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('visible'); } }); }); items.forEach(item => observer.observe(item)); ``` ```javascript .fade { opacity: 0; transform: translateY(20px); transition: 0.5s; } .fade.visible { opacity: 1; transform: translateY(0); } ``` Elements smoothly "fade in" as they enter the screen. --- ## 5. Example: **lazy loading images** ```javascript <img data-src="photo.jpg" alt="photo" width="400" height="300" /> ``` ```javascript const images = document.querySelectorAll('img[data-src]'); const observer = new IntersectionObserver((entries, obs) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src; obs.unobserve(img); // stop watching this image } }); }); images.forEach(img => observer.observe(img)); ``` Now images load **only once they become visible**, which saves bandwidth and speeds up the site's loading. --- ## 6. Advantages over `scroll` handlers | Regular scroll | IntersectionObserver | |---|---| | Fires an event on **every pixel** | Runs asynchronously and efficiently | | You have to manually compute `getBoundingClientRect()` | It does everything itself | | CPU load | Almost no load | | Inconvenient with many elements | An observer can watch hundreds of elements | --- ## 7. Stopping observation To stop watching an element: ```javascript observer.unobserve(target); ``` To disconnect completely: ```javascript observer.disconnect(); ``` --- ## Summary | What it does | `IntersectionObserver` | |---|---| | Tracks | When an element enters or leaves the viewport | | Replaces | `onscroll` and `getBoundingClientRect()` | | Used for | Lazy loading, scroll animations, ad tracking, analytics | | Performance | Very high (runs off the main JS thread) | --- > **A simple way to remember it:** > `IntersectionObserver` is a "visibility watcher". > It reports when an element appears on the screen, > and it does so efficiently, without excess `scroll` events.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.