JavaScript (JS) is the language that makes web pages interactive. HTML gives structure, CSS controls presentation, and JavaScript adds behaviour (for example: opening a menu, validating a form, loading content without reloading the page, and updating the page based on user actions).
This topic focuses on core JavaScript concepts and how to use them to work with the DOM (Document Object Model).
1) JavaScript in the Browser: What the DOM Is
When a browser loads an HTML page, it builds a live “tree” representation of the page called the DOM. JavaScript can:
- Read what is on the page (text, attributes, input values)
- Change what is on the page (update text, add/remove elements, toggle classes)
- React to the user (clicks, typing, submitting forms, scrolling)
Think of the DOM as JavaScript’s way to access and control the HTML.
2) Variables and Data Types
Variables store values so you can reuse them and change them.
let, const, and var
const: use when the variable reference should not change (recommended default).let: use when you need to reassign a new value.var: older style; avoid in modern code unless you must support very old patterns.
const siteName = "My Portfolio";
let itemsInCart = 0;
itemsInCart = 3; // allowed because it's let
// siteName = "New Name"; // not allowed because it's const
Common data types
- String:
"Hello" - Number:
42 - Boolean:
true/false - Null: explicitly “nothing”
- Undefined: not assigned
- Object:
{ name: "Ayesha" } - Array:
["Home", "About", "Contact"]
const user = { name: "Ayesha", isMember: true };
const pages = ["Home", "Services", "Contact"];
3) Operators and Basic Logic
You will often compare values and make decisions.
Comparison and equality
===(strict equality) compares value and type (recommended)==(loose equality) converts types (avoid most of the time)
console.log(5 === "5"); // false
console.log(5 == "5"); // true (type conversion happens)
Conditionals (if, else)
const age = 17;
if (age >= 18) {
console.log("You may proceed.");
} else {
console.log("You must be 18 or older.");
}
Logical operators
&&(and)||(or)!(not)
const isLoggedIn = true;
const isAdmin = false;
if (isLoggedIn && isAdmin) {
console.log("Show admin dashboard");
}
4) Functions: Reusable Behaviour
Functions group steps into reusable blocks.
Function declaration
function greet(name) {
return `Hello, ${name}`;
}
console.log(greet("Sibusiso"));
Arrow functions (common in modern JS)
const add = (a, b) => a + b;
console.log(add(2, 3));
Why functions matter in DOM work
You will frequently write functions to:
- validate inputs
- update the UI
- handle events (click, submit, input)
5) Selecting Elements in the DOM
To interact with the page, you first select elements.
Common selectors
document.querySelector()returns the first matchdocument.querySelectorAll()returns all matches (a NodeList)
const heading = document.querySelector("h1");
const navLinks = document.querySelectorAll(".nav a");
const emailInput = document.querySelector("#email");
Tip: Use IDs for unique elements (#email) and classes for groups (.nav a).
6) Reading and Changing Content
Once you have an element, you can read or update it.
Text updates
textContentsets/gets text onlyinnerHTMLsets/gets HTML (use carefully)
const message = document.querySelector("#message");
message.textContent = "Saved successfully.";
Use innerHTML only when you control the content (to avoid security issues like XSS):
const list = document.querySelector("#items");
list.innerHTML = "<li>Milk</li><li>Bread</li>";
Attributes
const logo = document.querySelector("img");
logo.setAttribute("alt", "Company logo");
console.log(logo.getAttribute("src"));
7) Changing Styles with Classes (Preferred)
Avoid setting inline styles directly where possible. Prefer toggling classes so CSS remains responsible for design.
const banner = document.querySelector(".banner");
banner.classList.add("banner--success");
banner.classList.remove("banner--error");
banner.classList.toggle("is-hidden");
In CSS you might have:
.is-hidden { display: none; }
This keeps your code clean and easier to maintain.
8) Events: Reacting to User Actions
An event is something that happens in the browser: a click, key press, form submit, input change, etc.
You attach an event listener to an element:
const button = document.querySelector("#saveBtn");
button.addEventListener("click", () => {
console.log("Button clicked");
});
Common events you will use often
click(buttons, links, cards)submit(forms)input(live typing in a field)change(select menus, checkbox changes)keydown(keyboard interaction)
9) Example: Toggle a Mobile Menu
This is a common real-world pattern: clicking a hamburger button opens/closes navigation.
HTML
<button id="menuBtn" aria-expanded="false" aria-controls="mainNav">
Menu
</button>
<nav id="mainNav" class="nav is-hidden">
<a href="#home">Home</a>
<a href="#about">About</a>
<a href="#contact">Contact</a>
</nav>
CSS
.is-hidden { display: none; }
JavaScript
const menuBtn = document.querySelector("#menuBtn");
const mainNav = document.querySelector("#mainNav");
menuBtn.addEventListener("click", () => {
const isHidden = mainNav.classList.toggle("is-hidden");
menuBtn.setAttribute("aria-expanded", String(!isHidden));
});
Accessibility note (WCAG-friendly):
aria-expandedcommunicates state to screen readers.- Using a real
<button>ensures keyboard support by default.
10) Example: Form Validation (Client-Side)
Client-side validation improves user experience, but it does not replace server-side validation.
HTML
<form id="signupForm" novalidate>
<label for="email">Email</label>
<input id="email" name="email" type="email" />
<p id="emailError" class="error is-hidden">Please enter a valid email address.</p>
<button type="submit">Sign up</button>
</form>
JavaScript
const form = document.querySelector("#signupForm");
const email = document.querySelector("#email");
const emailError = document.querySelector("#emailError");
function isValidEmail(value) {
// Simple pattern; real-world apps may use more robust checks.
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
}
form.addEventListener("submit", (event) => {
const emailValue = email.value.trim();
if (!isValidEmail(emailValue)) {
event.preventDefault(); // stop form submission
emailError.classList.remove("is-hidden");
email.setAttribute("aria-invalid", "true");
email.focus();
return;
}
// Valid state
emailError.classList.add("is-hidden");
email.removeAttribute("aria-invalid");
});
Good practice:
- Use
trim()to avoid spaces causing false “valid” inputs. - Give feedback near the field.
- Move focus to the first invalid field.
11) Creating, Adding, and Removing Elements
You can build dynamic content (for example: a list of tasks, comments, products).
const list = document.querySelector("#taskList");
const addBtn = document.querySelector("#addTaskBtn");
const input = document.querySelector("#taskName");
addBtn.addEventListener("click", () => {
const name = input.value.trim();
if (name === "") return;
const li = document.createElement("li");
li.textContent = name;
// Add a remove button inside the list item
const removeBtn = document.createElement("button");
removeBtn.type = "button";
removeBtn.textContent = "Remove";
removeBtn.addEventListener("click", () => {
li.remove();
});
li.appendChild(removeBtn);
list.appendChild(li);
input.value = "";
input.focus();
});
This pattern is useful for:
- To-do lists
- Cart items
- Adding form sections dynamically
12) Event Bubbling and Event Delegation (Useful for Dynamic Lists)
If you add items dynamically, attaching listeners to each new item can get messy. Event delegation attaches one listener to a parent and checks what was clicked.
const list = document.querySelector("#taskList");
list.addEventListener("click", (event) => {
if (event.target.matches("button.remove")) {
const li = event.target.closest("li");
li.remove();
}
});
This works well when list items are created later.
13) Practical Tips for Clean, Reliable JavaScript
- Put your script at the end of
<body>, or usedeferin the<head>:<script src="app.js" defer></script> - Keep behaviour in JS, styling in CSS, structure in HTML.
- Use
constby default; switch toletonly when needed. - Use
===for comparisons. - Prefer class toggling over inline styling.
- Always consider keyboard and screen reader users when building interactions.
14) Mini-Checklist: What You Should Be Able to Do After This Topic
You should be able to:
- declare variables with
letandconst - write and call functions (including arrow functions)
- select DOM elements with
querySelector/querySelectorAll - update text and attributes safely
- add and remove classes to change UI state
- handle common events (
click,submit,input) - create and append elements dynamically
- build simple interactive features like menus and form validation