@opuu/inview
| Install | |
|---|---|
npm install @opuu/inview |
|
| Latest Version: | 2.3.1 |
| Older releases: | 3 |
| License: | MIT |
| Last Updated: | Aug 4, 2025 |
| Links: | GitHub · npm |
InView
A lightweight JavaScript library for detecting when elements enter or exit the viewport.
Installation
npm install @opuu/inview
Quick 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 up
Event 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-vue
Angular
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
Related Packages
Vue.js directives for viewport detection - v-inview and v-outview directives pow...
Extremely lightweight (~2.7 KB gzipped), zero-dependency toast notification libr...
Scroll-driven animation for the web — draw SVG paths, reveal elements, pin secti...
Simple, privacy-focused analytics SDK for internal tools and applications. Track...
Trigger functions and events based on an element's position on screen — a tiny,...
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 2.3.1 | MIT | ||
| 2.3.0 | MIT | ||
| 2.2.1 | MIT | ||
| 2.2.0 | MIT | ||
| 2.1.0 | ^3.5.13 | MIT | |
| 2.0.1 | MIT | ||
| 2.0.0 | MIT | ||
| 1.1.0 | MIT | ||
| 1.0.2 | MIT | ||
| 1.0.1 | MIT | ||
| 1.0.0 | MIT |
Pre-releases (2)
| Version | Released | Vue | License |
|---|---|---|---|
| 2.1.0-beta.3 | ^3.5.13 | MIT | |
| 2.1.0-beta.2 | ^3.5.13 | MIT |