Now.js Framework Documentation

Now.js Framework Documentation

ScrollManager

TH 15 Dec 2025 08:52

ScrollManager

ภาพรวม

ScrollManager คือระบบจัดการ scroll behavior ใน Now.js Framework รองรับ smooth scrolling, waypoints, scroll tracking และ infinite scroll

ใช้เมื่อ:

  • ต้องการ smooth scroll to element
  • ต้องการ scroll waypoints/triggers
  • ต้องการ infinite scroll
  • ต้องการ scroll restoration
  • ต้องการ scroll navigation

ทำไมต้องใช้:

  • ✅ Smooth scrolling with easing
  • ✅ Waypoints และ triggers
  • ✅ Infinite scroll support
  • ✅ Scroll position persistence
  • ✅ Mobile touch support
  • ✅ Accessibility features

การใช้งานพื้นฐาน

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 top

การตั้งค่า

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 อ้างอิง

ScrollManager.scrollTo(target, options)

Scroll ไปยัง target

Parameter Type Description
target string/number/HTMLElement Selector, position หรือ 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 ไปด้านบน

await ScrollManager.scrollToTop({ duration: 500 });

ScrollManager.scrollToBottom(options)

Scroll ไปด้านล่าง

await ScrollManager.scrollToBottom();

ScrollManager.scrollToContent(options)

Scroll ไปยัง main content

await ScrollManager.scrollToContent();

ScrollManager.getScrollPosition()

รับ position ปัจจุบัน

Returns: Object - { x, y, direction }

const pos = ScrollManager.getScrollPosition();
console.log(`Scroll Y: ${pos.y}`);

ScrollManager.addWaypoint(id, element, options)

เพิ่ม 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)

ลบ waypoint

ScrollManager.removeWaypoint('section-1');

ScrollManager.cancelScroll()

ยกเลิก 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

เหตุการณ์

Event เมื่อเกิด Detail
scroll:start เริ่ม scroll animation {target}
scroll:end จบ scroll animation {position}
scroll:progress ระหว่าง 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`);
});

ตัวอย่างการใช้งานจริง

<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}`);
    }
  });
});

ข้อควรระวัง

⚠️ 1. รอ Init ก่อนใช้

// ❌ ใช้ก่อน init
ScrollManager.scrollTo('#section');

// ✅ รอ init
await ScrollManager.init({ enabled: true });
ScrollManager.scrollTo('#section');

⚠️ 2. Offset สำหรับ Fixed Header

// ❌ ไม่คำนึงถึง header
ScrollManager.scrollTo('#content');

// ✅ เพิ่ม offset
const headerHeight = document.querySelector('header').offsetHeight;
ScrollManager.scrollTo('#content', {
  offset: -headerHeight
});

เอกสารที่เกี่ยวข้อง