Now.js Framework Documentation
EventSystemManager - DOM Event System
EventSystemManager - DOM Event System
Documentation for EventSystemManager, a high-performance DOM event management system.
📋 Table of Contents
- Overview
- Installation and Import
- Basic Usage
- Event Delegation
- Keyboard Events
- Window Events
- Performance Optimization
- Memory Management
- Priority System
- Configuration
- Usage Examples
- API Reference
- Best Practices
Overview
EventSystemManager is a high-performance DOM event management system designed with advanced features beyond standard addEventListener.
Key Features
- ✅ Event Delegation: Centralized event management
- ✅ Auto Cleanup: Automatically removes handlers when elements are removed
- ✅ Memory Management: Monitors and manages memory usage
- ✅ Priority System: Controls handler execution order
- ✅ UI Event Optimization: Uses requestAnimationFrame for UI events
- ✅ Keyboard Event Enhancement: Comprehensive keyboard event information
- ✅ Throttle/Debounce: Built-in event rate limiting
- ✅ Component Integration: Integrates with Now.js Components
- ✅ MutationObserver: Tracks DOM changes
- ✅ Performance Monitoring: Measures and tracks performance
Differences from EventManager
| Feature | EventSystemManager | EventManager |
|---|---|---|
| Purpose | DOM Events | Application Events |
| Main API | addHandler(), removeHandler() |
on(), emit(), off() |
| Event Types | DOM events (click, submit, etc.) | Custom events |
| Target | DOM elements | Application logic |
| Event Delegation | ✅ Supported | ❌ Not supported |
| Auto Cleanup | ✅ Supported | ⚠️ Manual |
| Memory Monitoring | ✅ Supported | ❌ Not supported |
| UI Optimization | ✅ requestAnimationFrame | ❌ Not supported |
When to Use EventSystemManager
✅ Use EventSystemManager when:
- Managing DOM Events (click, submit, input, etc.)
- Need Event Delegation
- Need Auto Cleanup when elements are removed
- Need Performance Optimization
- Need automatic Memory Management
- Need Priority-based event handling
❌ Don't use EventSystemManager when:
- Need Custom Application Events (use EventManager)
- Need Pattern Matching (use EventManager)
- Need Middleware (use EventManager)
- Need Event Groups (use EventManager)
Installation and Import
EventSystemManager loads with Now.js Framework and initializes automatically:
// No need to import - ready to use immediately
console.log(window.EventSystemManager); // EventSystemManager object
// Access through Now.js
const eventSystem = Now.getManager('eventsystem');Dependencies
EventSystemManager requires these dependencies:
- ErrorManager - For error handling
Initialization
EventSystemManager initializes automatically when Now.js loads:
// Auto-initialized
EventSystemManager.init();
// Or init with custom config
EventSystemManager.init({
delegation: {
enabled: true,
maxDelegationDepth: 10
},
memoryManagement: {
maxHandlersPerElement: 100,
maxCacheSize: 1000
}
});Basic Usage
1. Add Event Handler
// Basic
const element = document.querySelector('#my-button');
const handlerId = EventSystemManager.addHandler(element, 'click', (event) => {
console.log('Button clicked!', event);
});
// With options
const id = EventSystemManager.addHandler(element, 'click', (event) => {
console.log('Clicked:', event.target);
}, {
capture: false,
once: false,
passive: true,
priority: 10
});2. Remove Event Handler
// Remove by handler ID
EventSystemManager.removeHandler(handlerId);
// Remove all handlers for a component
EventSystemManager.removeComponentHandlers('my-component-id');3. Window Events
// Window events are handled automatically
EventSystemManager.addHandler(window, 'resize', (event) => {
console.log('Window resized');
});
EventSystemManager.addHandler(window, 'scroll', (event) => {
console.log('Window scrolled');
});4. Document Events
// Document events
EventSystemManager.addHandler(document, 'click', (event) => {
console.log('Document clicked');
});Event Delegation
Event Delegation allows managing events of child elements from a parent.
Basic Delegation
// Capture clicks on child elements matching selector
const container = document.querySelector('#container');
EventSystemManager.addHandler(container, 'click', (event) => {
console.log('Button clicked:', event.delegateTarget);
}, {
selector: '.item-button' // Only triggers on .item-button within container
});Use Cases for Delegation
1. Dynamic Lists
// List with dynamically added/removed items
const list = document.querySelector('#todo-list');
// Handle clicks on delete buttons
EventSystemManager.addHandler(list, 'click', (event) => {
const item = event.delegateTarget;
const itemId = item.dataset.id;
deleteItem(itemId);
}, {
selector: '.delete-button'
});
// Handle clicks on checkboxes
EventSystemManager.addHandler(list, 'click', (event) => {
const checkbox = event.delegateTarget;
toggleItemComplete(checkbox);
}, {
selector: '.item-checkbox'
});2. Tables
// Handle clicks on table rows
const table = document.querySelector('#data-table');
EventSystemManager.addHandler(table, 'click', (event) => {
const row = event.delegateTarget;
const rowId = row.dataset.id;
showRowDetails(rowId);
}, {
selector: 'tbody tr'
});
// Handle clicks on edit buttons
EventSystemManager.addHandler(table, 'click', (event) => {
const button = event.delegateTarget;
const rowId = button.closest('tr').dataset.id;
editRow(rowId);
}, {
selector: '.edit-button'
});3. Modal/Dialog
// Handle clicks on backdrop to close modal
EventSystemManager.addHandler(document.body, 'click', (event) => {
if (event.delegateTarget.classList.contains('modal-backdrop')) {
closeModal();
}
}, {
selector: '.modal-backdrop'
});Keyboard Events
EventSystemManager has special keyboard event enhancement.
Enhanced Keyboard Events
EventSystemManager.addHandler(input, 'keydown', (event) => {
const enhanced = event.originalEvent._enhanced;
console.log('Key:', enhanced.key);
console.log('Code:', enhanced.code);
// Helper properties
if (enhanced.isEnter) {
console.log('Enter pressed');
}
if (enhanced.isShiftEnter) {
console.log('Shift+Enter pressed');
}
if (enhanced.isCtrlEnter) {
console.log('Ctrl+Enter pressed');
}
if (enhanced.isTab) {
console.log('Tab pressed');
}
if (enhanced.isShiftTab) {
console.log('Shift+Tab pressed');
}
if (enhanced.isArrowKey) {
console.log('Arrow key pressed:', enhanced.key);
}
// Modifiers
if (enhanced.ctrlKey) console.log('Ctrl is held');
if (enhanced.altKey) console.log('Alt is held');
if (enhanced.shiftKey) console.log('Shift is held');
if (enhanced.metaKey) console.log('Meta/Cmd is held');
});Keyboard Shortcuts
// Submit form with Ctrl+Enter
EventSystemManager.addHandler(textarea, 'keydown', (event) => {
const enhanced = event.originalEvent._enhanced;
if (enhanced.isCtrlEnter) {
event.preventDefault();
submitForm();
}
});
// Tab navigation with Shift+Tab
EventSystemManager.addHandler(form, 'keydown', (event) => {
const enhanced = event.originalEvent._enhanced;
if (enhanced.isShiftTab) {
// Custom tab navigation
navigateToPreviousField();
}
});
// Close on Escape
EventSystemManager.addHandler(document, 'keydown', (event) => {
if (event.key === 'Escape') {
closeAllModals();
}
});Window Events
Handle window-level events such as resize, scroll, popstate.
Supported Window Events
// Resize
EventSystemManager.addHandler(window, 'resize', (event) => {
console.log('Window resized');
handleResize();
});
// Scroll
EventSystemManager.addHandler(window, 'scroll', (event) => {
console.log('Window scrolled');
handleScroll();
});
// Popstate (history navigation)
EventSystemManager.addHandler(window, 'popstate', (event) => {
console.log('History state changed');
handlePopState(event);
});
// Hashchange
EventSystemManager.addHandler(window, 'hashchange', (event) => {
console.log('Hash changed');
handleHashChange();
});
// Load
EventSystemManager.addHandler(window, 'load', (event) => {
console.log('Window loaded');
initialize();
});
// Online/Offline
EventSystemManager.addHandler(window, 'online', (event) => {
console.log('Connection restored');
syncData();
});
EventSystemManager.addHandler(window, 'offline', (event) => {
console.log('Connection lost');
showOfflineMessage();
});Performance Optimization
EventSystemManager has several performance enhancement mechanisms.
UI Event Optimization
UI events (resize, scroll, mousemove) use requestAnimationFrame:
// Optimized automatically
EventSystemManager.addHandler(window, 'scroll', (event) => {
// Runs in requestAnimationFrame
updateScrollPosition();
});
EventSystemManager.addHandler(window, 'resize', (event) => {
// Batched in requestAnimationFrame
recalculateLayout();
});
EventSystemManager.addHandler(element, 'mousemove', (event) => {
// Queued and processed together
updateMousePosition(event);
});Throttle and Debounce
// Throttle - limit execution rate
let lastTime = 0;
EventSystemManager.addHandler(window, 'scroll', (event) => {
const now = Date.now();
if (now - lastTime < 100) return; // throttle 100ms
lastTime = now;
handleScroll();
});
// Debounce - wait until stopped then execute
let debounceTimer;
EventSystemManager.addHandler(window, 'resize', (event) => {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => {
handleResize();
}, 200); // debounce 200ms
});Event Filtering
EventSystemManager has built-in event filtering:
// Configuration
EventSystemManager.config.filtering = {
enabled: true,
maxThrottleRate: 60, // events per second
debounceWait: 100,
highFrequencyEvents: new Set([
'mousemove',
'scroll',
'resize',
'touchmove',
'pointermove'
])
};Memory Management
EventSystemManager manages memory automatically.
Auto Cleanup
// Handlers are automatically removed when element is removed from DOM
const element = document.createElement('div');
document.body.appendChild(element);
const id = EventSystemManager.addHandler(element, 'click', handler);
// Remove element - handler is automatically removed
element.remove();Manual Cleanup
// Remove specific handler
EventSystemManager.removeHandler(handlerId);
// Remove all handlers for a component
EventSystemManager.removeComponentHandlers('component-id');
// Cleanup everything
EventSystemManager.cleanup();
// Destroy
EventSystemManager.destroy();Memory Monitoring
// Check memory usage
const stats = EventSystemManager.gatherMemoryStats();
console.log('Handlers:', stats.handlerCount);
console.log('Cache size:', stats.cacheSize);
console.log('WeakMap size:', stats.weakMapSize);
// Memory stats
console.log(EventSystemManager.state.memoryStats);
// {
// handlerCount: 42,
// cacheSize: 15,
// weakMapSize: 8,
// lastGC: 1698765432100,
// peakMemoryUsage: 50,
// memoryWarnings: 0
// }Garbage Collection
// Manual GC trigger
EventSystemManager.performGC();
// Auto GC configuration
EventSystemManager.config.memoryManagement = {
checkInterval: 30000, // Check every 30 seconds
maxHandlersPerElement: 100, // Max handlers per element
maxCacheSize: 1000, // Max cache size
gcThreshold: 0.8, // Trigger GC at 80%
detailedTracking: true // Enable detailed logging
};Priority System
Control handler execution order.
Priority Values
// High priority - executes first
EventSystemManager.addHandler(element, 'click', validationHandler, {
priority: 100
});
// Medium priority
EventSystemManager.addHandler(element, 'click', transformHandler, {
priority: 50
});
// Low priority - executes last
EventSystemManager.addHandler(element, 'click', submitHandler, {
priority: 10
});
// Default priority (0) - executes last
EventSystemManager.addHandler(element, 'click', loggingHandler);Use Cases for Priority
1. Form Validation Pipeline
// Validate first
EventSystemManager.addHandler(form, 'submit', (event) => {
if (!validateForm()) {
event.preventDefault();
event.stopImmediatePropagation();
}
}, {priority: 100});
// Transform data
EventSystemManager.addHandler(form, 'submit', (event) => {
transformFormData();
}, {priority: 50});
// Submit - executes last
EventSystemManager.addHandler(form, 'submit', (event) => {
submitFormData();
}, {priority: 10});2. Click Handlers
// Check permissions first
EventSystemManager.addHandler(button, 'click', (event) => {
if (!hasPermission()) {
event.preventDefault();
event.stopPropagation();
showPermissionError();
}
}, {priority: 100});
// Actual action
EventSystemManager.addHandler(button, 'click', (event) => {
performAction();
}, {priority: 50});Configuration
Configuration Options
const config = {
cleanupInterval: 600000, // Cleanup interval (ms)
maxMemoryUsage: 52428800, // Max memory (50MB)
delegation: {
enabled: true,
matchingStrategy: 'closestFirst',
maxDelegationDepth: 10,
optimizeSelectors: true,
rootElement: document.body
},
memoryManagement: {
checkInterval: 30000,
maxHandlersPerElement: 100,
maxCacheSize: 1000,
gcThreshold: 0.8,
detailedTracking: true
},
filtering: {
enabled: true,
maxThrottleRate: 60,
debounceWait: 100,
highFrequencyEvents: null // Set or null
}
};Update Configuration
// Update individual settings
EventSystemManager.config.memoryManagement.maxHandlersPerElement = 200;
EventSystemManager.config.delegation.maxDelegationDepth = 15;
// Update filtering
EventSystemManager.config.filtering.enabled = true;
EventSystemManager.config.filtering.maxThrottleRate = 30;Usage Examples
1. Form Handling
const form = document.querySelector('#registration-form');
// Submit handler
EventSystemManager.addHandler(form, 'submit', (event) => {
event.preventDefault();
// Validate
if (!validateForm(form)) {
showErrors();
return;
}
// Submit
const formData = new FormData(form);
submitRegistration(formData);
}, {
priority: 50
});
// Real-time validation
const inputs = form.querySelectorAll('input');
inputs.forEach(input => {
EventSystemManager.addHandler(input, 'blur', (event) => {
validateField(event.target);
});
EventSystemManager.addHandler(input, 'input', (event) => {
clearFieldError(event.target);
});
});2. Dynamic List with Delegation
const todoList = document.querySelector('#todo-list');
// Add item
EventSystemManager.addHandler(todoList, 'click', (event) => {
const item = event.delegateTarget;
const itemId = item.dataset.id;
addTodoItem(itemId);
}, {
selector: '.add-button'
});
// Toggle complete
EventSystemManager.addHandler(todoList, 'click', (event) => {
const checkbox = event.delegateTarget;
const itemId = checkbox.closest('.todo-item').dataset.id;
toggleComplete(itemId, checkbox.checked);
}, {
selector: '.todo-checkbox'
});
// Delete item
EventSystemManager.addHandler(todoList, 'click', (event) => {
const button = event.delegateTarget;
const itemId = button.closest('.todo-item').dataset.id;
deleteItem(itemId);
}, {
selector: '.delete-button'
});
// Edit item
EventSystemManager.addHandler(todoList, 'click', (event) => {
const button = event.delegateTarget;
const itemId = button.closest('.todo-item').dataset.id;
editItem(itemId);
}, {
selector: '.edit-button'
});3. Keyboard Navigation
const searchBox = document.querySelector('#search-box');
const results = document.querySelector('#search-results');
EventSystemManager.addHandler(searchBox, 'keydown', (event) => {
const enhanced = event.originalEvent._enhanced;
if (enhanced.isArrowKey) {
event.preventDefault();
if (enhanced.key === 'ArrowDown') {
focusNextResult();
} else if (enhanced.key === 'ArrowUp') {
focusPreviousResult();
}
}
if (enhanced.isEnter) {
const focused = results.querySelector('.focused');
if (focused) {
selectResult(focused);
}
}
if (event.key === 'Escape') {
closeResults();
}
});4. Scroll Handling
// Infinite scroll
let isLoading = false;
EventSystemManager.addHandler(window, 'scroll', (event) => {
if (isLoading) return;
const scrollPosition = window.scrollY + window.innerHeight;
const documentHeight = document.documentElement.scrollHeight;
if (scrollPosition >= documentHeight - 200) {
isLoading = true;
loadMoreContent().then(() => {
isLoading = false;
});
}
});
// Sticky header
const header = document.querySelector('#header');
EventSystemManager.addHandler(window, 'scroll', (event) => {
if (window.scrollY > 100) {
header.classList.add('sticky');
} else {
header.classList.remove('sticky');
}
});5. Drag and Drop
const draggable = document.querySelector('.draggable');
const dropzone = document.querySelector('.dropzone');
// Drag start
EventSystemManager.addHandler(draggable, 'dragstart', (event) => {
event.originalEvent.dataTransfer.effectAllowed = 'move';
event.originalEvent.dataTransfer.setData('text/html', event.target.innerHTML);
event.target.classList.add('dragging');
});
// Drag end
EventSystemManager.addHandler(draggable, 'dragend', (event) => {
event.target.classList.remove('dragging');
});
// Drag over
EventSystemManager.addHandler(dropzone, 'dragover', (event) => {
event.preventDefault();
event.originalEvent.dataTransfer.dropEffect = 'move';
dropzone.classList.add('drag-over');
});
// Drag leave
EventSystemManager.addHandler(dropzone, 'dragleave', (event) => {
dropzone.classList.remove('drag-over');
});
// Drop
EventSystemManager.addHandler(dropzone, 'drop', (event) => {
event.preventDefault();
dropzone.classList.remove('drag-over');
const data = event.originalEvent.dataTransfer.getData('text/html');
handleDrop(data);
});6. Modal Management
// Open modal
function openModal(modalId) {
const modal = document.querySelector(`#${modalId}`);
modal.classList.add('active');
// Close on backdrop click
const backdropId = EventSystemManager.addHandler(modal, 'click', (event) => {
if (event.target === modal) {
closeModal(modalId);
EventSystemManager.removeHandler(backdropId);
}
});
// Close on Escape
const escapeId = EventSystemManager.addHandler(document, 'keydown', (event) => {
if (event.key === 'Escape') {
closeModal(modalId);
EventSystemManager.removeHandler(escapeId);
}
});
}
function closeModal(modalId) {
const modal = document.querySelector(`#${modalId}`);
modal.classList.remove('active');
}7. Context Menu
const contextMenu = document.querySelector('#context-menu');
// Show context menu
EventSystemManager.addHandler(document, 'contextmenu', (event) => {
if (!event.target.closest('.has-context-menu')) return;
event.preventDefault();
contextMenu.style.left = event.originalEvent.pageX + 'px';
contextMenu.style.top = event.originalEvent.pageY + 'px';
contextMenu.classList.add('active');
});
// Hide context menu
EventSystemManager.addHandler(document, 'click', (event) => {
if (!event.target.closest('#context-menu')) {
contextMenu.classList.remove('active');
}
});
// Context menu actions
EventSystemManager.addHandler(contextMenu, 'click', (event) => {
const action = event.delegateTarget.dataset.action;
handleContextMenuAction(action);
contextMenu.classList.remove('active');
}, {
selector: '[data-action]'
});8. Table Sorting
const table = document.querySelector('#data-table');
EventSystemManager.addHandler(table, 'click', (event) => {
const th = event.delegateTarget;
const columnIndex = Array.from(th.parentElement.children).indexOf(th);
const currentSort = th.dataset.sort || 'none';
// Toggle sort direction
let newSort;
if (currentSort === 'none') newSort = 'asc';
else if (currentSort === 'asc') newSort = 'desc';
else newSort = 'none';
// Update UI
table.querySelectorAll('th').forEach(header => {
header.dataset.sort = 'none';
});
th.dataset.sort = newSort;
// Sort table
sortTable(table, columnIndex, newSort);
}, {
selector: 'th[data-sortable]'
});9. File Upload with Drag and Drop
const dropzone = document.querySelector('#file-dropzone');
// Prevent default drag behaviors
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
EventSystemManager.addHandler(dropzone, eventName, (event) => {
event.preventDefault();
event.stopPropagation();
});
});
// Highlight dropzone
['dragenter', 'dragover'].forEach(eventName => {
EventSystemManager.addHandler(dropzone, eventName, (event) => {
dropzone.classList.add('highlight');
});
});
['dragleave', 'drop'].forEach(eventName => {
EventSystemManager.addHandler(dropzone, eventName, (event) => {
dropzone.classList.remove('highlight');
});
});
// Handle drop
EventSystemManager.addHandler(dropzone, 'drop', (event) => {
const files = event.originalEvent.dataTransfer.files;
handleFiles(files);
});
// Click to upload
EventSystemManager.addHandler(dropzone, 'click', (event) => {
const input = document.createElement('input');
input.type = 'file';
input.multiple = true;
input.onchange = (e) => handleFiles(e.target.files);
input.click();
});10. Responsive Navigation
const nav = document.querySelector('#main-nav');
const toggle = document.querySelector('#nav-toggle');
// Toggle mobile menu
EventSystemManager.addHandler(toggle, 'click', (event) => {
nav.classList.toggle('active');
});
// Close on outside click
EventSystemManager.addHandler(document, 'click', (event) => {
if (!event.target.closest('#main-nav') &&
!event.target.closest('#nav-toggle')) {
nav.classList.remove('active');
}
});
// Close on Escape
EventSystemManager.addHandler(document, 'keydown', (event) => {
if (event.key === 'Escape') {
nav.classList.remove('active');
}
});
// Handle resize
EventSystemManager.addHandler(window, 'resize', (event) => {
if (window.innerWidth > 768) {
nav.classList.remove('active');
}
});API Reference
Configuration
{
cleanupInterval: number, // Cleanup interval (ms)
maxMemoryUsage: number, // Max memory usage (bytes)
delegation: {
enabled: boolean, // Enable delegation
matchingStrategy: string, // 'closestFirst'
maxDelegationDepth: number, // Max depth
optimizeSelectors: boolean, // Optimize selectors
rootElement: HTMLElement // Root element
},
memoryManagement: {
checkInterval: number, // Check interval (ms)
maxHandlersPerElement: number, // Max handlers per element
maxCacheSize: number, // Max cache size
gcThreshold: number, // GC threshold (0-1)
detailedTracking: boolean // Detailed tracking
},
filtering: {
enabled: boolean, // Enable filtering
maxThrottleRate: number, // Max events per second
debounceWait: number, // Debounce wait (ms)
highFrequencyEvents: Set // High frequency events
}
}Methods
Core Methods
// Initialize
init(): EventSystemManager
// Add handler
addHandler(
element: Element|Window|Document,
type: string,
handler: function,
options?: {
capture?: boolean,
once?: boolean,
passive?: boolean,
priority?: number,
componentId?: string,
selector?: string
}
): number
// Remove handler
removeHandler(id: number): boolean
// Remove component handlers
removeComponentHandlers(componentId: string): voidCleanup Methods
// Manual cleanup
cleanup(): void
// Remove element handlers
removeElementHandlers(element: Element): void
// Destroy
destroy(): voidMemory Methods
// Gather memory stats
gatherMemoryStats(): object
// Check memory usage
checkMemoryUsage(): void
// Perform GC
performGC(): voidEvent Object
{
type: string, // Event type
key: string, // Key (keyboard events)
shiftKey: boolean, // Shift key pressed
ctrlKey: boolean, // Ctrl key pressed
altKey: boolean, // Alt key pressed
metaKey: boolean, // Meta key pressed
target: Element, // Event target
currentTarget: Element, // Current target
delegateTarget: Element, // Delegate target
timestamp: number, // Timestamp
originalEvent: Event, // Original DOM event
preventDefault(): void,
stopPropagation(): void,
stopImmediatePropagation(): void,
matches(selector: string): boolean
}Handler Options
{
capture: boolean, // Capture phase
once: boolean, // Execute once
passive: boolean, // Passive listener
priority: number, // Priority (higher = first)
componentId: string, // Component ID
selector: string // Delegation selector
}Best Practices
1. ✅ Use Event Delegation
// ❌ Bad: separate handlers for each element
items.forEach(item => {
EventSystemManager.addHandler(item, 'click', handler);
});
// ✅ Good: use delegation
EventSystemManager.addHandler(container, 'click', handler, {
selector: '.item'
});2. ✅ Cleanup When Destroying Component
// ✅ Good: store handler IDs
const MyComponent = {
handlerIds: [],
init() {
const id1 = EventSystemManager.addHandler(this.element, 'click', handler);
const id2 = EventSystemManager.addHandler(this.button, 'submit', handler);
this.handlerIds.push(id1, id2);
},
destroy() {
this.handlerIds.forEach(id => {
EventSystemManager.removeHandler(id);
});
}
};3. ✅ Use Component ID
// ✅ Good: use componentId for easy cleanup
const componentId = 'my-component-123';
EventSystemManager.addHandler(element, 'click', handler, {
componentId
});
// Cleanup entire component at once
EventSystemManager.removeComponentHandlers(componentId);4. ✅ Use Priority Appropriately
// ✅ Good: validation before submit
EventSystemManager.addHandler(form, 'submit', validateHandler, {
priority: 100
});
EventSystemManager.addHandler(form, 'submit', submitHandler, {
priority: 10
});5. ✅ Use Passive for Scroll/Touch
// ✅ Good: passive for better performance
EventSystemManager.addHandler(element, 'touchstart', handler, {
passive: true
});
EventSystemManager.addHandler(window, 'scroll', handler, {
passive: true
});6. ✅ Throttle/Debounce UI Events
// ✅ Good: throttle scroll event
let lastTime = 0;
EventSystemManager.addHandler(window, 'scroll', (event) => {
const now = Date.now();
if (now - lastTime < 100) return;
lastTime = now;
handleScroll();
});7. ✅ Use Once for One-time Events
// ✅ Good: once for one-time events
EventSystemManager.addHandler(button, 'click', handler, {
once: true
});8. ✅ Manage Memory Carefully
// ✅ Good: monitor memory usage
setInterval(() => {
const stats = EventSystemManager.gatherMemoryStats();
if (stats.handlerCount > 500) {
console.warn('Too many handlers:', stats.handlerCount);
}
}, 60000);9. ✅ Use stopPropagation Carefully
// ⚠️ Careful: stopPropagation may prevent other handlers
EventSystemManager.addHandler(button, 'click', (event) => {
// Only use when necessary
event.stopPropagation();
});10. ✅ Test on Multiple Devices
// ✅ Good: support both mouse and touch
EventSystemManager.addHandler(element, 'click', handleClick);
EventSystemManager.addHandler(element, 'touchend', handleClick);Summary
When to Use EventSystemManager
| Use Case | Use EventSystemManager? | Notes |
|---|---|---|
| Manage DOM Events | ✅ Yes | click, submit, input, etc. |
| Event Delegation | ✅ Yes | Dynamic content |
| Auto Cleanup | ✅ Yes | Memory management |
| Performance Optimization | ✅ Yes | UI events |
| Keyboard Handling | ✅ Yes | Enhanced keyboard events |
| Custom Application Events | ❌ No | Use EventManager |
| Pattern Matching | ❌ No | Use EventManager |
| Middleware | ❌ No | Use EventManager |
Key Features
| Feature | Supported | Notes |
|---|---|---|
| Event Delegation | ✅ | Selector-based |
| Auto Cleanup | ✅ | MutationObserver |
| Memory Management | ✅ | Auto GC |
| Priority System | ✅ | Ordered execution |
| UI Optimization | ✅ | requestAnimationFrame |
| Keyboard Enhancement | ✅ | Helper properties |
| Throttle/Debounce | ✅ | Built-in filtering |
| Component Integration | ✅ | Component IDs |