In the previous level of our Shopping List project, we built a simple app that allowed us to add and remove items dynamically. However, all the JavaScript code was still mixed inside the HTML, using inline onclick attributes.
Now in Level 3, we take a major step forward:
✅ We separate JavaScript from HTML
✅ We use addEventListener() to handle events the modern way
✅ We introduce conditional logic using if statements
✅ We write cleaner, more reusable and secure code
Why Separate JavaScript from HTML?
At first, writing everything in one file may seem easier. But as your project grows, mixing behavior (JavaScript) with structure (HTML) becomes messy and hard to maintain.
By separating code:
- ✅ HTML focuses on structure
- ✅ JavaScript handles behavior
- ✅ Each part is easier to read, debug, and reuse
📌 Reusable code also means we need to write it safely, checking that elements actually exist on the page before using them.
Project Folder Structure
We’ll use two files:
pgsqlCopyEditshopping-list/
├── index.html
└── script.js
The HTML File – Structure Only
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Shopping List - Level 3</title>
</head>
<body>
<h1>My Shopping List</h1>
<input type="text" id="itemInput" placeholder="Add item..." />
<button id="addItemBtn">Add</button>
<ul id="shoppingList"></ul>
<!-- Link to external JavaScript -->
<script src="script.js"></script>
</body>
</html>
✅ No more onclick in the button. All behavior is now handled inside script.js.
The JavaScript File – Behavior Only
const itemInput = document.getElementById('itemInput');
const addItemBtn = document.getElementById('addItemBtn');
const shoppingList = document.getElementById('shoppingList');
// Check if all elements exist before adding behavior
if (itemInput && addItemBtn && shoppingList) {
addItemBtn.addEventListener('click', function () {
const itemText = itemInput.value.trim();
// Conditional logic: only proceed if input is not empty
if (itemText !== '') {
const li = document.createElement('li');
li.textContent = itemText;
// Add click event to remove the item
li.addEventListener('click', function () {
shoppingList.removeChild(li);
});
shoppingList.appendChild(li);
itemInput.value = '';
} else {
alert('Please enter an item.');
}
});
}
Explaining the Code – Step by Step
getElementById()
This function selects an HTML element by its id. We use it to interact with specific parts of the page.
addEventListener()
This is the modern way to assign actions to events like clicks or keyboard input.
Benefits:
- HTML stays clean
- You can assign multiple listeners
- More flexibility and scalability
if (itemText !== '')
This is a conditional statement. It checks whether the user entered some text.
If true, it runs the code inside { ... }.
If false, it shows an error message.
Think of it like a traffic light:
- If green → go
- If red → stop
createElement() and appendChild()
These methods allow us to:
- Dynamically create new elements
- Add them to the page
- Attach behavior (like click events) as we go
Verifying Elements Exist
If you reuse the same script.js in different pages, some elements might not be there. That’s why we check for their presence:
if (itemInput && addItemBtn && shoppingList) {
// Only run this code if everything exists
}
This prevents JavaScript errors like Cannot read properties of null.
Advantages of This Approach
| Benefit | Description |
|---|---|
| ✅ Clean separation | Each file has one job: structure or behavior |
| ✅ Reusability | One script file can be used on multiple pages |
| ✅ Easier maintenance | You know exactly where to fix things |
| ✅ Safe conditions | Code won’t run if required elements aren’t present |
Summary: What We Learned
| Concept | Purpose |
|---|---|
getElementById() | Select page elements by ID |
addEventListener() | React to user actions (clicks, input, etc.) |
if (condition) | Decide whether or not to run a block of code |
createElement() | Create HTML elements on the fly |
appendChild() | Add an element to the page |
removeChild() | Remove an element from the page |
What’s Next?
In Level 4, we’ll explore:
- How to edit existing list items
- Apply dynamic CSS classes
- Save the list in your browser using
localStorage
Ready to keep going?
Leave a comment or jump to the next step in your learning journey!
