Example 1 · Scroll Detection
Use Case: Detect when elements enter or leave the viewport using the IntersectionObserver API.
Hint: Scroll down inside the box to see the observable element appear!
â Scroll down â
â Keep scrolling â
Observable Element
I'm {{ isVisible ? 'VISIBLE' : 'NOT VISIBLE' }}
{{ isVisible ? 'â Visible' : 'â Not Visible' }}
â Keep scrolling â
End of scroll area
Is Visible
{{ isVisible }}
Intersection Ratio
{{ (intersectionRatio * 100).toFixed(1) }}%
Is Intersecting
{{ isIntersecting }}
Intersection Count
{{ intersectionCount }}
// Intersection observer with the v-intersection directive <div v-intersection="onIntersection" class="observable-box">...</div> methods: { onIntersection(entries, $ctx) { const entry = entries[0]; // Is the element intersecting with the viewport? this.isVisible = entry.isIntersecting; this.intersectionRatio = entry.intersectionRatio; console.log('Element:', $ctx.element); } }
Example 2 · Custom Threshold
Use Case: Configure IntersectionObserver with custom options using the :options.intersection attribute.
Hint: This example triggers when 50% of the element is visible!
â Scroll to 50% visibility â
50% Threshold Observer
Triggers at {{ observerOptions.threshold * 100 }}% visibility
{{ isThresholdVisible ? 'â 50% Visible' : 'â Less than 50%' }}
End of scroll area
// Custom threshold with :options.intersection <div v-intersection="onThresholdIntersection" :options.intersection="observerOptions">...</div> data() { return { observerOptions: { threshold: 0.5, rootMargin: '0px' } }; }, methods: { onThresholdIntersection(entries, $ctx) { this.isThresholdVisible = entries[0].isIntersecting; } }
Key Features
- IntersectionObserver API: native browser API for efficient visibility detection
- Custom Options: configure
threshold/rootMarginvia:options.intersectionor:options - Context Parameter: access element, VNode, and userData via
$ctx - Automatic Cleanup: the observer is disconnected during the destroy phase
- Performance: more efficient than scroll event listeners
// Handler signature onIntersection(entries, $ctx) { // entries[0].isIntersecting - true if visible // entries[0].intersectionRatio - 0.0 to 1.0 // entries[0].boundingClientRect - element position // $ctx.element / $ctx.vnode / $ctx.userData } // Options format (IntersectionObserverInit) { root: null, // viewport or ancestor element rootMargin: '0px', // margin around root threshold: 0.5 // 0.0 to 1.0, or an array of thresholds }