Package Exports
- @opuu/inview
Readme
InView
A lightweight JavaScript library for detecting when elements enter or exit the viewport.
Installation
npm install @opuu/inviewQuick Start
import InView from "@opuu/inview";
const observer = new InView(".my-element");
observer.on("enter", (event) => {
console.log("Element visible:", event.percentage + "%");
});
observer.on("exit", (event) => {
console.log("Element hidden");
});Common Examples
Lazy Loading Images
import InView from "@opuu/inview";
const observer = new InView(".lazy-image");
observer.on("enter", (event) => {
const img = event.target;
img.src = img.dataset.src;
img.classList.add("loaded");
});Scroll Animations
import InView from "@opuu/inview";
const observer = new InView(".animate-on-scroll");
observer.on("enter", (event) => {
event.target.classList.add("animate");
});
observer.on("exit", (event) => {
event.target.classList.remove("animate");
});Infinite Scrolling
import InView from "@opuu/inview";
const observer = new InView(".load-more-trigger");
observer.on("enter", (event) => {
loadMoreContent();
});API Reference
Configuration
You can pass options when creating an InView instance:
const observer = new InView({
selector: ".my-element",
delay: 100, // Debounce delay in ms
precision: "high", // "low", "medium", or "high"
single: true, // Only observe first element
});| Option | Default | Description |
|---|---|---|
selector |
required | CSS selector for elements to observe |
delay |
0 |
Debounce delay in milliseconds |
precision |
"medium" |
Observation precision level |
single |
false |
Only observe the first matching element |
Methods
observer.on("enter", callback); // Element enters viewport
observer.on("exit", callback); // Element exits viewport
observer.pause(); // Pause observation
observer.resume(); // Resume observation
observer.setDelay(100); // Update debounce delay
observer.destroy(); // Clean upEvent Object
Callbacks receive an event object with:
{
percentage: 75, // Visibility percentage (0-100)
target: Element, // The observed element
time: 1234567890, // Timestamp
event: "enter" | "exit" // Event type
// ... other properties
}CDN Usage
<script type="module">
import InView from "https://cdn.jsdelivr.net/npm/@opuu/inview/dist/inview.js";
</script>License
MIT
Common Use Cases
Lazy Loading Images
import InView from "@opuu/inview";
const imageObserver = new InView(".lazy-image");
imageObserver.on("enter", (event) => {
const img = event.target;
if (img.dataset.src) {
img.src = img.dataset.src;
img.removeAttribute("data-src");
img.classList.add("loaded");
}
});Scroll-Triggered Animations
import InView from "@opuu/inview";
const animationObserver = new InView({
selector: ".animate-on-scroll",
precision: "medium",
});
animationObserver.on("enter", (event) => {
if (event.percentage > 50) {
// Trigger when 50% visible
event.target.classList.add("animate-in");
}
});
animationObserver.on("exit", (event) => {
event.target.classList.remove("animate-in");
});Infinite Scrolling
import InView from "@opuu/inview";
const infiniteObserver = new InView({
selector: ".load-more-trigger",
single: true,
delay: 200, // Debounce to prevent multiple rapid loads
});
infiniteObserver.on("enter", async (event) => {
try {
const newContent = await loadMoreContent();
document.getElementById("content").appendChild(newContent);
} catch (error) {
console.error("Failed to load content:", error);
}
});Performance Monitoring
import InView from "@opuu/inview";
const performanceObserver = new InView({
selector: ".track-visibility",
delay: 300, // Debounce analytics calls
});
performanceObserver.on("enter", (event) => {
// Track when important content becomes visible
analytics.track("element_viewed", {
element_id: event.target.id,
visibility_percentage: event.percentage,
timestamp: event.time,
});
});Framework Integration
React
import { useEffect, useRef } from "react";
import InView from "@opuu/inview";
function LazyImage({ src, alt }) {
const imgRef = useRef(null);
useEffect(() => {
const observer = new InView({
selector: imgRef.current,
single: true,
});
observer.on("enter", (event) => {
event.target.src = src;
event.target.classList.add("loaded");
});
return () => observer.destroy();
}, [src]);
return <img ref={imgRef} alt={alt} className="lazy-image" />;
}Vue.js
For Vue.js applications, use the dedicated @opuu/inview-vue package which provides v-inview and v-outview directives.
npm install @opuu/inview-vueAngular
import { Component, ElementRef, OnInit, OnDestroy } from "@angular/core";
import InView from "@opuu/inview";
@Component({
selector: "app-lazy-content",
template: '<div class="lazy-content">Content</div>',
})
export class LazyContentComponent implements OnInit, OnDestroy {
private observer: InView;
constructor(private elementRef: ElementRef) {}
ngOnInit() {
this.observer = new InView({
selector: this.elementRef.nativeElement,
single: true,
});
this.observer.on("enter", (event) => {
event.target.classList.add("visible");
});
}
ngOnDestroy() {
this.observer?.destroy();
}
}Best Practices
Performance Optimization
- Use appropriate precision levels: Start with "medium" and only use "high" when necessary
- Clean up observers: Always call
destroy()when components unmount - Debounce rapid changes: Use the
delayoption for expensive operations - Single element optimization: Use
single: truewhen observing only one element
Memory Management
// Good: Clean up when done
const observer = new InView(".my-element");
// ... use observer
observer.destroy(); // Important!
// Good: Store reference for cleanup
class MyComponent {
constructor() {
this.observer = new InView(".element");
}
destroy() {
this.observer.destroy();
}
}Browser Support
InView is built on the Intersection Observer API and supports all modern browsers:
- Chrome 51+
- Firefox 55+
- Safari 12.1+
- Edge 15+
For older browser support, consider using an Intersection Observer polyfill.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
License
MIT License - feel free to use this project in your commercial and personal projects.
Author
Obaydur Rahman
Related Projects
- @opuu/inview-vue - Vue.js directives for InView