James Williams
Birmingham Newman University
jwilliams@staff.newman.ac.uk
3-hour session
// Event example
button.addEventListener('click', function() {
console.log('Button clicked!');
});
// Mouse events
'click', 'dblclick', 'mouseenter', 'mouseleave'
// Keyboard events
'keydown', 'keyup', 'keypress'
// Form events
'submit', 'change', 'input', 'focus', 'blur'
// Document events
'load', 'DOMContentLoaded', 'resize', 'scroll'
// 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 approachThis demo shows DOM manipulation, event handling, and dynamic styling!
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
});
// 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();
});
stopPropagation() to prevent bubblingconst 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 submissioninput: Value changesfocus/blur: Field focuschange: Value confirmeddocument.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 downkeyup: Key releasedkeypress: Character inputelement.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 clickdblclick: Double clickmouseenter/mouseleave: Hover effectsmousemove: Mouse tracking// 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
event.target to identify specific elementsform.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();
});
// 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)
});
// 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');
// 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);
}
requestAnimationFrame for smooth animations// 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');
// 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);
});
Create animated typewriter text effects.
// Initialize Typed.js
new Typed('#typed-demo', {
strings: ['Hello World!', 'Welcome to Typed.js', 'Amazing typewriter effect!'],
typeSpeed: 50,
backSpeed: 30,
loop: true
});
Beautiful tooltips and popovers with custom styling.
// Initialize Tippy.js
tippy('#my-button', {
content: 'This is a tooltip!',
theme: 'light',
animation: 'scale'
});
Beautiful, responsive, customizable popup boxes.
// Show a SweetAlert
Swal.fire({
title: 'Success!',
text: 'Your action was completed.',
icon: 'success',
confirmButtonText: 'OK'
});
Utility library for array/object manipulation and data processing.
// Lodash utilities
const arr = [1, 2, 2, 3, 3, 3, 4];
_.uniq(arr); // [1, 2, 3, 4]
const users = [{name: 'John', age: 30}, {name: 'Jane', age: 25}];
_.sortBy(users, 'age'); // Sort by age
Lightweight library for date formatting and manipulation.
// Format dates with Day.js
dayjs().format('MMMM D, YYYY'); // "January 15, 2024"
dayjs().format('h:mm A'); // "3:45 PM"
dayjs().add(7, 'day').format('MMM DD'); // Add 7 days
Copy text to clipboard without Flash.
<!-- HTML -->
<input id="copy-input" value="Copy this text" />
<button data-clipboard-target="#copy-input">Copy</button>
<script>
// Initialize Clipboard.js
new ClipboardJS('button');
</script>
Simple toast notifications for user feedback.
// Show a toast notification
Toastify({
text: "This is a toast notification!",
duration: 3000,
gravity: "top",
position: "right",
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)"
}).showToast();
Create stunning 3D graphics and animations in the browser.
// Create a 3D scene
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, width/height, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({ color: 0x2196f3 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
Creative coding library for interactive art and animations.
// p5.js sketch
function setup() {
createCanvas(400, 200);
}
function draw() {
background(30);
fill(255, 100, 150);
ellipse(mouseX, mouseY, 30, 30);
}
Professional-grade JavaScript animation library.
// GSAP animation
gsap.to('#box', {
duration: 1.2,
y: -30,
repeat: -1,
yoyo: true,
ease: 'power1.inOut'
});
Interactive maps for mobile and desktop.
// Create a map
const map = L.map('map').setView([52.489, -1.898], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
L.marker([52.489, -1.898]).addTo(map)
.bindPopup('Birmingham Newman University');
Simple yet flexible JavaScript charting library.
// Create a chart
new Chart(ctx, {
type: 'bar',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
datasets: [{
label: 'Sales',
data: [12, 19, 3, 5, 2]
}]
}
});
interactive-form.htmlTime: 45 minutes
This task will help you understand form events and validation
Take a break, ask questions, or catch up on the previous task.
Next: Secondary slides and Task 2
addEventListener instead of inline handlers// 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);
});
// 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');
}
});
});
// 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);
};
// 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');
});
interactive-dashboard.html
Time: 45 minutes
This task will help you understand complex event handling and UI interactions
JavaScript Advanced Concepts - Functions, objects, and modern JavaScript