JavaScript Events and Interactivity 
                CMU422: Fundamentals of Web Design - Session 7 
                Birmingham Newman University 
                Lecturer: James Williams 
                Building responsive user interfaces
                3-hour session • 25 slides • 2 interactive tasks 
                
                    Session Timeline: 
                    
                        10 min: Registration & waiting 
                        20 min: Opening slides 
                        45 min: Task 1 
                        15 min: Break/Catch up 
                        20 min: Secondary slides 
                        45 min: Task 2 
                        Remaining: Self-study 
                     
                 
             
            
            
                Learning Objectives 
                
                    Understand JavaScript event handling 
                    Master different types of events 
                    Create interactive user interfaces 
                    Handle form submissions and validation 
                    Build responsive and accessible interactions 
                 
             
            
            
                What are JavaScript Events? 
                
                    Events  are actions or occurrences that happen in the browser
                
                
                    User interactions (clicks, key presses, mouse movements) 
                    Browser actions (page load, resize, scroll) 
                    Form submissions and input changes 
                    Network events (AJAX responses) 
                 
                
                    // Event example 
                    button.addEventListener('click', function() { 
                      console.log('Button clicked!'); 
                    });
                
             
            
            
                Common Event Types 
                
                    // Mouse events 
                    'click', 'dblclick', 'mouseenter', 'mouseleave' 
                    // Keyboard events 
                    'keydown', 'keyup', 'keypress' 
                    // Form events 
                    'submit', 'change', 'input', 'focus', 'blur' 
                    // Document events 
                    'load', 'DOMContentLoaded', 'resize', 'scroll'
                
                
                    Mouse events for user interactions 
                    Keyboard events for text input 
                    Form events for data handling 
                    Document events for page lifecycle 
                 
             
            
            
                Event Handling Methods 
                
                    // Method 1: addEventListener (recommended) 
                    element.addEventListener('click', function(event) { 
                      console.log('Clicked!'); 
                    }); 
                    // Method 2: Inline event handlers 
                    <button onclick="handleClick()">Click me</button> 
                    // Method 3: Event properties 
                    element.onclick = function() { 
                      console.log('Clicked!'); 
                    };
                
                
                    addEventListener is the modern approach 
                    Allows multiple event listeners 
                    Better control over event handling 
                 
                
                
                    Try It: Interactive DOM Manipulation 
                    
                        
                            
                                Add
                                    Element 
                                Remove
                                    Element 
                                Highlight All 
                                Clear
                                    Highlights 
                            
                            
                            
                                Click the buttons to manipulate me!
                             
                         
                     
                    
                        This demo shows DOM manipulation, event handling, and dynamic styling!
                    
                 
             
            
            
                The Event Object 
                
                    element.addEventListener('click', function(event) { 
                      console.log(event.type); // 'click' 
                      console.log(event.target); // Element that was clicked 
                      console.log(event.clientX); // Mouse X position 
                      console.log(event.clientY); // Mouse Y position 
                      event.preventDefault(); // Prevent default behavior 
                      event.stopPropagation(); // Stop event bubbling 
                    });
                
                
                    Contains information about the event 
                    Provides methods to control event behavior 
                    Automatically passed to event handlers 
                 
             
            
            
                Event Bubbling and Capturing 
                
                    // Event bubbling (default) 
                    parent.addEventListener('click', function() { 
                      console.log('Parent clicked'); 
                    }); 
                    // Event capturing 
                    parent.addEventListener('click', function() { 
                      console.log('Parent clicked'); 
                    }, true); // true enables capturing 
                    // Stop propagation 
                    child.addEventListener('click', function(event) { 
                      event.stopPropagation(); 
                    });
                
                
                    Events bubble up from child to parent 
                    Capturing goes from parent to child 
                    Use stopPropagation() to prevent bubbling 
                 
             
            
            
                Form Events 
                
                    const form = document.querySelector('form'); 
                    // Form submission 
                    form.addEventListener('submit', function(event) { 
                      event.preventDefault(); 
                      // Handle form data 
                    }); 
                    // Input changes 
                    input.addEventListener('input', function(event) { 
                      console.log('Input value:', event.target.value); 
                    }); 
                    // Focus events 
                    input.addEventListener('focus', function() { 
                      this.style.borderColor = 'blue'; 
                    });
                
                
                    submit: Form submission 
                    input: Value changes 
                    focus/blur: Field focus 
                    change: Value confirmed 
                 
             
            
            
                Keyboard Events 
                
                    document.addEventListener('keydown', function(event) { 
                      console.log('Key pressed:', event.key); 
                      console.log('Key code:', event.code); 
                      // Check for specific keys 
                      if (event.key === 'Enter') { 
                        console.log('Enter pressed!'); 
                      } 
                      // Check for modifier keys 
                      if (event.ctrlKey && event.key === 's') { 
                        event.preventDefault(); 
                        console.log('Save shortcut!'); 
                      } 
                    });
                
                
                    keydown: Key pressed down 
                    keyup: Key released 
                    keypress: Character input 
                    Check for specific keys and modifiers 
                 
             
            
            
                Mouse Events 
                
                    element.addEventListener('click', function(event) { 
                      console.log('Click at:', event.clientX, event.clientY); 
                    }); 
                    element.addEventListener('mouseenter', function() { 
                      this.style.backgroundColor = 'yellow'; 
                    }); 
                    element.addEventListener('mouseleave', function() { 
                      this.style.backgroundColor = 'white'; 
                    }); 
                    element.addEventListener('mousemove', function(event) { 
                      // Track mouse movement 
                    });
                
                
                    click: Single click 
                    dblclick: Double click 
                    mouseenter/mouseleave: Hover effects 
                    mousemove: Mouse tracking 
                 
             
            
            
                Event Delegation 
                
                    // Instead of adding listeners to each item 
                    const list = document.querySelector('ul'); 
                    list.addEventListener('click', function(event) { 
                      if (event.target.tagName === 'LI') { 
                        console.log('List item clicked:',
                    event.target.textContent); 
                      } 
                    }); 
                    // Works for dynamically added items too
                
                
                    Attach event listener to parent element 
                    Use event.target to identify specific elements 
                    Efficient for multiple similar elements 
                    Works with dynamically added content 
                 
             
            
            
                Client-Side Form Validation 
                
                    form.addEventListener('submit', function(event) { 
                      event.preventDefault(); 
                      const email = document.getElementById('email').value; 
                      const password = document.getElementById('password').value; 
                      if (!email.includes('@')) { 
                        showError('Please enter a valid email'); 
                        return; 
                      } 
                      if (password.length < 8) { 
                            showError('Password must be at least 8
                        characters'); 
                            return; 
                          } 
                          // Form is valid, submit it 
                          this.submit(); 
                        });
                
                
                    Validate before form submission 
                    Provide immediate user feedback 
                    Always validate on server side too 
                    Use HTML5 validation attributes 
                 
             
            
            
                AJAX and Fetch API 
                
                    // Fetch data from server 
                    fetch('/api/data') 
                      .then(response => response.json()) 
                      .then(data => { 
                        console.log('Data received:', data); 
                        updateUI(data); 
                      }) 
                      .catch(error => { 
                        console.error('Error:', error); 
                      }); 
                    // POST data to server 
                    fetch('/api/submit', { 
                      method: 'POST', 
                      headers: { 'Content-Type': 'application/json' }, 
                      body: JSON.stringify(data) 
                    });
                
                
                    Fetch API for HTTP requests 
                    Promise-based approach 
                    Handle success and error cases 
                    Update UI with received data 
                 
             
            
            
                Local Storage 
                
                    // Store data 
                    localStorage.setItem('username', 'john'); 
                    localStorage.setItem('preferences', JSON.stringify({theme: 'dark'})); 
                    // Retrieve data 
                    const username = localStorage.getItem('username'); 
                    const preferences = JSON.parse(localStorage.getItem('preferences')); 
                    // Remove data 
                    localStorage.removeItem('username'); 
                    localStorage.clear(); // Remove all 
                    // Session storage (cleared when tab closes) 
                    sessionStorage.setItem('temp', 'value');
                
                
                    Store data in browser 
                    Persists between sessions 
                    Limited to strings (use JSON for objects) 
                    5-10MB storage limit 
                 
             
            
            
                Animation and Transitions 
                
                    // CSS transitions 
                    element.style.transition = 'all 0.3s ease'; 
                    element.style.transform = 'scale(1.1)'; 
                    // JavaScript animations 
                    function animate(element, duration) { 
                      const start = performance.now(); 
                      function update(currentTime) { 
                        const elapsed = currentTime - start; 
                        const progress = Math.min(elapsed / duration, 1); 
                        element.style.opacity = progress; 
                        if (progress < 1) { 
                              requestAnimationFrame(update); 
                            } 
                          } 
                          requestAnimationFrame(update); 
                        }
                
                
                    CSS transitions for simple animations 
                    JavaScript for complex animations 
                    Use requestAnimationFrame for smooth animations 
                    Consider performance and accessibility 
                 
             
            
            
                Accessibility Best Practices 
                
                    Use semantic HTML elements 
                    Provide keyboard navigation 
                    Add ARIA attributes when needed 
                    Ensure focus management 
                    Test with screen readers 
                    Provide alternative text for images 
                    Use sufficient color contrast 
                 
                
                    // Keyboard navigation 
                    element.addEventListener('keydown', function(event) { 
                      if (event.key === 'Enter' || event.key === ' ') { 
                        event.preventDefault(); 
                        handleClick(); 
                      } 
                    }); 
                    // ARIA attributes 
                    element.setAttribute('aria-label', 'Close dialog'); 
                    element.setAttribute('role', 'button');
                
             
            
            
                Error Handling 
                
                    // Try-catch for synchronous code 
                    try { 
                      const result = riskyOperation(); 
                      console.log(result); 
                    } catch (error) { 
                      console.error('Error occurred:', error.message); 
                      showUserFriendlyError(); 
                    } 
                    // Promise error handling 
                    fetch('/api/data') 
                      .then(response => { 
                        if (!response.ok) { 
                          throw new Error('Network response was not
                    ok'); 
                        } 
                        return response.json(); 
                      }) 
                      .catch(error => { 
                        console.error('Fetch error:', error); 
                        showErrorMessage(error.message); 
                      });
                
                
                    Handle errors gracefully 
                    Provide user-friendly error messages 
                    Log errors for debugging 
                    Use try-catch and promise error handling 
                 
             
            
            
                Task 1: Interactive Form 
                
                    Instructions: 
                    
                        Create a new HTML file called interactive-form.html 
                        Build a registration form with: 
                        
                            Name, email, password, and confirm password fields 
                            Real-time validation as user types 
                            Password strength indicator 
                            Submit button with loading state 
                         
                        Add event listeners for: 
                        
                            Input validation on blur and input events 
                            Form submission with preventDefault 
                            Password strength calculation 
                         
                        Use local storage to remember form data 
                        Add visual feedback for validation states 
                     
                    Time:  45 minutes
                    This task will help you understand form events and validation 
                 
             
            
            
                Break Time 
                
                    15 Minutes 
                    Take a break, ask questions, or catch up on the previous task.
                    Next: Secondary slides and Task 2 
                 
             
            
            
                Event Handling Best Practices 
                
                    Use addEventListener instead of inline handlers 
                    Remove event listeners when elements are destroyed 
                    Use event delegation for multiple elements 
                    Prevent default behavior when appropriate 
                    Handle errors gracefully 
                    Consider performance for frequent events 
                    Test across different browsers 
                 
                
                    // Remove event listener 
                    const handler = function() { console.log('clicked'); }; 
                    element.addEventListener('click', handler); 
                    element.removeEventListener('click', handler); 
                    // Throttle frequent events 
                    let timeout; 
                    element.addEventListener('scroll', function() { 
                      clearTimeout(timeout); 
                      timeout = setTimeout(handleScroll, 100); 
                    });
                
             
            
            
                Performance Considerations 
                
                    Throttle or debounce frequent events 
                    Use event delegation for many elements 
                    Avoid inline event handlers 
                    Remove unused event listeners 
                    Use passive event listeners when possible 
                    Consider using Intersection Observer for scroll events 
                 
                
                    // Passive event listener 
                    element.addEventListener('touchstart', handler, { passive: true }); 
                    // Intersection Observer 
                    const observer = new IntersectionObserver(entries => { 
                      entries.forEach(entry => { 
                        if (entry.isIntersecting) { 
                          entry.target.classList.add('visible'); 
                        } 
                      }); 
                    });
                
             
            
            
                Debugging Event Issues 
                
                    Use browser developer tools 
                    Check event listener attachment 
                    Verify event target and currentTarget 
                    Monitor event propagation 
                    Check for JavaScript errors 
                    Test event timing 
                 
                
                    // Debug event listeners 
                    element.addEventListener('click', function(event) { 
                      console.log('Event target:', event.target); 
                      console.log('Current target:', event.currentTarget); 
                      console.log('Event phase:', event.eventPhase); 
                      console.trace('Event call stack'); 
                    }); 
                    // Monitor all events 
                    const originalAddEventListener = EventTarget.prototype.addEventListener; 
                    EventTarget.prototype.addEventListener = function(type, listener, options) { 
                      console.log('Adding listener:', type, 'to', this); 
                      return originalAddEventListener.call(this, type, listener,
                    options); 
                    };
                
             
            
            
                Mobile-Specific Events 
                
                    // Touch events 
                    element.addEventListener('touchstart', function(event) { 
                      console.log('Touch started'); 
                      event.preventDefault(); // Prevent default touch behavior 
                    }); 
                    element.addEventListener('touchmove', function(event) { 
                      console.log('Touch moved'); 
                    }); 
                    element.addEventListener('touchend', function(event) { 
                      console.log('Touch ended'); 
                    }); 
                    // Device orientation 
                    window.addEventListener('orientationchange', function() { 
                      console.log('Orientation changed'); 
                    });
                
                
                    Touch events for mobile interactions 
                    Orientation change events 
                    Consider touch targets (minimum 44px) 
                    Handle both touch and mouse events 
                 
             
            
            
                Task 2: Interactive Dashboard 
                
                    Instructions: 
                    
                        Create a new HTML file called interactive-dashboard.html
                         
                        Build an interactive dashboard with: 
                        
                            Navigation:  Tabbed interface with smooth
                                transitions 
                            Widgets:  Collapsible panels with toggle
                                functionality 
                            Charts:  Simple data visualization (use CSS or basic
                                canvas) 
                            Search:  Real-time search with debouncing 
                            Settings:  Theme toggle and preferences 
                         
                        Implement event handling for: 
                        
                            Tab switching with keyboard navigation 
                            Widget collapse/expand animations 
                            Search input with live filtering 
                            Theme switching with local storage 
                         
                        Add accessibility features (ARIA attributes, keyboard support) 
                        Make it responsive for mobile devices 
                     
                    Time:  45 minutes
                    This task will help you understand complex event handling and UI
                            interactions 
                 
             
            
            
                Session Summary 
                
                    Events are the foundation of interactive web applications 
                    Use modern event handling methods 
                    Implement proper form validation 
                    Consider accessibility and performance 
                    Handle errors gracefully 
                    Test across different devices and browsers 
                 
                
                    Next Session: 
                    JavaScript Advanced Concepts - Functions, objects, and modern JavaScript