JavaScript for Front-End Developers
Session Time: 120 minutes
Table of Contents
- Core JavaScript Fundamentals
- The Document Object Model (DOM)
- Handling User Events
- AI-Assisted Debugging
- Lab: Adding Interactivity to a Web Page
- Wrap-Up and Reflection
Learning Objectives
Upon completion of this session, participants will be able to:
- Construct scripts to modify DOM elements dynamically.
- Analyze how variables, functions, and events operate in JavaScript.
- Utilize AI tools to interpret and resolve JavaScript errors.
Session Breakdown
| Segment | Topic | Duration (minutes) |
|---|---|---|
| Concept I | Core Syntax & DOM Manipulation | 45 |
| Concept II | Events & AI Debugging | 30 |
| Practical Lab | Lab: Adding Interactivity to a Web Page | 45 |
| Total | 120 minutes |
1. Intro to JavaScript Concepts
Learning objective: By the end of this lesson, students will be able to describe the role of JavaScript in web development and its significance in both client-side and server-side applications.
What is JavaScript?
JavaScript (commonly abbreviated as JS) is a powerful and versatile programming language. It was created primarily to enhance web pages by making them interactive. It is a high-level language, meaning developers don't need to manage system-specific details as we write it.
JavaScript is the only programming language used directly in web browsers. This alone has made it increasingly popular as web-based applications have become more common. Its ubiquitous use in the browser has also fueled its proliferation out of the browser and into server, mobile, and desktop applications.
These attributes have all fueled JavaScript's explosive growth and sustained popularity through time. The following graph shows the top languages on GitHub since 2014, where JavaScript has steadily held the top position. When you visit a website in your browser, it almost always uses JavaScript in some form or fashion.

Why use JavaScript?
There are a lot of reasons to learn JavaScript, including:
- It's necessary for web development but also a versatile language that can do much more.
- It's system and environment agnostic. This means it doesn't require a lot of resources to run.
- It's under active development. New improvements and features are still added to JavaScript annually.
- It's community support. If you're trying to accomplish something in JavaScript, someone has likely built a tool to help you achieve that task more efficiently.
These reasons funnel into another important factor: jobs. As more job positions are filled, the community continues to grow, the usefulness of JavaScript expands, and even more job positions are created.

JavaScript's role in web applications
JavaScript, along with HTML and CSS, is one of the three essential technologies used to create web apps. HTML defines the structure and content of a web page. CSS controls how the page is styled and presented. JavaScript adds interactivity and behavior.

2. JS Fundamentals
Learning objective: By the end of this lesson, students will be able to utilize comments for code documentation and print to the console for debugging.
Making Comments
In JavaScript and many other programming languages, we can make our more readable and maintainable for ourselves and others by writing comments. Comments are pieces of text that are ignored when code is evaluated.
There are several reasons why comments in code are valuable to us:
- Help ourselves and others understand our code when reading it later.
- Help us document why a decision was made - what the purpose of code is or provide other context.
- They help document our code's functionality, aiding in troubleshooting and debugging.
- Documenting any known issues with your code. Perhaps it doesn't account for specific edge cases or isn't as performant as it could be, and you want to return to it later.
As you're just learning, don't be afraid to add comments to help you understand what that code is doing. However, outside of a learning environment, comments explaining why decisions were made are typically more valuable than comments explaining what code does.
There are two types of comments in JavaScript: single-line and multi-line.
Single-line comments
Single-line comments start with two forward slashes // and continue to the end of the line. Everything on that line after the forward slashes is ignored when the code is evaluated.
// This is a single-line comment.You can write single-line comments on their own line or on the same line as code (but this can get messy). The forward slashes will ignore the code written before them.
console.log('Comments are great'); // I only ignore words written after me!๐ง VS Code can automatically comment line(s) of code for us by pressing
โ Command+/in macOS orCtrl+/in Linux and Windows.
Multi-line comments
Multi-line comments in JavaScript are opened with a forward slash and an asterisk /* and closed with an asterisk and a forward slash */. When the code is evaluated, anything written between the start and end tags is ignored.
/*
This is a multi-line comment.
It can span multiple lines.
*/Printing to the console
We can print output to the terminal app or console in the browser running our code!
To print to the console in JavaScript, we can use a console.log(). Whatever is in the parenthesis will be printed.
console.log('Hello, world!');
// Prints: Hello, world!Printing to the console, or console logging, is one of the most powerful tools we have for understanding and debugging our code. Trying things out and console logging often is one of the best ways to learn JavaScript.
3. Variables
The purpose of a variable in programming is to hold or reference data.
๐ A variable is a named container used to store and retrieve data used within a program.
We use the let or const (short for constant) keyword to declare a variable in JavaScript. These are special keywords known as declarations. The variable name or identifier follows the declaration.
๐ A declaration is used to indicate a variable is being created. An identifier is then used to identify a variable.
let favSnack;
// let is the declaration
// favSnack is the identifierWe can also assign a value to a variable at the time we declare it by using the = (assignment) operator:
let name = 'Tony Stark';and change its value later:
name = 'Pepper Potts';
// note that we only declare a variable onceNaming rules
In JavaScript, when naming variables, the convention is to name the identifiers using lowerCamelCase. Good examples are numActivePlayers, tacoFlavor, or name.
Identifiers in JS:
- Are case-sensitive
- Cannot begin with a number
- Can contain letters, digits, underscores, and dollar signs
- Cannot contain spaces
- Cannot be reserved words or keywords
โ Is car-3 a valid variable identifier?
let and const
The difference between let and const is that a const variable cannot be re-assigned to - you can assign data to it once, and that's it:
let x = 25;
x = 100; // no problem
const z = 25;
z = 100; // Uncaught TypeError: Assignment to constant variable4. Primitive data types
Primitive types are data types that are stored directly in memory. JavaScript has seven primitive data types, five of which are common and two of which are uncommon.
Here are the common primitive data types in JavaScript:
- String
- Number
- Boolean
- Undefined
- Null
string
A string represents textual data with zero or more characters wrapped by single or double quotation marks, such as "John" or 'Jane'. Either can be used; just be consistent in your code. A pair of quotes with nothing between them is still a string. Specifically, this is an empty string.
let myString = 'Hello World';
let myOtherString = "Hello World again";
console.log(typeof myString);
// Prints: stringNote that the typeof operator returns a string describing the data type.
number
A number represents a numeric value.
Unlike many other programming languages, there is no distinction between integer (15, 3, etc.) and floating-point/decimal types (17.24, 3.1416, etc.).
Internally, JavaScript represents all numbers as floating-point values.
let myNumber = 15;
console.log(typeof myNumber);
// Prints: numberโ What will the following code print to the console?
console.log(typeof 12.34);
boolean
Whereas strings and numbers can have a virtually unlimited number of different values, the boolean data type only has two possible values: true and false.
Booleans are useful for their simplicity, especially when making decisions based on data. For example, say you're building a game. When a player beats the game, you may check the user's score against the current high score of that game and see if a new record has been achieved. This would resolve in one of two ways - either the user has scored higher than the previous high score, or they didn't. This could be represented using boolean values.
undefined
A variable that has not been assigned a value is of type undefined. For example:
let cohort;
console.log(cohort);
// Prints: undefinednull
The null data type has only one value: null. null is the value of a variable that explicitly has no value. Thus, it represents a deliberate and intentional absence of value as opposed to undefined, which only represents a lack of assigned value.
null does have some strange behavior:
console.log(typeof null);
// Prints: object Wait, what? This is a known bug within JavaScript, but it remains to this day because many applications that depend on this (incorrect) behavior have been written.
Because of this, the use of null is somewhat controversial in the JavaScript community.
โ Do all variables have a data type?
๐ You do
Strings, numbers, and booleans are the most common data types used to model real-world application data.
For example, in a multiplayer gaming app, we would represent a player's name using a string.
Let's brainstorm a couple of examples for each of the three common data types that would be used to represent information in that gaming app:
| Data Type | Example Data/Information |
|---|---|
| String | playerName |
| Number | |
| Boolean |
Uncommon primitive data types
There are two uncommon primitive data types in JavaScript:
- Symbol
- BigInt
You're unlikely to encounter them in most circumstances.
5. Template Literals
Combining strings
We can use string interpolation with template literals to combine strings with one another .
Template literals are a special type of string written using the backtick character: `. The key to type the backtick character is above the Tab key and to the left of the 1 key. The greeting string below is written as a template literal.
let username = 'friend';
let greeting = `Hello,`;So what makes these so special? Template literals allow us to combine strings and place them anywhere we want in the template literal. Change the value that is assigned to greeting:
let greeting = `Hello, ${username}.`;As you can see above we use this special syntax ${} inside of the template literal. Then, add a variable name inside of the {}. What happens when we log the greeting?
console.log(greeting);
// Prints: Hello, friend.Anything that resolves to a single value (an expression) can be used inside the ${}.
As an additional note, template literals can span multiple lines. For example:
let longString = `Hello, and welcome to the application!
Get started by logging in below!
We're happy to have you.`;Attempting this with a normal string will cause an error.
๐ You Do
Make use of template literals by sending a greeting to a friend!
Create two variables, myName and friendName. Assign both to different strings. Then, write a short message to your friend using a template literal that uses both variables inside of it.
6. Implicit and Explicit Type Conversion
Type Conversion
JavaScript is very relaxed when it comes to data types. Contrary to non-dynamic languages, a variable can change its type.
let num = 15; // I'm a number
num = 'Hey!'; // Now I'm a string!Beware of implicit conversion
Implicit type conversion is the process of automatically converting one data type to another. JavaScript performs implicit type conversion in various situations, such as when you perform arithmetic operations on values of different types.
JavaScript is friendly and tries to help us whenever it can. However, sometimes this help can backfire if we lack knowledge of these behaviors.
Try adding a string to a number. What did JS do?
Now try comparing a number and a string containing the same digits using the equality (==) comparison operator:
13 == '13';
// true!This is why we use the strict equality operator (===). It will not perform type conversion.
13 === '13';
// false!Explicit type conversion
Explicit type conversion is the process of manually converting one data type to another. You can use the following methods to perform explicit type conversion:
To convert into strings:
using the
toString()methodlet numOne = 123.456; let strOne = numOne.toString(); // "123.456"using the
String()methodlet numTwo = 123.456; let strTwo = String(numTwo); // "123.456"using the
toFixed()methodlet numThree = 123.456; let strThree = numThree.toFixed(2); // "123.46"Note that we must specify the number of decimals we want inside the
()'s.
To convert into numbers:
using the
parseInt()methodlet strFour = '1234.567'; let numFour = parseInt(strFour); // 1234parseInt()rounds down to the nearest whole number.using the
parseFloat()methodlet strFive = '1234.567'; let numFive = parseFloat(strFive); // 1234.567using the
Number()methodlet strSix = '1234.567'; let numSix = Number(strSix); // 1234.567
When to use implicit and explicit type conversion
Implicit type conversion can be convenient but can lead to unexpected results. It's important to be aware of the situations in which JavaScript will perform implicit type conversion.
In general, it's best to use explicit type conversion when we need to be sure that a value is of a certain type. For example, if we're writing a function that expects a number value as a parameter, we should use the Number() function to convert the value to a number before using it in the function.
7. JavaScript Control Flow Concepts
What is control flow?
Control flow in programming refers to the way we manage the order in which code is executed within a program. It's like having a set of instructions and deciding when and how to follow them.
Think of control flow in JavaScript as a traffic light at an intersection. Just as a traffic light regulates the movement of vehicles, pedestrians, and cyclists at a crossing, control flow in code regulates the sequence of actions and decisions that our program takes.
So how do we implement this type of control?
Basic types of control flow
There are several methods for directing how and when our code executes.
Sequence: Statements execute one at a time in succession. This is the default behavior.

Branching: Different code paths are executed based on a conditional expression.

Looping: The code in the loop repeatedly executes while a condition is truthy.

Why is control flow important?
By default, when you run a program, it starts executing from the top line of code and continues sequentially until it reaches the last line. This linear execution doesn't align with the needs of most applications. In reality, we often need to change or manipulate the order of execution to achieve specific goals, such as:
Decision-Making: Sometimes, we need the program to make choices and execute different code paths based on conditions. For example, showing different messages to users based on their input.
Repetition: Many tasks involve performing the same actions multiple times. Control flow allows us to create loops to repeat a set of instructions until a certain condition is met.
User Interaction: Applications often respond to user actions. Control flow lets us manage these interactions, triggering specific actions when users click buttons, enter data, or perform other actions.
Error Handling: Handling errors gracefully is essential. Control flow helps us navigate errors by directing the program to take specific actions when something goes wrong.
In essence, we don't always want our code to run straight from top to bottom. Control flow is the fundamental mechanism that enables us to shape the behavior of our programs, making them smart and adaptable to various scenarios.
7.1 Branching
Branching is a type of control flow that allows for different code paths to be executed based on specific conditions.
if
Single Path
To execute a statement or statements conditionally, use the if statement. Conditional expressions must be surrounded by parenthesis.
The if statement checks a condition โ it's like asking a yes-or-no question. If the answer is 'yes' (which in coding terms means the condition is true), then the code inside the if block will run. If the answer is 'no' (false), the code inside the block will be skipped.
const val = 1;
// Ask: Is val exactly equal to 1?
if (val === 1) {
console.log('This code runs because val is 1');
}
// Since val is 1, the answer is 'yes', so the code inside the if block runs.if...else
Dual Paths
When using an if...else statement, the code inside the if block will be executed if the condition evaluates to true. If the condition evaluates to false, then the code inside the else block will be executed.
Think of if...else like a fork in the road. If the condition in the if part is true, take the first path. Otherwise, take the else path.
const val = 2;
// If path
if (val === 1) {
console.log('val is one');
// Else path
} else {
console.log('val is not one');
// Since val is not 1, the else path is taken, printing 'val is not one'.
}Check out the Ternary Operator for another way to write short dual path branches.
if...else if...else
Three or more paths
If you have three or more code paths, use if with as many else if statements as necessary and optionally a final else.
When you have several conditions to check, think of if...else if...else like multiple doors to choose from. Only one door can be entered, based on which condition is true.
const val = 3;
if (val === 1) {
console.log('val is one');
} else if (val === 2) {
console.log('val is two');
} else if (val === 3) {
console.log('val is three');
} else {
console.log('not one, two, or three');
}
// val is 3, so 'val is three' will be printed.๐ You Do
First, declare and initialize a variable named color.
Then, write a branching statement that console.logs the following based upon the value of color:
- If the value is
green, log'Go' - If the value is
yellow, log'Slow' - If the value is
red, log'Stop' - If the value is anything else, log
'Whatever'
Manipulate the value of color to ensure you're able to log all of the above values.
7.2 Looping
Looping is a control flow mechanism that repeats a set of actions. In programming, these actions are typically code blocks, and they are repeated either until a certain condition is no longer met (while the condition is true) or a specific number of times (for a certain number of iterations). This process is especially crucial when dealing with collections of data, such as arrays or lists, where you might need to examine or manipulate each element in the collection.
for
A for loop repeats until a specific condition evaluates to false. for loops are commonly used to run a block of code a specified number of times. The syntax is as follows:

- The
forkeyword. This keyword starts aforloop, signaling the beginning of a block of code that will repeat a set of actions. initialization- An expression or variable declaration evaluated once before the loop begins. This is where you set up your loop counter. It is evaluated only once at the very start of the loop. For instance,let i = 0;initializes a counter variableito0. Variables declared here are local to the loop.condition- An expression to be evaluated before each loop iteration. Think of this as the 'question' the loop checks before each iteration. If this condition evaluates totrue, the loop's code block runs. If it evaluates tofalse, the loop stops. For example,i < 10; continues the loop as long asiis less than10.afterthought- An expression to be evaluated at the end of each loop iteration. This part of the loop is for updating the loop counter and is evaluated after the code block has executed but before the next iteration's condition check. Commonly, this involves incrementing the counter, likei++.- A code block - The curly braces
{}enclose the actions that you want to repeat in each loop iteration. This is where you put the code that does something, like printing values or modifying elements in an array. - Code to be executed as long as the condition evaluates to
true.
Next, let's examine the order of operations for a for loop, with an example:
for (let i = 1; i < 10; i++) {
console.log(i);
}Step 1
The initialization runs once before looping begins. It is used to declare and initialize a looping variable - in this example, a new variable named i is initialized with the value 1.
Step 2
Theย condition is evaluated. If true, the code block will execute. At the start of this loop, i was just initialized as 1, so i < 10 is true.
Step 3
Theย statementย executes. It prints the current value of i to the console.
Step 4
The update expressionย afterthoughtย is executed. In this example, i is incremented by 1.
Step 5
The loop control returns to Step 2.
Naming descriptive loop counters
In programming, especially with for loops, it's common to see the variable i used as the loop counter. However, it's important to know that i is just a convention and not a requirement. In fact, using more descriptive variable names instead of i can significantly enhance the readability and clarity of your code.
For example, the above for loop could be written as:
for (let number = 1; number < 10; number++) {
console.log(number);
}Here's another example:
for (let day = 1; day <= 7; day++) {
console.log(`Day ${day} of the week`);
}๐ You Do
Write a for loop that iterates from 1 - 20 and logs out the square of each number.
Sample Output:
1 squared is 1
2 squared is 4
3 squared is 9
4 squared is 16
[...]
20 squared is 400Check out this documentation on the exponentiation operator if you need a hint.
8. JavaScript Functions
What is a function?
A function is a reusable block of code written to perform a single purpose. With a function, you can store code that can be used conveniently as many times as you wish without having to rewrite the code each time. As a result, functions are one of the fundamental building blocks of JavaScript, and you'll find and use them everywhere.

Functions optionally take in data as input and return a single piece of data (including complex data such as objects or other functions).
๐ A function is a block of code that can be called as needed and is designed to perform a specific task. A function may accept input and can return a result after completing its task.
Why are functions essential in programming?
Tackle complexity
We typically tackle a complex task by breaking it into smaller tasks or steps - when we're programming, we want to do the same! Functions allow us to break up programs into more manageable blocks of code.
Code reuse
Functions help us reuse code by allowing us to run the same set of instructions multiple times. For example, a renderBoard function might be called every time the data in a board changes.
This helps us avoid repeating the same code in many places โ a principle often called "Don't Repeat Yourself" (or DRY). Writing code this way makes it easier to read, fix, and update later.
Documentation & debugging
Naming functions appropriately, for example a name like renderBoard helps document what that function's job is (to show the user the current game board).Organizing code into functions also makes it easier to find and fix code that's not working as expected, a process known as debugging.
8.1 Function syntax
A function declaration will have the following syntax:

- The
functionkeyword. - The name of the function.
- The body of the function is indicated by curly braces.
- 3a. The statements that make up the function itself.
- 3b. Optionally, a
returnstatement.
Declaring a function
A basic function declaration could look something like this:
function printBanner() {
console.log('=======================');
console.log('Insert Banner Text Here');
console.log('=======================');
}Let's quickly revisit the syntax:
We start with the function keyword.
The name of our function is printBanner - it prints a banner! Functions do something, so we name them with words that indicate action (verbs).
We want to pack as much information as possible into our function names without being overly wordy. Try to avoid function names like getSalesDataAndLaborCostsAndMigrateToNewBudgetReportWithItemizedDates() - sure, it's descriptive, but it's hard to read or recognize at a glance. Also, try to avoid a name like getAllStuff() - it's non-specific to the point of hiding what the function does.
In the body of our function, we are logging three lines of text to the console. These would be our statements.
๐ง A quick note on commenting functions:
Comments should explain why you chose to solve a task a certain way, typically not what the code is doing. If your code is unclear enough to require a comment, it is often best to rewrite it. Well-composed code should generally speak for itself.
Calling a function
Defining a function does not execute it.
A function must be called for it to run.
If we wanted to call the printBanner() function from our previous example, we would do so like this:
printBanner();This text would be printed to the console:
=======================
Insert Banner Text Here
=======================The beauty of functions is their reusability. If we wanted to log this text out twice, rather than having to type out each console log again, we can call the function twice:
printBanner();
printBanner();To get the output:
=======================
Insert Banner Text Here
=======================
=======================
Insert Banner Text Here
=======================๐ง Developers might say call, execute, invoke, or run a function. In the context of functions, these are synonyms.
8.2 What is a return value?
A return value is the output of a function. In other words, it is what a function gives back after it does its job.
If a function does not explicitly return a value, it defaults to returning undefined. This means the function has not been instructed to supply a result.
Often, you may want to use the result of a function for further operations. In such cases, the return statement is used to specify what value a function should output.
The return statement
Use the return keyword to return a value from a function.
The return keyword can only be used inside of functions. When used, it stops the execution of the function, and the function then evaluates to the return value.
Let's look at some examples:
function addOne(num){
return num + 1;
}
console.log(addOne(3));
// Prints: 4The above works as expected! We are returning the result of adding num and 1. Here's a simplified version of this, similar to what you saw in the Concepts section:

function addOne(num){
return 'this is some text';
return num + 1;
}
console.log(addOne(3));
// Prints: 'this is some text'Above, the first return statement blocks the remainder of the code from running! The function stops executing when the first return statement is reached.
function addOne(num){
num + 1;
return;
}
console.log(addOne(3));
// Prints: undefinedFinally, we can see that returning without an expression defaults to undefined.
This is also the case when we omit the return statement entirely, as mentioned earlier:
function addOne(num){
num + 1;
}
console.log(addOne(3));
// Prints: undefinedStoring and using the return value of a function
It is often useful to store the return value of a function. We can assign the return value of a function to a variable, just like any other value.
For instance, if we wanted to store the value of invoking addOne() and passing in 3 as an argument, we could do something like this:
function addOne(num){
return num + 1;
}
// addOne(3) evaluates to 4
const incrementedNum = addOne(3);
// incremetedNum is 4
console.log(incrementedNum);
// Prints: 48.3 Function Expressions Syntax
So far, we've mostly covered function declarations, but you should be aware of another syntax for writing a function: function expressions.
To get a sense of how they're different, let's look at an example function declaration:
function add(numA, numB){
return numA + numB;
}The same function, as a function expression, would look like this:
const add = function(numA, numB) {
return numA + numB;
}Here's a syntax breakdown of this:

- The
constkeyword.constshould be used whenever a function expression is assigned to a variable. - The name of the function.
- The
functionkeyword. - Comma-separated parameters.
- The body of the function is indicated by curly braces.
- 5a. The statements that make up the function itself.
- 5b. Optionally, a
returnstatement.
Note how the code inside of the function doesn't change. The only alteration is the syntax on the first line.
Function expressions: assigning a function to a variable
At first glance, this may look complex, but there is a familiar element here. This is how we declare variables! Instead of assigning the variable to a string or a number, we're assigning it to a function.
Also, note the function itself has no name - function expressions allow us to omit the name and create what is known as an anonymous function.
๐ An anonymous function is any function without a name.
So, if the function doesn't have a name, how do we call it? We use the variable name!
const add = function(a, b) {
return a + b;
}
// called using the variable name:
add(4, 2);9. The Document Object Model (DOM)
The DOM (Document Object Model) is a data representation of a web page loaded in the browser.
The DOM is a tree-like data structure with the top (root) being the document object. It mirrors the tree-like structure of the HTML for a given document. Each element in the DOM is referred to as a node.

JavaScript uses the DOM to access an HTML document and its elements. The DOM has an application programming interface or API that enables developers to make the UI dynamic by using JavaScript.
๐ An API, or Application Programming Interface, is a set of predefined rules or methods that enables communication and data exchange between software components, applications, or systems.
More specifically, the DOM API, is a set of methods and properties provided by web browsers that allow us to interact with and manipulate the structure, content, and attributes of HTML using JavaScript.
Selecting Elements
Before we change an element, we must "select" it.
// Selects the first element that matches the CSS selector
const myButton = document.querySelector('.btn-primary');
// Selects an element by its ID
const mainHeader = document.getElementById('header-title');Modifying Elements
Once selected, we can change properties like text, style, or classes.
// Changing text content
mainHeader.innerText = "Welcome to My Portfolio";
// Changing CSS styles directly
mainHeader.style.color = "blue";
// Adding a CSS class (Best Practice for styling)
mainHeader.classList.add('active');10. Handling User Events
Learning objective: Analyze how variables, functions, and events operate in JS.
Interactive websites wait for the user to do something. These actions are called Events (clicks, key presses, scrolling). We use Event Listeners to "listen" for these actions and run a function in response.
In JavaScript we use the addEventListener() method to attach event listeners to HTML elements in the DOM.
๐ An event listener is a function or piece of code in JavaScript that "listens" for specific events to occur on an HTML element, such as a click, mouseover, or keypress event. When the specified event happens, the event listener executes its associated code, allowing you to respond to user interactions and perform actions on your web page.
Here is the common syntax for doing this:

The element we want to add an event to.
The
addEventListener()method. It accepts two arguments:2a. The
type. This should be a string and indicates the event that the event listener will respond to.2b. The
callbackFunction. ThecallbackFunctionis a function that will be executed when the eventtypewe've specified happens on theelementthat is listening for it.
As a reminder, a callback function is a function passed into another function as an argument. You might recall using callback functions with the
forEach()method. The callback function provided to theforEach()method is executed once for every item inside an array.
The callbackFunction above operates in a very similar way, but the code inside of it will be executed in response to an event triggered buy a user interaction.
โป๏ธ Repeatable Pattern: When working directly with the DOM, we always use the
addEventListener()method to attach event listeners to elements.
The 'click' event
Let's build an event listener that will respond to one of the most common types of events - the 'click' event. We'll add this to the <button id="like-button"> element we created during setup.
An element receives a 'click' event when a mouse's primary button is pressed and released on that item. Other pointing devices can also trigger a 'click' event, such as a finger tapping an element on a mobile device's touch screen. For this lesson, let's assume we are working with mouse clicks.
Let's start by selecting the <button id="like-button"> element from the DOM and create a variable called likeButtonElement to keep track of it.
const likeButtonElement = document.querySelector('#like-button');
// let's log it to confirm
console.dir(likeButtonElement);After you've confirmed that you've selected the <button id="like-button"> element from the DOM, you can remove the console.dir().
Now, let's attach our first event listener to that element:
- To listen for a click event, we'll use the
addEventListener()method and pass the string'click'as thetype. - Then we'll write the callback function so that it logs the string
'You clicked me!'
likeButtonElement.addEventListener('click', () => {
console.log('You clicked me!');
});Return to your browser and open your DevTools. Click on the button element in the browser. You should see a message logged to the console: 'You clicked me!' - congrats! You've built your first event listener!
Common Events
click: When the user clicks an element.submit: When a form is submitted.keydown: When a user presses a key on the keyboard.
11. AI-Assisted Debugging
Learning objective: Use AI to interpret and resolve JavaScript errors.
JavaScript is strict; a missing comma or bracket can break the whole script. Browsers report these issues in the Console tab of Developer Tools.
Debugging Workflow
- Check the Console: Open DevTools > Console. Look for red text.
- Identify the Error: Note the error message (e.g.,
Uncaught ReferenceError: x is not defined) and the line number. - Prompt the AI: Copy the error and your code snippet into the AI.
Example Prompt:
"I am getting an 'Uncaught TypeError: Cannot read property of null' on line 12 of my JavaScript file. Here is my code. What is causing this and how do I fix it?"
The AI helps explain why the error happened (e.g., you tried to add an event listener to a button that doesn't exist on the page yet).
12. Lab: Adding Interactivity to a Web Page
Learning objective: Write JavaScript to control basic page interactions like toggling menus or showing alerts. Use AI to explain and correct coding errors encountered during development.
Overview
In this lab, you will build a simple "Dark Mode" toggle for a web page. You will write the HTML and CSS, then use JavaScript to make the button functional. Finally, you will intentionally break your code to practice AI debugging.
Part 1: Setup HTML & CSS
- Create an
index.htmlfile with a simple heading, a paragraph, and a button withid="theme-toggle". - Create a
style.cssfile. Add a.dark-modeclass that changes the background color to black and text to white. - Link the CSS file in your HTML.
Part 2: Writing the JavaScript
- Create a
script.jsfile and link it at the bottom of your HTML body:<script src="script.js"></script>. - Select the button and the body element using
document.querySelector. - Add a
clickevent listener to the button. - Inside the function, use
element.classList.toggle('dark-mode')on the body.
Part 3: AI Debugging Challenge
- Intentionally introduce a typo. For example, change
addEventListenertoaddListener(which is incorrect/deprecated for this context) or misspell the ID selector. - Refresh the page and open the Console.
- Copy the error message.
- Action: Ask your AI assistant:
"I made a mistake in my code and the console says [Insert Error]. Can you help me spot the syntax error?"
Deliverable
A functional web page where clicking the button toggles the color theme, and a brief note on what the AI explained about your intentional error.
13. Wrap-Up and Reflection
Discussion Questions:
- Why do we place the
<script>tag at the bottom of the HTML file rather than the top? (Hint: Think about how the browser reads code from top to bottom). - What is the difference between changing
style.colorin JavaScript versus toggling a CSS class withclassList? - How did the AI explain the error message you received during the lab?