How to Create Intersection Observer Action in Svelte
In Svelte, create an
intersection observer action by defining a function that sets up an IntersectionObserver on an element and returns a cleanup function. Use this action in your component by adding use:yourAction to the element you want to observe.Syntax
An intersection observer action in Svelte is a function that receives a DOM element and optionally parameters. It sets up an IntersectionObserver on the element and returns an object with a destroy method to clean up when the element is removed.
The action is used in markup with use:actionName.
javascript
function intersectionObserver(node, options) { const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { node.dispatchEvent(new CustomEvent('enter')); } else { node.dispatchEvent(new CustomEvent('leave')); } }); }, options); observer.observe(node); return { destroy() { observer.unobserve(node); observer.disconnect(); } }; }
Example
This example shows a Svelte component using the intersection observer action to detect when a box enters or leaves the viewport. It changes the text accordingly.
svelte
<script> function intersectionObserver(node, options) { const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { node.dispatchEvent(new CustomEvent('enter')); } else { node.dispatchEvent(new CustomEvent('leave')); } }); }, options); observer.observe(node); return { destroy() { observer.unobserve(node); observer.disconnect(); } }; } let status = 'Scroll to see me'; function handleEnter() { status = 'Box is visible!'; } function handleLeave() { status = 'Box is not visible'; } </script> <style> .spacer { height: 150vh; } .box { width: 200px; height: 200px; background-color: lightcoral; margin: 0 auto; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 1.2rem; } </style> <div class="spacer"></div> <div class="box" use:intersectionObserver on:enter={handleEnter} on:leave={handleLeave} > {status} </div> <div class="spacer"></div>
Output
A red box centered vertically with text that changes between 'Scroll to see me', 'Box is visible!', and 'Box is not visible' as you scroll the page.
Common Pitfalls
- Not returning a
destroymethod causes observers to stay active and leak memory. - Forgetting to observe the node with
observer.observe(node)means no events fire. - Not handling the
entriesarray properly can cause missed intersection events. - Passing incorrect options to
IntersectionObservercan lead to unexpected behavior.
javascript
/* Wrong: Missing destroy cleanup */ function badObserver(node) { const observer = new IntersectionObserver(() => {}); observer.observe(node); // No destroy method returned } /* Right: Proper cleanup */ function goodObserver(node) { const observer = new IntersectionObserver(() => {}); observer.observe(node); return { destroy() { observer.unobserve(node); observer.disconnect(); } }; }
Quick Reference
Use this checklist when creating an intersection observer action in Svelte:
- Define a function receiving
nodeand optionaloptions. - Create an
IntersectionObserverwith a callback. - Call
observer.observe(node)to start observing. - Dispatch custom events like
enterandleaveon intersection changes. - Return an object with a
destroymethod to unobserve the node. - Use the action in markup with
use:actionName.
Key Takeaways
Create a Svelte action function that sets up an IntersectionObserver on the given element.
Always return a destroy method to clean up the observer when the element is removed.
Use custom events dispatched from the observer callback to react to visibility changes.
Attach the action to elements with the use: directive in your Svelte markup.
Test intersection options carefully to match your visibility detection needs.