This topic introduces the fundamentals of creating interactive web pages. It covers:
HTML provides the skeleton of a web page. The syllabus expects knowledge of the following concepts.
<header>, <nav>, <main>, <section>, <article>, <footer><form>, <input>, <select>, <textarea>, validation attributes (required, pattern, min, max)id, class, src, href, alt, title, role<header>, <nav>, <section>…) to give meaning to page structure.alt) and ARIA attributes when native semantics are insufficient:
role="button", role="dialog", aria‑label, aria‑expanded, aria‑controlstabindex="0" only when necessary.<h1> → <h6>) and landmarks (role="main", role="navigation") to aid screen readers.<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My First Web Page</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header>
<h1>Welcome</h1;
</header>
<main id="content" role="main">
<p id="msg">Hello, world!</p>
</main>
<script src="script.js"></script>
</body>
</html>
CSS separates presentation from structure. The syllabus expects knowledge of:
:hover, :focus, :nth-child()) ), child (>), adjacent sibling (+), general sibling (~)margin, border, padding, width/heightblock, inline, inline‑block, flex, gridstatic, relative, absolute, fixed, sticky/* styles.css */
body {
font-family: Arial, sans-serif;
line-height: 1.5;
margin: 0;
padding: 0;
}
#msg {
color: #0066cc;
font-size: 1.2rem;
}
/* Responsive example */
@media (max-width: 600px) {
#msg { font-size: 1rem; }
}
| Component | Role in a Web Transaction |
|---|---|
| Browser (client) | Sends an HTTP request, receives the response, renders HTML/CSS/JS. |
| Web server | Receives the request, processes it (static files or server‑side scripts), returns an HTTP response. |
| HTTP request line | GET /index.html HTTP/1.1 – method, resource, protocol. |
| HTTP response line | HTTP/1.1 200 OK – protocol, status code, reason phrase. |
GET, POST, PUT, DELETE, HEAD200 (OK), 201 (Created), 301 (Moved Permanently), 302 (Found), 400 (Bad Request), 401 (Unauthorized), 403 (Forbidden), 404 (Not Found), 500 (Server Error)User-Agent – identifies the browserAccept – media types the client can process (e.g., text/html, application/json)Accept-Language – preferred language(s)Cookie – sends stored cookies to the serverContent-Type – MIME type of the payload (e.g., text/html)Cache-Control – caching directives (max-age=3600, no‑store)ETag – validator for conditional requestsSet-Cookie – instructs the browser to store a cookieCache-Control and Expires headers.ETag, Last-Modified) allow conditional GET requests.;) – optional but recommended.{ … }.| Keyword | Scope | Hoisting | Re‑assignment |
|---|---|---|---|
var |
Function‑scoped (or global if declared outside a function) | Hoisted & initialised with undefined |
Yes |
let |
Block‑scoped | Hoisted but in the Temporal Dead Zone until the declaration line | Yes |
const |
Block‑scoped | Hoisted with TDZ | No – the binding is constant; objects/arrays it refers to can still be mutated |
Example demonstrating scope and the Temporal Dead Zone:
// global scope
const PI = 3.14159;
function circleArea(r) {
// console.log(area); // ReferenceError – TDZ
let area = PI * r * r;
return area;
}
console.log(circleArea(5)); // 78.53975
| Category | Operators | Typical Use |
|---|---|---|
| Arithmetic | + - * / % ++ -- |
Numeric calculations |
| Assignment | = += -= *= /= %= **= |
Store a value in a variable |
| Comparison | == != === !== > < >= <= |
Produce a Boolean result |
| Logical | && || ! |
Combine Boolean expressions |
| String | + (concatenation) |
Join text values |
| Conditional (ternary) | condition ? expr1 : expr2 |
Inline if‑else |
| Bitwise | & | ^ ~ << >> >>> |
Low‑level integer manipulation (rare in A‑Level but part of the language) |
Use parentheses ( ) to control evaluation order when needed.
if … else, switch – decision makingfor, while, do…while – loopsbreak, continue – alter loop executionExample for loop:
for (let i = 1; i <= 5; i++) {
console.log('Step', i);
}
Functions are reusable blocks of code. Three common ways to define them:
// 1. Function declaration – hoisted
function add(x, y) {
return x + y;
}
// 2. Function expression – not hoisted
const multiply = function (a, b) {
return a * b;
};
// 3. Arrow function – concise syntax, lexical this
const square = n => n * n;
return, it returns undefined.function parseNumber(str) {
try {
const n = Number(str);
if (isNaN(n)) throw new Error('Not a number');
return n;
} catch (err) {
console.error('Parse error:', err.message);
return null;
}
}
.then(), .catch(), .finally().Simple fetch example using async/await:
async function loadUser(id) {
try {
const response = await fetch(`https://api.example.com/users/${id}`);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
return data;
} catch (e) {
console.error(e);
return null;
}
}
// file: mathUtils.js
export function sum(a, b) { return a + b; }
export const PI = 3.14159;
// file: main.js
import { sum, PI } from './mathUtils.js';
console.log(sum(2, 3) * PI);
setTimeout, I/O).// Single element
const header = document.querySelector('header');
// Multiple elements
const buttons = document.querySelectorAll('.btn');
// Legacy methods
const form = document.getElementById('myForm');
const msg = document.getElementById('msg');
// Text content
msg.textContent = 'Welcome to the site!';
// HTML content
msg.innerHTML = '<strong>Hello</strong>';
// Attributes
msg.setAttribute('data-user', 'alice');
msg.dataset.role = 'admin'; // shortcut for data-role
const list = document.querySelector('#todo');
const newItem = document.createElement('li');
newItem.textContent = 'Buy milk';
list.appendChild(newItem); // add at the end
// Remove
list.removeChild(newItem);
// Attach a click handler
document.getElementById('btnCalc').addEventListener('click', function (e) {
e.preventDefault(); // stop default form submit
const radius = Number(document.getElementById('radius').value);
const area = Math.PI * radius * radius;
document.getElementById('result').textContent = area.toFixed(2);
});
Instead of attaching a listener to every child, attach one to a common ancestor and use event.target to determine the actual element that triggered the event.
// HTML: <ul id="menu"> … <li class="item">Item 1</li> … </ul>
const menu = document.getElementById('menu');
menu.addEventListener('click', function (e) {
if (e.target && e.target.matches('li.item')) {
console.log('Clicked:', e.target.textContent);
}
});
const data = [
{ name: 'Alice', age: 28, city: 'London' },
{ name: 'Bob', age: 34, city: 'Manchester' },
{ name: 'Cara', age: 22, city: 'Bristol' }
];
function buildTable(arr) {
const table = document.createElement('table');
const thead = table.createTHead();
const headerRow = thead.insertRow();
// create header cells
Object.keys(arr[0]).forEach(key => {
const th = document.createElement('th');
th.textContent = key.charAt(0).toUpperCase() + key.slice(1);
headerRow.appendChild(th);
});
const tbody = table.createTBody();
arr.forEach(item => {
const row = tbody.insertRow();
Object.values(item).forEach(val => {
const cell = row.insertCell();
cell.textContent = val;
});
});
return table;
}
document.getElementById('tableContainer').appendChild(buildTable(data));
Access-Control-Allow-Origin headers.// Simple GET request with CORS handling
fetch('https://api.example.com/data', { mode: 'cors' })
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.then(json => console.log(json))
.catch(err => console.error('Fetch error:', err));
// localStorage example
localStorage.setItem('theme', 'dark');
const theme = localStorage.getItem('theme'); // 'dark'
// IndexedDB simple example (open a DB, create an object store, add a record)
const request = indexedDB.open('myDB', 1);
request.onupgradeneeded = e => {
const db = e.target.result;
db.createObjectStore('users', { keyPath: 'id' });
};
request.onsuccess = e => {
const db = e.target.result;
const tx = db.transaction('users', 'readwrite');
const store = tx.objectStore('users');
store.add({ id: 1, name: 'Alice' });
};
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#0066cc';
ctx.fillRect(10, 10, 150, 100);
if ('geolocation' in navigator) {
navigator.geolocation.getCurrentPosition(pos => {
console.log('Lat:', pos.coords.latitude, 'Lng:', pos.coords.longitude);
}, err => console.error(err.message));
}
// main.js
const worker = new Worker('worker.js');
worker.postMessage(1000000); // send data to worker
worker.onmessage = e => console.log('Result:', e.data);
// worker.js
self.onmessage = e => {
const n = e.data;
// simple heavy calculation
let sum = 0;
for (let i = 1; i <= n; i++) sum += i;
self.postMessage(sum);
};
// Register service worker (main script)
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('sw.js')
.then(reg => console.log('SW registered', reg.scope))
.catch(err => console.error('SW registration failed', err));
}
// sw.js – simple cache‑first strategy
const CACHE = 'v1';
const ASSETS = [
'/',
'/index.html',
'/styles.css',
'/script.js'
];
self.addEventListener('install', e => {
e.waitUntil(
caches.open(CACHE).then(cache => cache.addAll(ASSETS))
);
});
self.addEventListener('fetch', e => {
e.respondWith(
caches.match(e.request).then(cached => cached || fetch(e.request))
);
});
Access-Control-Allow-Origin in its response.OPTIONS request if the request uses non‑simple methods or custom headers.Examiners expect awareness of common client‑side threats and mitigation techniques.
| Threat | Typical Attack | Mitigation (client‑side) |
|---|---|---|
| Cross‑Site Scripting (XSS) | Injecting malicious script into page content | Escape user input, use textContent instead of innerHTML, set a Content‑Security‑Policy header, validate input on the server. |
| Cross‑Site Request Forgery (CSRF) | Forcing a logged‑in user to perform unwanted actions | Include anti‑CSRF tokens in forms, use SameSite cookies, verify the Origin header on the server. |
| Clickjacking | Embedding a page in a hidden frame to trick users into clicking | Send X‑Frame‑Options: SAMEORIGIN or Content‑Security‑Policy: frame‑ancestors 'self' header. |
| Man‑in‑the‑Middle (MITM) | Intercepting and modifying traffic between client and server | Serve pages over HTTPS, use HSTS, avoid mixed content. |
let and const, describe hoisting and the Temporal Dead Zone.for loop and an if…else statement.try…catch.localStorage and retrieve it; outline how IndexedDB differs.Create an account or Login to take a Quiz
Log in to suggest improvements to this note.
Your generous donation helps us continue providing free Cambridge IGCSE & A-Level resources, past papers, syllabus notes, revision questions, and high-quality online tutoring to students across Kenya.