← Projects/Tutorials/JS 101
MyKeyZ Tutorial · Programming

JS 101

JavaScript is the third pillar of the web. HTML is the skeleton, CSS the skin, JavaScript the muscles. From your first line to an interactive page.

Beginner12 chaptersabout 6 to 8 hoursPrerequisite: CSS 101

Styling first? CSS 101 comes before JS 101.

Chapter 01

Introduction & setup

What is JavaScript — and how do we include it?

Assembly planWhere JavaScript runs

The browser has a built-in JS engine. No server, no installation.

script.jsin the MyFirst Site folder
<script>on all 4 pages, before </body>
JS engine in the browserreads line by line, top to bottom
Consoleconsole.log() shows what is inside

HTML is the skeleton, CSS the skin, JavaScript the muscles.

  • script.js
  • <script src defer>
  • console with F12

JavaScript is the third pillar of the web. HTML is the skeleton, CSS the skin — and JavaScript the muscles. In this chapter you learn what JS can do, how to include it in your MyFirst Site, and you write your first line of JS.

  • What JavaScript is and why it is the third pillar of the web
  • Understanding the difference between HTML, CSS and JavaScript
  • Including JavaScript in your MyFirst Site — the right way!
  • Writing your first line of JS and testing it in the browser
  • Getting to know the browser console, your most important tool

1.1 · What is JavaScript?

TechnologyTaskExample
HTMLStructure & content<button>Click me</button>
CSSLook & layoutbutton { background: blue; }
JavaScriptBehaviour & interactionbutton.onclick = () => alert('Hello!');
Right in the browser! JavaScript runs directly in the browser — no server, no installation. Every browser has a built-in JS engine that runs your code.

1.2 · How does JavaScript "think"?

JS reads your code line by line, from top to bottom. Like a cook following a recipe — step by step.

JavaScript · Order of execution
// JS reads this first
let name = "Mikey";        // Step 1: create a variable
name = "Dante";             // Step 2: change the value
console.log(name);          // Step 3: print "Dante"
// This will NOT print "Mikey" — name was changed!
console.log() is your best friend! With it you can check at any time what is inside a variable. Like an X-ray machine for your code.

1.3 · Including JavaScript — the right way

There are three ways to include JS — we learn all three, but we consistently use the best one.

❌ Way 1 — Inline
HTML
<button onclick="alert('Hi')">Click</button>
<!-- Works, but hard to maintain! -->
⚠️ Way 2 — In the <head>
HTML
<head>
<script src="script.js"></script>
<!-- Problem: JS loads before the HTML is ready! -->
</head>
✅ PASTE INTO FILE — all 4 HTML pages · right before </body>
 <!-- Always include JS just before </body> -->
<script src="script.js" defer></script>
</body>
</html>
What does defer do? It tells the browser: "Download the JS file now, but only run it once the whole HTML has finished loading." That way your JS finds all the HTML elements it needs.
✅ CREATE NEW FILE — script.js in the MyFirst Site folder
// ========================================
// MyFirst Site — script.js
// JS 101 learning project
// ========================================
// Our first "sign of life"
console.log("✅ script.js loaded successfully!");

1.4 · The browser console

The console is like a direct phone line to JavaScript. Here you see what your code does — and where it goes wrong.

BrowserShortcutAlternatively
Chrome / EdgeF12 or Ctrl+Shift+JRight-click → "Inspect" → Console
FirefoxF12 or Ctrl+Shift+KRight-click → "Inspect Element" → Console
SafariCmd+Option+CDeveloper menu → JavaScript Console
Console · type directly and press Enter
> 2 + 2
< 4
> console.log("Hello World!")
< Hello World!

> console.error("This is an error!")
< ❌ This is an error!

> console.warn("Careful!")
< ⚠️ Careful!
⚠️ For development only! Before you publish a page, remove all console.log() calls. Visitors should not see your debug output.

1.5 · Your first lines of JS

✅ PASTE INTO FILE — script.js · below the first console.log
// The current date and time
const now = new Date();
console.log("Page loaded on:", now.toLocaleString("en-GB"));

// Read the page title
console.log("Page title:", document.title);

// Count how many links are on the page
const allLinks = document.querySelectorAll("a");
console.log("Number of links:", allLinks.length);

What is happening here?

  • new Date() — JS asks the browser: "What time is it right now?"
  • document.title — JS reads the <title> tag from the HTML
  • querySelectorAll("a") — JS finds ALL links on the page

The word document is your gateway to the HTML — through document JS can read and change everything on the page. More on that in chapter 6!

Homework — chapter 1
  • Include script.js correctly in all four pages of your MyFirst Site
  • Open each page and check whether script.js loaded successfully! appears in the console
  • Add your own console.log() with your name
  • Type directly into the console: document.body.style.background = "red" — what happens? Why is the change gone after reloading?

→ On to chapter 2: variables & data types

Chapter 02

Variables & data types

How JavaScript stores data — and which kinds there are.

Assembly planContainers for data

A variable is a labelled container. It holds a value of a certain type.

Containerlet changeable, const fixed
content, for example
Text"Mikey"
Number350
True or falsetrue

var is old. Use let or const.

  • let const
  • typeof

Variables are containers for data. Everything your program needs to remember — numbers, text, states — lives in variables.

2.1 · let, const and var

KeywordUseChangeable?
letDefault choice for values that change✅ Yes
constFor values that do not change❌ No
varOld — please do not use any more⚠️ Problematic
JavaScript · Variables
// ✅ let — can be changed
let points = 0;
points = 10;   // OK
// ✅ const — cannot be reassigned
const name = "Mikey";
// name = "Dante";  // ❌ Error! const cannot be changed
// ❌ var — avoid it
var old = "do not use any more";
Rule of thumb: Always use const — and only switch to let when you know the value will change. You never use var.

2.2 · The 6 most important data types

TypeExampleDescription
String"Hello" or 'World'Text, always in quotation marks
Number42 or 3.14Numbers (whole or with decimals)
Booleantrue or falseTrue or false
nullnullDeliberately empty
undefinedundefinedNot assigned yet
Object{ name: 'Mikey' }A collection of data
JavaScript · All types in action
const greeting = "Hello MyKeyZ!";   // String
const points = 42;                     // Number
const isLoggedIn = false;           // Boolean
const user = null;                  // null — no user yet
let result;                            // undefined until a value is assigned
const cave = { name: "Mikey’s Center", points: 100 }; // Object
console.log(typeof greeting);  // "string"
console.log(typeof points);       // "number"
console.log(typeof null);        // "object" ← well-known JS bug!
⚠️ typeof null returns "object" — a historical bug in JS that was never fixed for compatibility reasons. null is not an object!

2.3 · Template literals — strings with variables

JavaScript · Template literals
const name = "Mikey";
const points = 42;

// ❌ Old way — clumsy
console.log("Hello " + name + "! You have " + points + " points.");

// ✅ Template literal — clean and readable
console.log(`Hello ${name}! You have ${points} points.`);

// Expressions work too
console.log(`Double: ${points * 2} points`);  // Double: 84 points
Backticks! Template literals use backticks ` (not normal quotation marks). On a Swiss keyboard: Shift+^ then the space bar.

2.4 · Type coercion

JavaScript · Automatic type conversion
// Number + string = string (concatenation!)
console.log(1 + "2");    // "12" not 3!
// Other operators force a number
console.log("5" - 2);   // 3
console.log("5" * 2);   // 10
// Convert explicitly — always better!
const input = "42";
const num = Number(input);   // 42 as a number
const text = String(42);        // "42" as text
Homework — chapter 2
  • Create 5 variables in script.js — one for each main type
  • Output all 5 with console.log() and typeof
  • Build a template literal that shows your name and the number of tutorials
  • What does console.log(typeof typeof 42) output? Why?

Chapter 03

Operators & conditions

Calculate, compare, decide — the tools of the logician.

Assembly planDeciding

A condition checks something. Depending on the answer, a different path runs.

Valuepoints
ifIs it true?
Answer
Yesthe block in if
Noelse

Always === instead of ==. Three equals signs check type and value.

  • + - * / %
  • === !== < >
  • if else
  • && ||

3.1 · Arithmetic operators

OperatorMeaningExampleResult
+Addition5 + 38
-Subtraction10 - 46
*Multiplication3 * 412
/Division15 / 35
%Modulo (remainder)10 % 31
**Power2 ** 8256
++Increment (+1)i++i = i + 1

3.2 · Comparison operators — == vs ===

⚠️ Always use ===! == converts types automatically and can lead to unexpected results. === (three equals signs) compares type AND value — always safe.
OperatorMeaningExampleResult
==Equal (with type conversion)"5" == 5true ⚠️
===Strictly equal"5" === 5false ✅
!==Strictly not equal"5" !== 5true
<Less than3 < 5true
>=Greater than or equal5 >= 5true

3.3 · Logical operators

JavaScript · &&, ||, !
// && (AND) — both must be true
const canEnter = age >= 16 && hasAccount;

// || (OR) — at least one must be true
const hasAccess = isAdmin || hasPremium;

// ! (NOT) — flips it
const isGuest = !isLoggedIn;

// ?? (Nullish Coalescing) — if null or undefined
const displayName = username ?? "Guest";

3.4 · if / else if / else

JavaScript · Conditions
const points = 75;

if (points >= 90) {
  console.log("Excellent! 🏆");
} else if (points >= 70) {
  console.log("Well done! ✅");
} else if (points >= 50) {
  console.log("Passed 👍");
} else {
  console.log("Try again 💪");
}
// Output: Well done! ✅

3.5 · Ternary operator

JavaScript · condition ? ifTrue : ifFalse
// Long form
let status;
if (isLoggedIn) { status = "Welcome!"; }
else               { status = "Please log in"; }

// Short form (ternary)
const status = isLoggedIn ? "Welcome!" : "Please log in";
const role   = hasPremium   ? "Premium Member" : "Free Member";
Homework — chapter 3
  • Write an if/else chain that outputs "Good morning", "Good afternoon" or "Good night" depending on the time
  • Use new Date().getHours() for the current hour
  • Turn the if/else into a ternary operator
  • What is the difference between 0 == false and 0 === false? Test it!

Chapter 04

Loops & arrays

Managing lists and repeating code — the most powerful duo.

Assembly planList and repetition

An array is a list. A loop goes through it item by item.

Arrayindex starts at 0
Loopfor, forEach
Per itemyour code

The first item is [0], not [1].

  • [ ]
  • push pop length
  • for forEach
  • map filter

4.1 · Arrays

JavaScript · Arrays
const tutorials = ["HTML 101", "CSS 101", "JS 101"];

// Access by index (starts at 0!)
console.log(tutorials[0]);      // "HTML 101"
console.log(tutorials.length); // 3
// Add / remove an element
tutorials.push("Python 101");  // to the end
const last = tutorials.pop(); // remove the last one

4.2 · The most important array methods

MethodWhat it doesReturns
push(x)Adds x to the endNew length
pop()Removes the last elementThe element
filter(fn)Filters by a conditionNew array
map(fn)Transforms every elementNew array
find(fn)Finds the first matching elementThe element
includes(x)Checks whether x is includedtrue / false
join(sep)Joins into a stringString
JavaScript · filter, map, find
const points = [45, 78, 92, 23, 88, 67];

// filter — only points above 70
const good = points.filter(p => p > 70);
console.log(good);  // [78, 92, 88]
// map — double them all
const doubled = points.map(p => p * 2);

// find — first number above 80
const firstBest = points.find(p => p > 80);
console.log(firstBest);  // 92

4.3 · Loops

JavaScript · for, for...of, forEach
// Classic for loop
for (let i = 0; i < 5; i++) {
  console.log(`Round ${i}`);
}

// for...of — elegantly through arrays
const colours = ["Red", "Green", "Blue"];
for (const colour of colours) {
  console.log(colour);
}

// forEach — with index
colours.forEach((colour, index) => {
  console.log(`${index}: ${colour}`);
});
⚠️ Infinite loops! Always make sure your loop stops at some point. When in doubt, use for...of or forEach — they run through automatically.
Homework — chapter 4
  • Create an array with 5 tutorial names and output each one with for...of
  • Filter out all tutorials that have "101" in their name
  • Write a loop that counts from 1–10 and outputs "even" for even numbers
  • What does [1, 2, 3].map(x => x ** 2) do? Work it out in your head first, then test it!

Chapter 05

Functions

Write code once — call it as often as you like.

Assembly planWrite once, call often

A function takes something in, does its work and returns a result.

Inparameter: name
greet()the code block
Out"Hello Mikey!"
  • function
  • return
  • () =>

Functions are reusable blocks of code. CheckMate consists of dozens of functions — here you learn the basis of everything.

5.1 · Declaring and calling

JavaScript · Classic function
function greet(name) {
  return `Hello ${name}! Welcome to the Center.`;
}

console.log(greet("Mikey"));
// Hello Mikey! Welcome to the Center.
function calculateScore(correct, total) {
  const percent = (correct / total) * 100;
  return `${percent.toFixed(1)}%`;
}
console.log(calculateScore(7, 10));  // "70.0%"

5.2 · Arrow functions

JavaScript · Arrow functions
// Classic function
function double(n) { return n * 2; }

// Arrow Function — same function, shorter
const double = (n) => { return n * 2; };

// Even shorter — for a one-line return
const double = n => n * 2;

// All three do the same thing!
console.log(double(21));  // 42
Arrow short form: If the function body consists of just a return, you can leave out the curly braces and return. const square = n => n * n; — neat!

5.3 · Default parameters & scope

JavaScript · Default values and visibility
// Default Parameter
function greet(name = 'Guest') {
  return `Hello ${name}!`;
}
greet('Mikey');  // 'Hello Mikey!'
greet();         // 'Hello Guest!' — the default kicks in
// Scope — global vs local variable
const appName = "MyKeyZ";   // global — visible everywhere
function showApp() {
  const internal = 'only here';  // local — only in this function
console.log(appName);  // ✅
}
// console.log(internal);  // ❌ Error!

5.4 · Callbacks

JavaScript · Functions as parameters
function process(num, operation) {
  return operation(num);
}

const double = n => n * 2;
const square   = n => n * n;

console.log(process(5, double));  // 10
console.log(process(5, square));    // 25
// You already know callbacks! (from chapter 4)
[1,2,3].map(n => n * 10);  // map takes a callback function
Homework — chapter 5
  • Write a function calculateBMI(weight, height) that returns the BMI
  • Write the same function as an arrow function
  • Build a function rateBMI(bmi) that returns "Underweight", "Normal" or "Overweight"
  • Combine both: rateBMI(calculateBMI(70, 1.75)) — what comes out?

Chapter 06

DOM manipulation

JavaScript talks to your HTML — and can change everything.

Assembly planJS talks to the HTML

The DOM is the bridge: find, change and add elements without reloading the page.

script.jsyour code
DOMthe page as a tree
Visible pagechanges right away

If querySelector finds nothing, it returns null. Check the selector.

  • getElementById querySelector
  • textContent classList
  • createElement

The DOM (Document Object Model) is the bridge between JS and HTML. With DOM manipulation you can read, change, add or remove any element — without reloading the page.

6.1 · Finding elements

MethodFindsReturns
getElementById('id')One element by IDElement or null
querySelector('css')First matching elementElement or null
querySelectorAll('css')All matching elementsNodeList
JavaScript · Finding elements
// By ID — fastest method
const cave = document.getElementById('cave');

// By CSS selector — most flexible method
const title = document.querySelector('.title');
const firstLink = document.querySelector('nav a');

// All elements
const allButtons = document.querySelectorAll('button');
allButtons.forEach(btn => console.log(btn.textContent));

6.2 · Reading and changing content

JavaScript · DOM manipulation
const title = document.querySelector('h1');

title.textContent = 'Hello Mikey!';        // change the text
title.innerHTML = '<em>Italic</em> and normal'; // set HTML
// Change CSS directly
title.style.color = 'var(--coral)';

// Control classes
const card = document.querySelector('.card');
card.classList.add('active');
card.classList.remove('hidden');
card.classList.toggle('darkmode');  // on/off
⚠️ Careful with innerHTML! Use textContent for plain text — innerHTML only for your own HTML code. Never set user input directly as innerHTML (XSS risk)!

6.3 · Creating and inserting elements

JavaScript · createElement
const newItem = document.createElement('li');
newItem.textContent = 'New tutorial';
newItem.classList.add('tutorial-item');

const list = document.querySelector('#tutorial-list');
list.appendChild(newItem);  // to the end
list.prepend(newItem);     // to the start
newItem.remove();           // remove
Homework — chapter 6
  • Add a button: <button id="magic">Click me!</button>
  • Write JS that sets the background to a random colour on click
  • Tip: document.body.style.background and Math.random()
  • Show a message in the HTML (not alert!) — create a <p id="message">

Chapter 07

Events & interactivity

Reacting to clicks, keys and mouse movements.

Assembly planReacting

An event happens, a listener is waiting, a function answers.

Eventclick, input, keydown
addEventListenerlistens
Your functiongets the event object
Page changesthrough the DOM

onclick = overwrites the previous handler. addEventListener does not.

  • addEventListener
  • click input submit keydown
  • e.target

7.1 · addEventListener

JavaScript · Binding events properly
const btn = document.querySelector('#myButton');

// ❌ Not like this — overwrites earlier handlers
btn.onclick = () => console.log("Click 1");
btn.onclick = () => console.log("Click 2");  // overwrites Click 1!
// ✅ Like this — several handlers possible
btn.addEventListener('click', () => console.log("Click 1"));
btn.addEventListener('click', () => console.log("Click 2"));  // both run!

7.2 · The most important events

EventWhen it firesElement
clickMouse clickbutton, a, div
inputOn every inputinput, textarea
changeWhen the field is leftinput, select
submitSubmitting a formform
keydownKey presseddocument, input
mouseoverMouse over itdiv, img
DOMContentLoadedHTML finished loadingdocument

7.3 · The event object & a practical example

JavaScript · Live search with the input event
const searchField = document.querySelector('#search');
const list    = document.querySelectorAll('.tutorial-item');

searchField.addEventListener('input', (e) => {
  const searchText = e.target.value.toLowerCase();

  list.forEach(item => {
    const text = item.textContent.toLowerCase();
    item.style.display = text.includes(searchText) ? '' : 'none';
  });
});
// Type, type → filtered live!

7.4 · Event delegation

JavaScript · One listener for all
// ✅ Event delegation — one listener on the container
document.querySelector('#container').addEventListener('click', (e) => {
  if (e.target.classList.contains('btn')) {
    handler(e.target);
  }
});
// Also works for buttons added later!
Homework — chapter 7
  • Build a character counter: show live how many characters have been typed into a text field
  • Keyboard shortcut: Ctrl+K should make an alert appear
  • Toggle: a button switches a div between visible and invisible
  • 5 coloured buttons — a click changes the body background to that colour

Chapter 08

Objects & JSON

The most important data structure in JS — and the format of the internet.

Assembly planObject and JSON

An object groups related values. As JSON text it travels to storage and servers.

Object{ name, points }
JSON textjust text, readable everywhere
an object againdata.name
  • { }
  • obj.key obj["key"]
  • JSON.stringify JSON.parse

8.1 · Creating objects

JavaScript · Objects
const user = {
  name: "Mikey",
  points: 350,
  premium: true,
  cave: "Mikey’s Creative Lab",
};

// Dot notation
console.log(user.name);      // 'Mikey'
// Bracket notation (for dynamic keys)
const field = "name";
console.log(user[field]);     // 'Mikey'
// Add a property
user.badges = ['HTML Master', 'CSS Pro'];

8.2 · Methods, destructuring & spread

JavaScript · Methods & destructuring
const cave = {
  name: "Mikey’s Center",
  visitors: 0,
  enter() {
    this.visitors++;
    return `Welcome to ${this.name}!`;
  }
};

// Destructuring — unpack properties
const { name, points } = user;

// Spread — copy/extend an object
const extended = { ...user, role: 'admin' };

8.3 · JSON

JSON = JavaScript Object Notation. A text format for exchanging data. Keys must be in double quotation marks, methods are not allowed.
JavaScript · JSON.stringify & JSON.parse
const user = { name: 'Mikey', points: 350 };

// JS object → JSON string
const json = JSON.stringify(user);
// '{"name":"Mikey","points":350}'
// JSON string → JS object
const data = JSON.parse('{"name":"Mikey","points":350}');
console.log(data.name);  // 'Mikey'
// Nicely formatted (for debugging)
console.log(JSON.stringify(user, null, 2));
Homework — chapter 8
  • Create an object for your Center with name, points, completed_tutorials (array) and premium
  • Add two methods: info() and complete_tutorial(name)
  • Serialise it with JSON.stringify() and parse it back again
  • What happens when you use JSON.stringify() on an object with a method?

Chapter 09

Fetch & async ⏳

Loading data from APIs — the web lives on it.

Assembly planData from another server

fetch asks an API. await waits for the answer while the page keeps running.

Your pagefetch(url)
Internetrequest goes out
API serverfor example weather data
Answer as JSONresponse.json()

Without internet or on an error: try/catch catches it.

  • async await
  • fetch
  • try catch

With fetch() you can load data from APIs — weather, exchange rates, user information. async/await makes it elegant.

9.1 · Synchronous vs. asynchronous

JavaScript · Asynchronous code
console.log('1');
setTimeout(() => console.log('2 (after 1 second)'), 1000);
console.log('3');  // runs BEFORE the '2'!
// Output: 1, 3, 2

9.2 · async / await — the clean way

JavaScript · fetch with async/await
async function loadWeather() {
  try {
    const response = await fetch(
      'https://api.open-meteo.com/v1/forecast?latitude=47.42&longitude=9.37&current_weather=true'
    );
    const data = await response.json();
    console.log('Temperature:', data.current_weather.temperature);
  } catch (error) {
    console.error('Error:', error);
  }
}

loadWeather();

What does await do?

  • await pauses execution inside the async function and waits for the promise
  • The rest of the page keeps running — no freezing!
  • async functions always return a promise
  • try/catch catches errors — network errors, invalid JSON responses, etc.

9.3 · Showing API data on the page

✅ Example — showing the weather for St. Gallen
async function showWeather() {
  const url = 'https://api.open-meteo.com/v1/forecast?latitude=47.42&longitude=9.37&current_weather=true';
  const display = document.querySelector('#weather');
  display.textContent = 'Loading...';
  try {
    const res  = await fetch(url);
    const data = await res.json();
    display.textContent = `St. Gallen: ${data.current_weather.temperature}°C`;
  } catch {
    display.textContent = "Error while loading";
  }
}
document.querySelector('#loadBtn').addEventListener('click', showWeather);
Homework — chapter 9
  • Call the Open-Meteo API for St. Gallen and show the temperature in the console
  • Show the result on the page — in a <div id="weather">
  • Add a "Loading..." indicator while the request is running
  • Recreate an error case — what happens with a wrong URL?

Chapter 10

localStorage & state

Storing data permanently — even after closing the tab.

Assembly planRemembering beyond the tab

localStorage stores text in the browser. It is still there after closing.

Objectcave
localStorageonly in this browser, text only
on the next visitan object again

localStorage only stores strings. Convert objects with JSON first.

  • setItem getItem removeItem
  • JSON.stringify JSON.parse

10.1 · localStorage basics

JavaScript · localStorage
// Save — strings only!
localStorage.setItem("username", "Mikey");

// Read
const name = localStorage.getItem("username");

// Delete
localStorage.removeItem("username");

// Objects with JSON
const cave = { name: 'Mikey’s Center', points: 350 };
localStorage.setItem('cave', JSON.stringify(cave));

const loaded = JSON.parse(localStorage.getItem("cave"));
console.log(loaded.name);  // 'Mikey’s Center'

10.2 · State management pattern

JavaScript · Persistent counter — the complete pattern
// Load state (or default)
let state = {
  count: JSON.parse(localStorage.getItem("count")) || 0
};

function render() {
  document.querySelector("#display").textContent = state.count;
}

function save() {
  localStorage.setItem("count", JSON.stringify(state.count));
}

document.querySelector("#plus").addEventListener("click", () => {
  state.count++;
  render();
  save();
});

render();  // Show initially
Single source of truth: Your state is the only truth. The UI mirrors the state — never the other way round. State changes → render again. That keeps state and UI in sync.
⚠️ localStorage limits: Only ~5MB per domain. Strings only. Never store passwords! Synchronous — blocks with large data. For complex apps: Supabase.
Homework — chapter 10
  • Build a visitor counter: every time the page loads, the counter goes up
  • Show the counter on the page
  • Add a "Reset" button
  • Also store the date of the last visit and show it

Chapter 11

JS in practice

Everything together — MyFirst Site becomes truly interactive.

Assembly planEverything together in script.js

Three functions make your MyFirst Site interactive.

script.jsone file for all pages
Functions
Dark moderemembers the choice with localStorage
Active navigationshows where you are
Live clock and smooth scrollruns in the background
  • chapters 1 to 10
  • script.js

Now we bring everything together! In this chapter you make your MyFirst Site truly interactive — with everything you learnt in chapters 1–10.

11.1 · Dark mode toggle

✅ PASTE INTO FILE — script.js
// ── Darkmode ──────────────────────────────────────
function initDarkmode() {
  const toggle = document.querySelector('#darkmode-toggle');
  if (!toggle) return;

  const saved = localStorage.getItem("darkmode") === "true";
  document.body.classList.toggle('dark', saved);

  toggle.addEventListener('click', () => {
    const isDark = document.body.classList.toggle('dark');
    localStorage.setItem("darkmode", isDark);
    toggle.textContent = isDark ? '☀️ Lightmode' : '🌙 Darkmode';
  });
}
initDarkmode();

11.2 · Active navigation

✅ PASTE INTO FILE — script.js
// ── Active nav ────────────────────────────────────
function markActiveNavigation() {
  const currentPage = window.location.pathname.split('/').pop() || 'index.html';
  document.querySelectorAll('nav a').forEach(link => {
    const linkTarget = link.getAttribute('href');
    link.classList.toggle('active', linkTarget === currentPage);
  });
}
markActiveNavigation();

11.3 · Live clock & smooth scroll

✅ PASTE INTO FILE — script.js
// ── Live clock ──────────────────────────────────────
function startLiveClock() {
  const display = document.querySelector('#clock');
  if (!display) return;
  function update() {
    display.textContent = new Date().toLocaleTimeString("en-GB");
  }
  update();
  setInterval(update, 1000);
}
startLiveClock();

// ── Smooth Scroll ─────────────────────────────────
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
  anchor.addEventListener('click', (e) => {
    e.preventDefault();
    const target = document.querySelector(anchor.getAttribute('href'));
    if (target) target.scrollIntoView({ behavior: "smooth" });
  });
});
Init function pattern: Every function first checks whether the element exists (if (!toggle) return;). That way the same script.js can run on every page without errors.
Homework — chapter 11
  • Build all four functions into your MyFirst Site
  • Add a <button id="darkmode-toggle">🌙 Darkmode</button> to index.html
  • Insert a <span id="clock"> and test the live clock
  • Make the dark mode button change its emoji (/) depending on the current mode

Chapter 12

PWA basics

The final chapter — your site becomes an app.

Assembly planFrom page to app (preview)

A PWA is a website you can install and that also works offline.

Your siteas before
Manifestmakes it installable
Service workerworks offline
Appon the home screen

This chapter unlocks when the Community Center starts.

🔒
This chapter is for Center members

Registration on mykeyz.ch is not open yet. As soon as the Community Center launches, this chapter will be unlocked.

What awaits you in chapter 12:

Why PWA? PWAs are the future of the mobile web. Installable like apps, work offline, push messages — all without an app store. CheckMate, WeeklyPlan, OffGrid PowerOn — all PWAs!
JS 101 — completely finished!

This is no longer an exercise — this is real JavaScript!

  • Including JavaScript in HTML — the right way!
  • Variables, types and operators
  • Arrays, loops and functions
  • DOM manipulation and events
  • Objects, JSON and APIs
  • localStorage and state management
  • MyFirst Site made fully interactive
What comes next?
PWA 101 — build your first real installable app with everything you have learnt!

→ PWA 101 is in preparation.