Now.js Framework Documentation
ScrollManager
ScrollManager
Overview
ScrollManager is the scroll behavior management system in Now.js Framework. It supports smooth scrolling, waypoints, scroll tracking, and infinite scroll.
When to use:
- Need smooth scroll to element
- Need scroll waypoints/triggers
- Need infinite scroll
- Need scroll restoration
- Need scroll navigation
Why use it:
- ✅ Smooth scrolling with easing
- ✅ Waypoints and triggers
- ✅ Infinite scroll support
- ✅ Scroll position persistence
- ✅ Mobile touch support
- ✅ Accessibility features
Basic Usage
Initialization
await ScrollManager.init({
enabled: true,
smoothScroll: {
enabled: true,
selector: 'a[href^="#"]'
}
});Smooth Scroll to Element
// Scroll to element
await ScrollManager.scrollTo('#section-2');
// With options
await ScrollManager.scrollTo('#contact', {
offset: -100, // Offset from top
duration: 800, // Animation duration
easing: 'easeInOutCubic'
});Scroll to Position
// Scroll to top
await ScrollManager.scrollToTop();
// Scroll to bottom
await ScrollManager.scrollToBottom();
// Scroll to specific position
await ScrollManager.scrollTo(500); // 500px from topConfiguration
await ScrollManager.init({
enabled: true,
core: {
offset: 0, // Global offset
duration: 500, // Default animation duration
easing: 'easeInOutCubic'
},
smoothScroll: {
enabled: true,
selector: 'a[href^="#"]',
excludeSelector: '.no-smooth',
hashChangeEnabled: true
},
waypoints: {
enabled: true,
threshold: 0.5, // Visibility threshold
offset: '0px'
},
infiniteScroll: {
enabled: false,
threshold: 0.9
},
persistence: {
enabled: true,
key: 'scroll_positions'
},
mobile: {
enabled: true,
touchAction: 'pan-y',
momentumScroll: true
}
});API Reference
ScrollManager.scrollTo(target, options)
Scroll to target
| Parameter | Type | Description |
|---|---|---|
target |
string/number/HTMLElement | Selector, position, or element |
options.offset |
number | Offset from target (px) |
options.duration |
number | Animation duration (ms) |
options.easing |
string | Easing function |
options.onComplete |
function | Callback on complete |
Returns: Promise<void>
await ScrollManager.scrollTo('#features', {
offset: -80,
duration: 600
});ScrollManager.scrollToTop(options)
Scroll to top
await ScrollManager.scrollToTop({ duration: 500 });ScrollManager.scrollToBottom(options)
Scroll to bottom
await ScrollManager.scrollToBottom();ScrollManager.scrollToContent(options)
Scroll to main content
await ScrollManager.scrollToContent();ScrollManager.getScrollPosition()
Get current position
Returns: Object - { x, y, direction }
const pos = ScrollManager.getScrollPosition();
console.log(`Scroll Y: ${pos.y}`);ScrollManager.addWaypoint(id, element, options)
Add waypoint
| Parameter | Type | Description |
|---|---|---|
id |
string | Waypoint ID |
element |
HTMLElement | Element to watch |
options.onEnter |
function | Callback when entering viewport |
options.onLeave |
function | Callback when leaving viewport |
options.threshold |
number | Visibility threshold (0-1) |
ScrollManager.addWaypoint('section-1', document.getElementById('section-1'), {
onEnter: () => console.log('Section 1 visible'),
onLeave: () => console.log('Section 1 hidden'),
threshold: 0.5
});ScrollManager.removeWaypoint(id)
Remove waypoint
ScrollManager.removeWaypoint('section-1');ScrollManager.cancelScroll()
Cancel current animation
ScrollManager.cancelScroll();Easing Functions
| Easing | Description |
|---|---|
linear |
Constant speed |
easeInOutCubic |
Smooth start and end |
easeOutQuart |
Fast start, slow end |
easeInQuad |
Slow start, fast end |
easeOutBack |
Overshoot and settle |
Events
| Event | When Triggered | Detail |
|---|---|---|
scroll:start |
Scroll animation starts | {target} |
scroll:end |
Scroll animation ends | {position} |
scroll:progress |
During scroll | {progress} |
waypoint:enter |
Element enters viewport | {id, element} |
waypoint:leave |
Element leaves viewport | {id, element} |
EventManager.on('waypoint:enter', (data) => {
console.log(`${data.id} is now visible`);
});Real-World Examples
Smooth Anchor Links
<nav>
<a href="#home">Home</a>
<a href="#features">Features</a>
<a href="#pricing">Pricing</a>
<a href="#contact">Contact</a>
</nav>
<section id="home">...</section>
<section id="features">...</section>
<section id="pricing">...</section>
<section id="contact">...</section>
<script>
await ScrollManager.init({
enabled: true,
smoothScroll: {
enabled: true,
selector: 'a[href^="#"]'
}
});
</script>Back to Top Button
<button id="back-to-top" class="hidden">↑</button>
<script>
const button = document.getElementById('back-to-top');
// Show/hide based on scroll position
window.addEventListener('scroll', () => {
button.classList.toggle('hidden', window.scrollY < 300);
});
button.addEventListener('click', () => {
ScrollManager.scrollToTop({ duration: 400 });
});
</script>Active Section Highlighting
const sections = document.querySelectorAll('section[id]');
const navLinks = document.querySelectorAll('nav a');
sections.forEach(section => {
ScrollManager.addWaypoint(section.id, section, {
threshold: 0.3,
onEnter: () => {
navLinks.forEach(link => {
link.classList.toggle('active',
link.getAttribute('href') === `#${section.id}`
);
});
}
});
});Lazy Load Images
const images = document.querySelectorAll('img[data-src]');
images.forEach((img, index) => {
ScrollManager.addWaypoint(`lazy-${index}`, img, {
threshold: 0.1,
onEnter: () => {
img.src = img.dataset.src;
img.removeAttribute('data-src');
ScrollManager.removeWaypoint(`lazy-${index}`);
}
});
});Common Pitfalls
⚠️ 1. Wait for Init
// ❌ Using before init
ScrollManager.scrollTo('#section');
// ✅ Wait for init
await ScrollManager.init({ enabled: true });
ScrollManager.scrollTo('#section');⚠️ 2. Offset for Fixed Header
// ❌ Not accounting for header
ScrollManager.scrollTo('#content');
// ✅ Add offset
const headerHeight = document.querySelector('header').offsetHeight;
ScrollManager.scrollTo('#content', {
offset: -headerHeight
});Related Documentation
- AnimationManager - Animations
- RouterManager - SPA routing