Now.js Framework Documentation

Now.js Framework Documentation

ScrollManager

EN 27 Nov 2025 14:16

ScrollManager

Overview

ScrollManager is a comprehensive and modern scrolling management system designed to provide smooth scrolling experiences with support for animations, waypoints, parallax effects, infinite scroll, and other advanced features.

Key Features:

  • Customizable smooth scrolling
  • Waypoints and Intersection Observer
  • Scroll restoration (remembers position on back navigation)
  • Mobile support (touch events)
  • Accessibility features (ARIA, keyboard navigation)
  • Performance optimization (throttle, debounce, RAF)
  • Parallax effects
  • Infinite scroll
  • Scroll progress indicator
  • Section highlighting
  • Multiple animation easing functions

Installation and Import

ScrollManager is loaded with the Now.js Framework and is ready to use immediately via the window object:

// No import needed - ready to use immediately
console.log(window.ScrollManager); // ScrollManager object

Configuration

Main Configuration Options

Option Type Default Description
enabled Boolean false Enable/disable ScrollManager
core.offset Number 0 Offset from top (px)
core.duration Number 500 Animation duration (ms)
core.easing String "easeInOutCubic" Easing function

Advanced Configuration

Animation Options

animation: {
  enabled: true,
  types: {
    linear: t => t,
    easeInOutCubic: t => ...,
    easeOutQuart: t => ...,
    easeInQuad: t => t * t
  }
}

Performance Options

performance: {
  throttle: 16,          // ms for throttle scroll events
  debounce: 100,         // ms for debounce
  passive: true,         // use passive event listeners
  observer: true,        // use IntersectionObserver
  requestAnimationFrame: {
    enabled: true,
    maxFPS: 60,
    skipThreshold: 16
  },
  batchSize: 5,
  maxQueue: 100
}

Restoration Options

restoration: {
  enabled: true,
  key: 'scroll_positions',
  ttl: 24 * 60 * 60 * 1000  // 24 hours
}

Mobile Options

mobile: {
  enabled: true,
  touchAction: 'pan-y',
  momentumScroll: true,
  pullToRefresh: false,
  touchThreshold: 5
}

Accessibility Options

accessibility: {
  enabled: true,
  announceChanges: true,
  smoothFocus: true,
  ariaLabels: true,
  focusableSelectors: '...'
}

Waypoints Options

waypoints: {
  offset: 0,
  threshold: 0.5,
  once: false,
  delay: 100
}

Scroll Features

scroll: {
  infinite: {
    enabled: false,
    threshold: 100,
    loadMore: null
  },
  parallax: {
    enabled: false,
    speed: 0.5
  },
  progress: {
    enabled: false,
    color: 'var(--color-primary)',
    height: '3px',
    zIndex: 1000
  },
  snap: {
    enabled: false,
    type: 'y',
    stop: true,
    align: 'start'
  },
  section: {
    highlight: true,
    threshold: 0.5,
    activeClass: 'active'
  },
  nav: {
    updateHash: true,
    highlightClass: 'active',
    smoothScroll: true
  }
}

Smooth Scroll Options

smoothScroll: {
  enabled: false,
  autoScroll: false,
  selector: 'a[href^="#"]',
  excludeSelector: '.no-smooth',
  hashChangeEnabled: true
}

Initialization

// Auto-initialize (requires enabled: true)
ScrollManager.init({
  enabled: true
});

// Initialize with custom config
ScrollManager.init({
  enabled: true,
  core: {
    offset: 80,  // for fixed header
    duration: 600
  },
  smoothScroll: {
    enabled: true,
    selector: 'a[href^="#"]'
  },
  waypoints: {
    threshold: 0.7,
    once: false
  },
  performance: {
    throttle: 16,
    debounce: 150
  }
});

Methods

init(options)

Initialize ScrollManager

Parameters:

  • options (Object, optional): Configuration options

Returns: Promise<ScrollManager>

Example:

await ScrollManager.init({
  enabled: true,
  core: { offset: 100, duration: 600 },
  smoothScroll: { enabled: true }
});

scrollTo(target, options)

Scroll to specified element or selector

Parameters:

  • target (String|HTMLElement): CSS selector or element
  • options (Object, optional): Scroll options
    • offset (Number): Offset from top
    • duration (Number): Animation duration
    • easing (String): Easing function name
    • focus (Boolean): Focus element after scroll (default: true)

Returns: Promise<void>

Example:

// Scroll to element
await ScrollManager.scrollTo('#section-about');

// Scroll with options
await ScrollManager.scrollTo('#contact', {
  offset: 100,
  duration: 1000,
  easing: 'easeOutQuart'
});

// Scroll using element directly
const element = document.querySelector('.target');
await ScrollManager.scrollTo(element, {
  offset: 80
});

scrollToTop(options)

Scroll to top of page

Parameters:

  • options (Object, optional): Scroll options

Returns: Promise<void>

Example:

await ScrollManager.scrollToTop();

// With animation
await ScrollManager.scrollToTop({
  duration: 800,
  easing: 'easeInOutCubic'
});

scrollToBottom(options)

Scroll to bottom of page

Parameters:

  • options (Object, optional): Scroll options

Returns: Promise<void>

Example:

await ScrollManager.scrollToBottom();

await ScrollManager.scrollToBottom({
  duration: 600
});

scrollToContent(options)

Scroll to main content area

Parameters:

  • options (Object, optional): Scroll options

Returns: Promise<void>

Example:

// Scroll to #main
await ScrollManager.scrollToContent();

addWaypoint(id, element, options)

Add waypoint to detect when element comes into view

Parameters:

  • id (String): Unique waypoint ID
  • element (HTMLElement): Element to track
  • options (Object, optional): Waypoint options
    • offset (Number): Offset value
    • threshold (Number): Visibility percentage (0-1)
    • once (Boolean): Trigger only once
    • callback (Function): Function to call on trigger

Returns: void

Example:

const element = document.querySelector('.animate-on-scroll');

ScrollManager.addWaypoint('my-waypoint', element, {
  threshold: 0.5,
  once: true,
  callback: (entry) => {
    console.log('Element is visible!');
    element.classList.add('animated');
  }
});

removeWaypoint(id)

Remove existing waypoint

Parameters:

  • id (String): Waypoint ID to remove

Returns: void

Example:

ScrollManager.removeWaypoint('my-waypoint');

cancelScroll()

Cancel currently active scroll

Returns: void

Example:

ScrollManager.cancelScroll();

getScrollPosition()

Get current scroll position

Returns: Object - {x, y, percentX, percentY}

Example:

const position = ScrollManager.getScrollPosition();
console.log(position);
// { x: 0, y: 500, percentX: 0, percentY: 25 }

on(event, handler)

Register event listener

Parameters:

  • event (String): Event name
  • handler (Function): Handler function

Returns: void

Example:

ScrollManager.on('scroll:complete', (data) => {
  console.log('Scrolled to:', data.element);
});

ScrollManager.on('waypoint:trigger', (data) => {
  console.log('Waypoint triggered:', data.id);
});

off(event, handler)

Remove event listener

Parameters:

  • event (String): Event name
  • handler (Function): Handler function

Returns: void

Example:

const handler = (data) => console.log(data);

ScrollManager.on('scroll:complete', handler);
// use...
ScrollManager.off('scroll:complete', handler);

emit(eventName, data)

Emit custom event

Parameters:

  • eventName (String): Event name
  • data (Any): Data to send

Returns: void

Example:

ScrollManager.emit('custom:scroll', {
  position: 100,
  target: 'section-about'
});

cleanup()

Clean up and stop all operations

Returns: void

Example:

ScrollManager.cleanup();

Events

ScrollManager emits various events that can be listened to:

Event Description Data
scroll:initialized Initialization complete -
scroll:start Scroll starts {element, options}
scroll:complete Scroll complete {element, position}
scroll:cancel Scroll canceled -
scroll:progress Scrolling (throttled) {x, y, percentX, percentY}
scroll:end Scroll ended and stopped {x, y, percentX, percentY}
scroll:direction Scroll direction changed {direction: 'up'\|'down'}
scroll:animationComplete Animation complete {startY, targetY, duration}
scroll:reveal Element revealed {element}
waypoint:trigger Waypoint triggered {id, entry}
section:active New section became active {id}
touch:move Touch move (mobile) {diffY, diffX, originalEvent}
scroll:error Error occurred {error}

Event Usage Examples:

// Listen to scroll complete
ScrollManager.on('scroll:complete', (data) => {
  console.log('Scrolled to:', data.element.id);
  console.log('Position:', data.position);
});

// Listen to scroll direction
ScrollManager.on('scroll:direction', (data) => {
  if (data.direction === 'down') {
    header.classList.add('hidden');
  } else {
    header.classList.remove('hidden');
  }
});

// Listen to waypoint
ScrollManager.on('waypoint:trigger', (data) => {
  console.log('Waypoint:', data.id);
});

// Listen to scroll progress
ScrollManager.on('scroll:progress', (position) => {
  progressBar.style.width = position.percentY + '%';
});

HTML Data Attributes

ScrollManager supports data attributes for behavior control:

Waypoints

<!-- Basic waypoint -->
<div data-scroll-waypoint="section-1">
  Content
</div>

<!-- Waypoint with offset -->
<div data-scroll-waypoint="section-2"
     data-scroll-offset="100">
  Content
</div>

<!-- Waypoint with callback -->
<div data-scroll-waypoint="section-3"
     data-scroll-callback="onSectionVisible">
  Content
</div>

Scroll Reveal

<!-- Element gets 'revealed' class when in view -->
<div data-scroll-reveal>
  Animate me!
</div>

Scroll Section

<!-- Sections that will be tracked and highlighted -->
<section id="about" data-scroll-section>
  About Us
</section>

<section id="services" data-scroll-section>
  Our Services
</section>

Scroll Navigation

<!-- Navigation links -->
<nav data-scroll-nav>
  <a href="#home">Home</a>
  <a href="#about">About</a>
  <a href="#contact">Contact</a>
</nav>

Parallax

<!-- Parallax element -->
<div data-parallax data-parallax-speed="0.5">
  Background Layer
</div>

Ignore Smooth Scroll

<!-- Don't use smooth scroll for this element -->
<a href="#skip" data-scroll-ignore>Skip smooth scroll</a>

Usage Examples

1. Basic Smooth Scrolling

// Enable smooth scrolling
ScrollManager.init({
  enabled: true,
  smoothScroll: {
    enabled: true,
    selector: 'a[href^="#"]'
  },
  core: {
    offset: 80,  // for fixed header
    duration: 600
  }
});
<nav>
  <a href="#home">Home</a>
  <a href="#about">About</a>
  <a href="#contact">Contact</a>
</nav>

<section id="home">...</section>
<section id="about">...</section>
<section id="contact">...</section>

2. Scroll-triggered Animations

await ScrollManager.init({
  enabled: true,
  waypoints: {
    threshold: 0.3,
    once: true
  }
});

// Add waypoints
document.querySelectorAll('.animate-on-scroll').forEach((el, i) => {
  ScrollManager.addWaypoint(`anim-${i}`, el, {
    threshold: 0.3,
    once: true,
    callback: (entry) => {
      el.classList.add('animated', 'fadeInUp');
    }
  });
});
<div class="animate-on-scroll">
  This will animate when scrolled into view
</div>

<div class="animate-on-scroll">
  Another animated element
</div>
.animate-on-scroll {
  opacity: 0;
  transform: translateY(50px);
  transition: all 0.6s ease;
}

.animate-on-scroll.animated {
  opacity: 1;
  transform: translateY(0);
}

3. Scroll to Top Button

ScrollManager.init({
  enabled: true,
  core: { duration: 800 }
});

const scrollTopBtn = document.querySelector('.scroll-top');

// Show button when scrolling down
ScrollManager.on('scroll:progress', (position) => {
  if (position.y > 300) {
    scrollTopBtn.classList.add('visible');
  } else {
    scrollTopBtn.classList.remove('visible');
  }
});

// Click to go to top
scrollTopBtn.addEventListener('click', () => {
  ScrollManager.scrollToTop({
    duration: 800,
    easing: 'easeOutQuart'
  });
});
<button class="scroll-top">↑</button>
.scroll-top {
  position: fixed;
  bottom: 20px;
  right: 20px;
  opacity: 0;
  visibility: hidden;
  transition: all 0.3s;
}

.scroll-top.visible {
  opacity: 1;
  visibility: visible;
}

4. Hide Header on Scroll Down

ScrollManager.init({
  enabled: true
});

const header = document.querySelector('.header');

ScrollManager.on('scroll:direction', (data) => {
  if (data.direction === 'down') {
    header.classList.add('header-hidden');
  } else {
    header.classList.remove('header-hidden');
  }
});
.header {
  position: fixed;
  top: 0;
  width: 100%;
  transition: transform 0.3s;
}

.header-hidden {
  transform: translateY(-100%);
}

5. Section Highlighting in Navigation

ScrollManager.init({
  enabled: true,
  scroll: {
    section: {
      highlight: true,
      threshold: 0.5,
      activeClass: 'active'
    },
    nav: {
      updateHash: true,
      highlightClass: 'active'
    }
  }
});

// Navigation gets active class automatically
ScrollManager.on('section:active', (data) => {
  // Update navigation
  document.querySelectorAll('[data-scroll-nav] a').forEach(link => {
    link.classList.remove('active');
  });

  const activeLink = document.querySelector(`[href="#${data.id}"]`);
  if (activeLink) {
    activeLink.classList.add('active');
  }
});
<nav data-scroll-nav>
  <a href="#section1">Section 1</a>
  <a href="#section2">Section 2</a>
  <a href="#section3">Section 3</a>
</nav>

<section id="section1" data-scroll-section>...</section>
<section id="section2" data-scroll-section>...</section>
<section id="section3" data-scroll-section>...</section>

6. Scroll Progress Bar

ScrollManager.init({
  enabled: true,
  scroll: {
    progress: {
      enabled: true,
      color: '#4CAF50',
      height: '4px',
      zIndex: 9999
    }
  }
});

// Or create custom progress bar
const progressBar = document.querySelector('.progress-bar');

ScrollManager.on('scroll:progress', (position) => {
  progressBar.style.width = position.percentY + '%';
});
<div class="scroll-progress">
  <div class="progress-bar"></div>
</div>
.scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 4px;
  background: rgba(0,0,0,0.1);
  z-index: 9999;
}

.progress-bar {
  height: 100%;
  background: #4CAF50;
  width: 0%;
  transition: width 0.1s;
}

7. Parallax Effect

ScrollManager.init({
  enabled: true,
  scroll: {
    parallax: {
      enabled: true,
      speed: 0.5
    }
  }
});

// Custom parallax
const parallaxElements = document.querySelectorAll('[data-parallax]');

ScrollManager.on('scroll:progress', (position) => {
  parallaxElements.forEach(el => {
    const speed = parseFloat(el.dataset.parallaxSpeed) || 0.5;
    const yPos = -(position.y * speed);
    el.style.transform = `translateY(${yPos}px)`;
  });
});
<div class="hero">
  <div class="hero-bg" data-parallax data-parallax-speed="0.5">
    Background
  </div>
  <div class="hero-content" data-parallax data-parallax-speed="0.2">
    Content
  </div>
</div>

8. Infinite Scroll

ScrollManager.init({
  enabled: true,
  scroll: {
    infinite: {
      enabled: true,
      threshold: 200,  // Load when 200px from bottom
      loadMore: async () => {
        console.log('Loading more content...');
        const newContent = await fetchMoreContent();
        appendContent(newContent);
      }
    }
  }
});

async function fetchMoreContent() {
  const response = await fetch('/api/load-more');
  return await response.json();
}

function appendContent(data) {
  const container = document.querySelector('.content-container');
  data.forEach(item => {
    const div = document.createElement('div');
    div.innerHTML = item.html;
    container.appendChild(div);
  });
}

State Properties

Property Type Description
state.initialized Boolean Initialization status
state.isScrolling Boolean Currently scrolling
state.isLoading Boolean Currently loading data
state.activeAnimation Number|null Current animation RAF ID
state.positions Map Stored scroll positions
state.waypoints Map All waypoints
state.observers Map Observers (Intersection, Mutation, Resize)
state.events Map Event handlers
state.history Array Scroll position history
state.lastPosition Object|null Last position
state.scrollDirection String|null Scroll direction ('up'|'down')
state.activeSection String|null Currently active section

Example:

// Check status
if (ScrollManager.state.initialized) {
  console.log('Ready');
}

if (ScrollManager.state.isScrolling) {
  console.log('Currently scrolling');
}

// View history
console.log(ScrollManager.state.history);

// View all waypoints
ScrollManager.state.waypoints.forEach((waypoint, id) => {
  console.log(id, waypoint);
});

Easing Functions

ScrollManager has built-in easing functions:

Function Description Best For
linear Constant speed Simple movement
easeInOutCubic Slow-fast-slow General scrolling (default)
easeOutQuart Gradually slow down Soft stop
easeInQuad Gradually speed up Slow start
easeOutBack Overshoot and return Special effects

Example:

ScrollManager.scrollTo('#target', {
  duration: 1000,
  easing: 'easeOutQuart'  // Use easing function
});

Custom Easing:

ScrollManager.config.animation.types.myCustomEasing = (t) => {
  return t * t * (3 - 2 * t); // smoothstep
};

ScrollManager.scrollTo('#target', {
  easing: 'myCustomEasing'
});

Integration

With RouterManager

// ScrollManager works automatically with RouterManager
RouterManager.init({
  mode: 'history',
  scrollToTop: true
});

ScrollManager.init({
  enabled: true,
  restoration: {
    enabled: true  // Remember position on back
  }
});

// Auto scroll to top on route change
RouterManager.on('route:changed', async (data) => {
  if (data.scrollToTop !== false) {
    await ScrollManager.scrollToTop();
  }
});

With ResponseHandler

// API response can control scrolling
ResponseHandler.registerHandler('scrollTo', async (action) => {
  await ScrollManager.scrollTo(action.target, action.options);
});

// API Response
{
  "success": true,
  "actions": [
    {
      "type": "scrollTo",
      "target": "#success-message",
      "options": {
        "offset": 100,
        "duration": 600
      }
    }
  ]
}

With Animation Libraries

// Use with GSAP, AOS, Animate.css
ScrollManager.init({
  enabled: true,
  waypoints: { threshold: 0.3, once: true }
});

// AOS Integration
document.querySelectorAll('[data-aos]').forEach((el, i) => {
  ScrollManager.addWaypoint(`aos-${i}`, el, {
    threshold: 0.3,
    once: true,
    callback: () => {
      AOS.refresh();
    }
  });
});

Best Practices

1. Enable Performance Features

ScrollManager.init({
  enabled: true,
  performance: {
    throttle: 16,
    debounce: 100,
    passive: true,
    observer: true,
    requestAnimationFrame: {
      enabled: true
    }
  }
});

2. Use Throttle and Debounce

// Throttle for scroll events
const handleScroll = ScrollManager.throttle(() => {
  // Runs every 16ms
}, 16);

// Debounce for resize
const handleResize = ScrollManager.debounce(() => {
  // Runs 150ms after resize stops
}, 150);

3. Clean Up When Not Used

// In SPA when changing page
RouterManager.on('route:before-change', () => {
  ScrollManager.cleanup();
});

// Or in component lifecycle
onBeforeUnmount(() => {
  ScrollManager.cleanup();
});

4. Use Waypoints Instead of Scroll Event Listeners

❌ Not Recommended:

window.addEventListener('scroll', () => {
  const element = document.querySelector('.target');
  const rect = element.getBoundingClientRect();
  if (rect.top < window.innerHeight) {
    element.classList.add('visible');
  }
});

✅ Recommended:

ScrollManager.addWaypoint('target', element, {
  threshold: 0.5,
  once: true,
  callback: () => {
    element.classList.add('visible');
  }
});

5. Set Offset for Fixed Header

ScrollManager.init({
  enabled: true,
  core: {
    offset: 80  // header height
  }
});
header {
  position: fixed;
  height: 80px;
}

6. Use Once for Animations

// Animation triggers only once
ScrollManager.addWaypoint('anim', element, {
  once: true,  // Won't trigger again
  callback: () => {
    element.classList.add('animated');
  }
});

7. Check Browser Support

if (!('IntersectionObserver' in window)) {
  // Use fallback
  console.warn('IntersectionObserver not supported');
  ScrollManager.init({
    enabled: true,
    performance: {
      observer: false
    }
  });
}

Common Pitfalls

1. Forgetting to Enable

// ❌ Won't work
ScrollManager.init({
  smoothScroll: { enabled: true }
});

// ✅ Must enable: true
ScrollManager.init({
  enabled: true,
  smoothScroll: { enabled: true }
});

2. Not Awaiting Async Methods

// ❌ May have issues
ScrollManager.scrollTo('#target');
doSomethingElse();  // Runs immediately

// ✅ Wait for completion
await ScrollManager.scrollTo('#target');
doSomethingElse();  // Runs after scroll

3. Target Doesn't Exist

// ❌ May error
ScrollManager.scrollTo('#non-existent');

// ✅ Check first
const target = document.querySelector('#my-target');
if (target) {
  await ScrollManager.scrollTo(target);
}

4. Duplicate Waypoint IDs

// ❌ Will throw error
ScrollManager.addWaypoint('my-id', element1);
ScrollManager.addWaypoint('my-id', element2);  // Error!

// ✅ Use unique IDs
ScrollManager.addWaypoint('waypoint-1', element1);
ScrollManager.addWaypoint('waypoint-2', element2);

5. Not Cleaning Up

// ❌ Memory leak in SPA
// No cleanup when changing page

// ✅ Clean up when necessary
RouterManager.on('route:before-change', () => {
  ScrollManager.cleanup();
});

Performance

1. Use RequestAnimationFrame

ScrollManager.init({
  enabled: true,
  performance: {
    requestAnimationFrame: {
      enabled: true,
      maxFPS: 60
    }
  }
});

2. Use Passive Event Listeners

ScrollManager.init({
  enabled: true,
  performance: {
    passive: true  // Improves scroll performance
  }
});

3. Use IntersectionObserver

// More performant than scroll event listeners
ScrollManager.init({
  enabled: true,
  performance: {
    observer: true
  }
});

4. Limit Waypoint Count

// ❌ Too many
document.querySelectorAll('.item').forEach((el, i) => {
  ScrollManager.addWaypoint(`item-${i}`, el);  // 1000+ waypoints
});

// ✅ Reasonable amount
document.querySelectorAll('.section').forEach((el, i) => {
  ScrollManager.addWaypoint(`section-${i}`, el);  // 10-20 waypoints
});

5. Throttle Scroll Events

ScrollManager.init({
  enabled: true,
  performance: {
    throttle: 16,    // ~60fps
    debounce: 100
  }
});

Security

1. Validate Selectors

// ❌ May have issues
const userInput = getUserInput();
ScrollManager.scrollTo(userInput);  // Dangerous!

// ✅ Validate first
function safeScrollTo(selector) {
  const element = document.querySelector(selector);
  if (element && element.matches('[data-scrollable]')) {
    ScrollManager.scrollTo(element);
  }
}

2. Check Callback Functions

// ✅ Verify callback is function
ScrollManager.addWaypoint('id', element, {
  callback: (entry) => {
    if (typeof window.onWaypoint === 'function') {
      window.onWaypoint(entry);
    }
  }
});

3. Limit Scroll Queue

ScrollManager.init({
  enabled: true,
  performance: {
    maxQueue: 100  // Limit queue size
  }
});

Browser Compatibility

Browser Version Support
Chrome 60+ ✅ Full
Firefox 55+ ✅ Full
Safari 12+ ✅ Full
Edge 79+ ✅ Full
iOS Safari 12+ ✅ Full
Chrome Android 80+ ✅ Full
IE Not Supported

Required Features:

  • ES6 (async/await, Map, Set)
  • requestAnimationFrame
  • IntersectionObserver (optional, uses fallback if unavailable)
  • ResizeObserver (optional)
  • MutationObserver (optional)

Polyfills:

<!-- For older browsers -->
<script src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver"></script>

API Reference

Methods Summary

Method Parameters Returns Description
init(options) options?: Object Promise<ScrollManager> Initialize
scrollTo(target, options) target: String\|Element, options?: Object Promise<void> Scroll to target
scrollToTop(options) options?: Object Promise<void> Scroll to top
scrollToBottom(options) options?: Object Promise<void> Scroll to bottom
scrollToContent(options) options?: Object Promise<void> Scroll to content area
addWaypoint(id, element, options) id: String, element: Element, options?: Object void Add waypoint
removeWaypoint(id) id: String void Remove waypoint
cancelScroll() - void Cancel scroll
getScrollPosition() - Object Get current position
on(event, handler) event: String, handler: Function void Register event
off(event, handler) event: String, handler: Function void Remove event
emit(eventName, data) eventName: String, data?: Any void Emit event
cleanup() - void Clean up
throttle(func, limit) func: Function, limit: Number Function Create throttled function
debounce(func, wait) func: Function, wait: Number Function Create debounced function

Live Examples

See ScrollManager in action with our comprehensive one-page scrolling example:

One-Page Scrolling Example

This example demonstrates:

  • ✨ Smooth scrolling navigation
  • 🎨 Parallax effects with multiple layers
  • 👁️ Waypoint animations
  • 📊 Scroll progress indicator
  • 🔗 Section highlighting and hash updates
  • 📱 Mobile-optimized touch interactions
  • ⌨️ Keyboard navigation support
  • 🎯 Interactive demo with real-time tracking

Visit the example to see all ScrollManager features working together in a beautiful one-page layout.

Summary

ScrollManager provides:

  • Smooth scrolling - Smooth page scrolling with animations
  • Waypoints - Detect when elements come into view
  • Performance - Uses RAF, throttle, debounce, IntersectionObserver
  • Accessibility - Supports keyboard, screen readers, ARIA
  • Mobile-friendly - Supports touch events
  • Flexible - Highly customizable with many events and callbacks
  • Integration - Works with RouterManager, ResponseHandler
  • Features - Parallax, infinite scroll, progress bar, section highlighting