UNPKG

vz-scroll-interactions

Version:

A lightweight, universal scroll interaction library that works with any framework - vanilla JS, React, Vue, and more

98 lines (84 loc) 2.59 kB
export class ScrollEventManager { constructor() { this.instances = new Map(); this.boundHandleScroll = this.handleScroll.bind(this); this.isListenerAttached = false; } // Create a new scroll event instance createInstance(key, callback, options = {}) { const { enabled = true, throttle = 0 } = options; // If instance already exists, update it if (this.instances.has(key)) { const existingInstance = this.instances.get(key); existingInstance.callback = callback; existingInstance.enabled = enabled; return existingInstance; } // Create new instance const instance = { key, callback, enabled, lastCall: 0, throttle }; this.instances.set(key, instance); this.attachGlobalListener(); return instance; } // Global scroll event handler handleScroll(event) { const now = Date.now(); this.instances.forEach(instance => { // Skip if instance is disabled if (!instance.enabled) return; // Check throttling if (now - instance.lastCall >= instance.throttle) { instance.lastCall = now; try { instance.callback(event); } catch (error) { console.error(`Scroll event error for ${instance.key}:`, error); } } }); } // Attach global scroll listener only once attachGlobalListener() { if (!this.isListenerAttached && typeof window !== 'undefined') { window.addEventListener('scroll', this.boundHandleScroll, { passive: true }); this.isListenerAttached = true; } } // Remove a specific scroll instance removeInstance(key) { this.instances.delete(key); // Remove global listener if no instances remain if (this.instances.size === 0 && typeof window !== 'undefined') { window.removeEventListener('scroll', this.boundHandleScroll); this.isListenerAttached = false; } } // Toggle an instance's enabled state toggleInstance(key, enabled) { const instance = this.instances.get(key); if (instance) { instance.enabled = enabled; } } // Get all current instances getInstances() { return Array.from(this.instances.keys()); } // Cleanup all instances cleanup() { if (typeof window !== 'undefined' && this.isListenerAttached) { window.removeEventListener('scroll', this.boundHandleScroll); this.isListenerAttached = false; } this.instances.clear(); } }