We use cookies to enhance your experience on the site
CodeWorlds

Event Listeners - Listening for Events

Ray Arnold leads you deeper into the control center. "This is where it all begins," he points to a massive panel with thousands of buttons and indicators. "Every element of this system is an event listener - a watcher waiting for a signal."

"In Jurassic Park," he continues, "we have motion sensors, temperature detectors, cameras, microphones. Each one constantly listens, waiting for something unusual. When it detects something, it reacts immediately. In JavaScript, we have

addEventListener()
- a method that works exactly the same way."

addEventListener() - The Fundamental Method

The

addEventListener()
method is the foundation of event handling in modern JavaScript. It allows you to assign a handler function to a specific event type on a chosen element.

Syntax

1element.addEventListener(eventType, handlerFunction, options);
  • eventType - the type of event (string): 'click', 'keydown', 'submit' etc.
  • handlerFunction - the function called when the event occurs
  • options - optional parameters (more on these later)

Basic Example

"Let's start with something simple," says Ray. "The Velociraptor feeding button."

1// Get the button element
2const feedButton = document.getElementById('velociraptor-feed');
3
4// Register a listener
5feedButton.addEventListener('click', function(event) {
6  console.log('Starting Velociraptor feeding procedure');
7  console.log('Clicked on:', event.target);
8
9  // Feeding logic
10  feedVelociraptors();
11});
12
13function feedVelociraptors() {
14  console.log('Safety cage: LOCKED');
15  console.log('Food dispenser: ACTIVE');
16  console.log('Monitoring: ENABLED');
17  console.log('Procedure completed successfully');
18}

Multiple Listeners on the Same Element

"What if we need multiple reactions to the same event?" asks Ray. "In the park systems, that's normal - one event can trigger multiple protocols."

1const emergencyButton = document.getElementById('emergency');
2
3// First listener - alarm activation
4emergencyButton.addEventListener('click', function() {
5  console.log('ALARM: Activating sirens');
6  activateSirens();
7});
8
9// Second listener - closing gates
10emergencyButton.addEventListener('click', function() {
11  console.log('SECURITY: Closing all gates');
12  lockAllGates();
13});
14
15// Third listener - notifying staff
16emergencyButton.addEventListener('click', function() {
17  console.log('COMMUNICATIONS: Sending notifications to the team');
18  notifySecurityTeam();
19});
20
21// All three functions will execute on click

Different Types of Handler Functions

Ray shows you different ways to define handlers:

1const enclosureGate = document.getElementById('gate-5');
2
3// 1. Anonymous function
4enclosureGate.addEventListener('click', function(event) {
5  console.log('Gate clicked', event.target.id);
6});
7
8// 2. Arrow function (modern JavaScript)
9enclosureGate.addEventListener('click', (event) => {
10  console.log('Gate clicked', event.target.id);
11});
12
13// 3. Named function (best practice)
14function handleGateClick(event) {
15  console.log('Gate clicked', event.target.id);
16
17  if (event.target.dataset.status === 'open') {
18    closeGate(event.target.id);
19  } else {
20    openGate(event.target.id);
21  }
22}
23
24enclosureGate.addEventListener('click', handleGateClick);

"Named functions are the best," Ray explains, "because you can remove them later, test them separately, and the code is more readable."

The Event Object - A Full Event Report

"When a sensor detects movement," Ray shows a report on the screen, "we get a complete data package: where, when, what type of movement, how fast. The Event object in JavaScript works the same way."

Basic Properties

1document.addEventListener('click', function(event) {
2  // Basic event information
3  console.log('Event type:', event.type); // 'click'
4  console.log('Timestamp:', event.timeStamp); // time in ms since page load
5
6  // The element that was the target of the event
7  console.log('Target element:', event.target);
8  console.log('Current element:', event.currentTarget);
9
10  // Position information (for mouse events)
11  console.log('Screen position - X:', event.screenX, 'Y:', event.screenY);
12  console.log('Window position - X:', event.clientX, 'Y:', event.clientY);
13  console.log('Page position - X:', event.pageX, 'Y:', event.pageY);
14
15  // Modifier keys
16  console.log('Shift:', event.shiftKey);
17  console.log('Ctrl:', event.ctrlKey);
18  console.log('Alt:', event.altKey);
19  console.log('Meta (Cmd/Win):', event.metaKey);
20
21  // Mouse button
22  console.log('Button:', event.button); // 0=left, 1=middle, 2=right
23});

Practical Use of Properties

"Let's see it in a real system," says Ray, opening the code for the interactive park map.

1const parkMap = document.getElementById('interactive-park-map');
2
3parkMap.addEventListener('click', function(event) {
4  // Get click coordinates
5  const x = event.clientX;
6  const y = event.clientY;
7
8  // Check if Ctrl was held (multiple selection)
9  if (event.ctrlKey) {
10    console.log('Multiple selection - adding to selection');
11    addToSelection(event.target);
12  } else {
13    console.log('Single selection - clearing previous selection');
14    clearSelection();
15    selectSingle(event.target);
16  }
17
18  // Different actions for different mouse buttons
19  switch(event.button) {
20    case 0: // Left button
21      showEnclosureDetails(event.target);
22      break;
23    case 2: // Right button
24      showContextMenu(x, y);
25      event.preventDefault(); // Block default context menu
26      break;
27  }
28
29  // Save position for later use
30  lastClickPosition = { x, y };
31});
32
33// Blocking the default context menu (right button)
34parkMap.addEventListener('contextmenu', function(event) {
35  event.preventDefault();
36  console.log('Custom context menu instead of default');
37});

Different Types of Events

Ray shows more screens with different systems. "Each type of sensor detects something different. Similarly, we have different types of events."

Mouse Events

1const dinoCard = document.getElementById('trex-card');
2
3// Clicks
4dinoCard.addEventListener('click', (e) => {
5  console.log('Single click');
6  showBasicInfo();
7});
8
9dinoCard.addEventListener('dblclick', (e) => {
10  console.log('Double click');
11  showDetailedView();
12});
13
14// Entering and leaving
15dinoCard.addEventListener('mouseenter', (e) => {
16  console.log('Mouse entered the card');
17  e.target.classList.add('highlighted');
18  showQuickPreview();
19});
20
21dinoCard.addEventListener('mouseleave', (e) => {
22  console.log('Mouse left the card');
23  e.target.classList.remove('highlighted');
24  hideQuickPreview();
25});
26
27// Mouse movement (use carefully - can generate hundreds of events)
28dinoCard.addEventListener('mousemove', (e) => {
29  // Update tooltip position
30  updateTooltipPosition(e.clientX, e.clientY);
31});
32
33// Button press and release
34dinoCard.addEventListener('mousedown', (e) => {
35  console.log('Mouse button pressed');
36  startDrag(e);
37});
38
39dinoCard.addEventListener('mouseup', (e) => {
40  console.log('Mouse button released');
41  endDrag(e);
42});

Keyboard Events

"Many systems are controlled via keyboard," Ray explains. "Access codes, keyboard shortcuts, navigation."

1// Listen on the entire document
2document.addEventListener('keydown', function(event) {
3  console.log('Key pressed:', event.key);
4  console.log('Key code:', event.code);
5  console.log('Is it a repeat:', event.repeat);
6
7  // Keyboard shortcuts
8  if (event.ctrlKey && event.key === 's') {
9    event.preventDefault(); // Block default browser save
10    saveParkConfiguration();
11    console.log('Configuration saved');
12  }
13
14  if (event.key === 'Escape') {
15    closeAllModals();
16    console.log('All windows closed');
17  }
18
19  // Arrow key navigation
20  switch(event.key) {
21    case 'ArrowUp':
22      moveCamera('north');
23      break;
24    case 'ArrowDown':
25      moveCamera('south');
26      break;
27    case 'ArrowLeft':
28      moveCamera('west');
29      break;
30    case 'ArrowRight':
31      moveCamera('east');
32      break;
33  }
34});
35
36// Listen on a specific field
37const securityCodeInput = document.getElementById('security-code');
38
39securityCodeInput.addEventListener('keypress', function(event) {
40  // Only digits
41  if (event.key < '0' || event.key > '9') {
42    event.preventDefault();
43    console.log('Only digits are allowed');
44  }
45});

Form Events

"Forms are a critical part of the park systems," says Ray. "Incident reporting, guest registration, monitoring."

1const incidentForm = document.getElementById('incident-report');
2const severitySelect = document.getElementById('severity');
3const descriptionArea = document.getElementById('description');
4
5// Submit - form submission
6incidentForm.addEventListener('submit', function(event) {
7  event.preventDefault(); // IMPORTANT: block default submission
8
9  console.log('Form submitted');
10
11  // Collect data
12  const formData = new FormData(incidentForm);
13  const data = {
14    severity: formData.get('severity'),
15    location: formData.get('location'),
16    description: formData.get('description'),
17    reporter: formData.get('reporter'),
18    timestamp: new Date().toISOString()
19  };
20
21  // Validation
22  if (validateIncidentReport(data)) {
23    submitIncidentReport(data);
24    incidentForm.reset();
25  } else {
26    console.error('Invalid form data');
27  }
28});
29
30// Change - value changed (after leaving the field)
31severitySelect.addEventListener('change', function(event) {
32  const severity = event.target.value;
33  console.log('Threat level changed to:', severity);
34
35  // Adjust priority and color
36  if (severity === 'critical') {
37    incidentForm.classList.add('critical');
38    setPriority('HIGH');
39  } else {
40    incidentForm.classList.remove('critical');
41    setPriority('NORMAL');
42  }
43});
44
45// Input - value changing (in real time)
46descriptionArea.addEventListener('input', function(event) {
47  const length = event.target.value.length;
48  const maxLength = 500;
49
50  console.log(`Characters: ${length}/${maxLength}`);
51  updateCharacterCounter(length, maxLength);
52
53  if (length > maxLength) {
54    event.target.classList.add('error');
55  } else {
56    event.target.classList.remove('error');
57  }
58});
59
60// Focus and Blur - field activation and deactivation
61descriptionArea.addEventListener('focus', function(event) {
62  console.log('Description field active - showing help tips');
63  showHelpTips();
64});
65
66descriptionArea.addEventListener('blur', function(event) {
67  console.log('Description field inactive - hiding tips');
68  hideHelpTips();
69});

removeEventListener() - Removing Listeners

"Systems that are no longer needed," Ray shows a disabled panel, "should be shut down. It saves energy and resources."

Basic Removal

1// The function must be named to be removable
2function handleClick(event) {
3  console.log('Clicked');
4}
5
6const button = document.getElementById('temp-button');
7
8// Add listener
9button.addEventListener('click', handleClick);
10
11// Later remove it (must be the same function)
12button.removeEventListener('click', handleClick);
13
14// ❌ This WON'T WORK - these are two different functions
15button.addEventListener('click', () => console.log('Test'));
16button.removeEventListener('click', () => console.log('Test'));

Practical Example - Timed Monitoring

1function setupMaintenanceMode() {
2  console.log('Enabling maintenance mode for 5 minutes');
3
4  const maintenanceAlert = function(event) {
5    event.preventDefault();
6    alert('Park is in maintenance mode. Please try again later.');
7  };
8
9  // Block all actions
10  document.addEventListener('click', maintenanceAlert, true); // true = capture
11
12  // After 5 minutes disable maintenance mode
13  setTimeout(() => {
14    document.removeEventListener('click', maintenanceAlert, true);
15    console.log('Maintenance mode disabled');
16  }, 5 * 60 * 1000);
17}

addEventListener() Options

Ray shows the advanced configuration panel. "Sometimes we need special settings for sensors."

1element.addEventListener(eventType, handler, {
2  capture: false,  // Use capture phase instead of bubbling
3  once: false,     // Remove listener after first invocation
4  passive: false   // Don't call preventDefault()
5});

Example: once - One-Time Listener

1const welcomeScreen = document.getElementById('welcome');
2
3// Show welcome only once
4welcomeScreen.addEventListener('click', function() {
5  console.log('Welcome to Jurassic Park!');
6  showTour();
7}, { once: true });
8
9// After the first click, the listener is automatically removed

Example: passive - Better Scroll

1// For scroll performance
2window.addEventListener('scroll', function(event) {
3  updateScrollPosition();
4  // Cannot use event.preventDefault() with passive: true
5}, { passive: true });

Monitoring System in Practice

"Let's combine everything into one system," says Ray, opening the main monitoring code.

1class ParkMonitoringSystem {
2  constructor() {
3    this.alerts = [];
4    this.isActive = false;
5    this.initialize();
6  }
7
8  initialize() {
9    console.log('Initializing monitoring system...');
10
11    // Document events
12    document.addEventListener('DOMContentLoaded', () => {
13      this.onSystemReady();
14    });
15
16    // Window events
17    window.addEventListener('beforeunload', (e) => {
18      return this.onBeforeExit(e);
19    });
20
21    // Error events
22    window.addEventListener('error', (e) => {
23      this.logError(e);
24    });
25
26    this.isActive = true;
27  }
28
29  onSystemReady() {
30    console.log('Monitoring system ready');
31    this.setupEnclosureMonitors();
32    this.setupSecuritySystem();
33    this.startPeriodicChecks();
34  }
35
36  setupEnclosureMonitors() {
37    const enclosures = document.querySelectorAll('.enclosure');
38
39    enclosures.forEach(enclosure => {
40      // Enclosure status
41      enclosure.addEventListener('click', (e) => {
42        this.showEnclosureStatus(enclosure.id);
43      });
44
45      // Details on double click
46      enclosure.addEventListener('dblclick', (e) => {
47        this.showDetailedView(enclosure.id);
48      });
49
50      // Highlight on hover
51      enclosure.addEventListener('mouseenter', (e) => {
52        e.target.classList.add('active');
53        this.showQuickInfo(enclosure.id);
54      });
55
56      enclosure.addEventListener('mouseleave', (e) => {
57        e.target.classList.remove('active');
58        this.hideQuickInfo();
59      });
60    });
61  }
62
63  setupSecuritySystem() {
64    // Keyboard shortcuts
65    document.addEventListener('keydown', (e) => {
66      if (e.ctrlKey && e.shiftKey && e.key === 'E') {
67        this.triggerEmergency();
68      }
69
70      if (e.key === 'F1') {
71        e.preventDefault();
72        this.showHelp();
73      }
74    });
75
76    // Emergency button
77    const emergencyBtn = document.getElementById('emergency');
78    if (emergencyBtn) {
79      emergencyBtn.addEventListener('click', () => {
80        this.triggerEmergency();
81      });
82    }
83  }
84
85  startPeriodicChecks() {
86    // Check all systems every 30 seconds
87    this.checkInterval = setInterval(() => {
88      if (this.isActive) {
89        this.performSystemCheck();
90      }
91    }, 30000);
92  }
93
94  performSystemCheck() {
95    console.log(`[${new Date().toLocaleTimeString()}] Checking systems...`);
96    // Check logic
97  }
98
99  triggerEmergency() {
100    console.error('🚨 EMERGENCY ALARM!');
101    this.addAlert({
102      type: 'emergency',
103      message: 'Emergency alarm activated',
104      timestamp: new Date()
105    });
106  }
107
108  addAlert(alert) {
109    this.alerts.push(alert);
110    const event = new CustomEvent('parkAlert', { detail: alert });
111    document.dispatchEvent(event);
112  }
113
114  onBeforeExit(event) {
115    if (this.alerts.some(a => a.type === 'emergency')) {
116      event.returnValue = 'There are active alerts! Are you sure you want to leave?';
117      return event.returnValue;
118    }
119  }
120
121  logError(event) {
122    console.error('System error:', event.error);
123    this.addAlert({
124      type: 'error',
125      message: event.error.message,
126      timestamp: new Date()
127    });
128  }
129
130  destroy() {
131    // Disable monitoring
132    this.isActive = false;
133    clearInterval(this.checkInterval);
134    console.log('Monitoring system disabled');
135  }
136}
137
138// Initialization
139const parkMonitoring = new ParkMonitoringSystem();

Summary

"Event listeners are the core of every interactive system," Ray summarizes. "Just as sensors in Jurassic Park watch over safety, event listeners watch over the functionality of your application."

Key rules:

  • Use
    addEventListener()
    for all listeners
  • Always check if the element exists before adding a listener
  • Use named functions for listeners you need to remove
  • Remember
    removeEventListener()
    when a listener is no longer needed
  • Use the
    { once: true }
    option for one-time operations
  • Use
    { passive: true }
    for scroll/touch for performance
Go to CodeWorlds