MULT-114

Web Development 3

Credits: 4 Hours: 60 Semester: 2 Corequisite: MULT-124 Methods: Lab, Theory

HTML gives your page structure. CSS makes it look good. JavaScript makes it do things. This is the course where your websites stop being static brochures and start being interactive experiences. Buttons that work. Forms that validate. Content that responds to what users do.

By the end of this course, you'll understand JavaScript fundamentals, be comfortable manipulating the DOM, and have built four real interactive features you can use in your own projects. No frameworks โ€” just vanilla JavaScript. You need to understand the foundation before you add layers on top.

1
JavaScript Fundamentals
โ–ถ

JavaScript is the programming language of the web. Every browser has a JavaScript engine built in. When you write JS, the browser reads and executes it โ€” no compilation, no server required. Open your browser's developer tools (F12 โ†’ Console tab) and you can start writing JavaScript right now.

Variables

Variables store data. Think of them as labeled boxes you put values in.

// Three ways to declare variables:
let userName = 'Kiarra';      // Can be reassigned later
const maxItems = 10;           // Cannot be reassigned โ€” use for constants
var oldWay = 'avoid this';     // Old syntax โ€” use let/const instead

// Reassigning:
userName = 'Zephyra';         // โœ… Works โ€” let allows reassignment
// maxItems = 20;              // โŒ Error โ€” const can't be reassigned

Rule of thumb: Use const by default. Switch to let only when you need to reassign. Never use var.

Data Types

JavaScript has a few core data types you need to know:

// Strings โ€” text, wrapped in quotes
const greeting = 'Hello, world!';
const name = "Kiarra";
const template = `Welcome, ${name}!`;  // Template literal โ€” use backticks for interpolation

// Numbers โ€” integers and decimals, no distinction
const age = 28;
const price = 9.99;
const total = price * 3;       // 29.97

// Booleans โ€” true or false
const isLoggedIn = true;
const hasAccess = false;

// Arrays โ€” ordered lists
const colors = ['red', 'green', 'blue'];
console.log(colors[0]);        // 'red' (arrays are 0-indexed)
console.log(colors.length);    // 3

// Objects โ€” key-value pairs
const user = {
  name: 'Kiarra',
  age: 28,
  isCreator: true
};
console.log(user.name);        // 'Kiarra'
console.log(user['age']);      // 28

Operators

// Arithmetic
5 + 3    // 8
10 - 4   // 6
3 * 7    // 21
20 / 4   // 5
17 % 5   // 2 (remainder/modulo)

// Comparison (use === not ==)
5 === 5      // true (strict equality โ€” checks value AND type)
5 === '5'    // false (number vs string)
5 == '5'     // true (loose equality โ€” avoid this, it's confusing)
10 > 5       // true
3 <= 3       // true
'a' !== 'b'  // true (strict inequality)

// Logical
true && true     // true (AND โ€” both must be true)
true || false    // true (OR โ€” at least one must be true)
!true            // false (NOT โ€” flips the value)

The Console

Your best friend while learning JavaScript is console.log(). It prints values to the browser console so you can see what's happening:

const name = 'Kiarra';
const items = 3;
console.log('Name:', name);              // Name: Kiarra
console.log('Items:', items);            // Items: 3
console.log(`${name} has ${items} items`);  // Kiarra has 3 items

Open DevTools (F12), go to Console, and practice. Type expressions directly โ€” the console will evaluate them and show the result. This is the fastest way to learn.

๐Ÿ’ก Key Takeaway

JavaScript variables hold data, and there are only a handful of types you'll use daily: strings, numbers, booleans, arrays, and objects. Master these and you can build anything.

๐Ÿ”จ Exercise 1.1: Console Playground

Open your browser console (F12 โ†’ Console) and complete these tasks:

  1. Create variables for your name, age, and favorite color using const
  2. Create an array of 5 of your favorite websites
  3. Create an object representing a product (name, price, description, inStock)
  4. Use console.log() to print a sentence using template literals that includes data from your object
  5. Use comparison operators to check if the product price is greater than 20

Deliverable: Screenshot of your console output. Paste your code into a .js file and save it.

2
Control Flow & Functions
โ–ถ

So far, your code runs top to bottom, one line after another. Control flow lets you make decisions and repeat actions. Functions let you package code into reusable chunks. This is where programming starts to feel powerful.

Conditional Statements (if/else)

Conditionals let your code make decisions based on whether something is true or false:

const age = 25;

if (age >= 18) {
  console.log('You are an adult');
} else if (age >= 13) {
  console.log('You are a teenager');
} else {
  console.log('You are a child');
}

// Ternary operator โ€” shorthand for simple if/else
const status = age >= 18 ? 'adult' : 'minor';
console.log(status);  // 'adult'

Loops

Loops repeat code multiple times. Two main types:

// for loop โ€” when you know how many times to repeat
for (let i = 0; i < 5; i++) {
  console.log(`Iteration ${i}`);  // 0, 1, 2, 3, 4
}

// for...of loop โ€” iterate over arrays (much cleaner)
const platforms = ['Reddit', 'Twitter', 'Instagram', 'TikTok'];
for (const platform of platforms) {
  console.log(`Check out ${platform}`);
}

// forEach โ€” array method for iterating
platforms.forEach((platform, index) => {
  console.log(`${index + 1}. ${platform}`);
});

// while loop โ€” when you don't know how many times
let count = 0;
while (count < 3) {
  console.log(`Count: ${count}`);
  count++;
}

Function Declarations

Functions are reusable blocks of code. Define once, use anywhere:

// Function declaration
function greet(name) {
  return `Hello, ${name}!`;
}
console.log(greet('Kiarra'));  // 'Hello, Kiarra!'

// Function with multiple parameters
function calculateTotal(price, quantity, taxRate) {
  const subtotal = price * quantity;
  const tax = subtotal * taxRate;
  return subtotal + tax;
}
console.log(calculateTotal(9.99, 3, 0.08));  // 32.3676

// Default parameters
function createUser(name, role = 'viewer') {
  return { name, role };
}
console.log(createUser('Kiarra'));           // { name: 'Kiarra', role: 'viewer' }
console.log(createUser('Jasper', 'admin'));   // { name: 'Jasper', role: 'admin' }

Arrow Functions

Arrow functions are a shorter syntax for writing functions. You'll see them everywhere in modern JavaScript:

// Regular function
function double(n) {
  return n * 2;
}

// Arrow function (same thing)
const double = (n) => {
  return n * 2;
};

// Arrow function (even shorter โ€” implicit return)
const double = (n) => n * 2;

// Arrow function with no parameters
const sayHello = () => 'Hello!';

// Practical example: filtering an array
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const evens = numbers.filter(n => n % 2 === 0);
console.log(evens);  // [2, 4, 6, 8, 10]

const doubled = numbers.map(n => n * 2);
console.log(doubled);  // [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

When to use which: Use arrow functions for short, simple operations (callbacks, array methods). Use regular function declarations for named functions that form the core of your program.

๐Ÿ’ก Key Takeaway

Functions are how you organize code. If you find yourself writing the same logic twice, put it in a function. Name it clearly. Keep it short. One function, one job.

๐Ÿ”จ Exercise 2.1: Build a Tip Calculator

Create a JavaScript tip calculator in the console (or a .js file):

  1. Write a function calculateTip(billAmount, tipPercent, numPeople)
  2. It should return an object with: tipAmount, totalWithTip, and perPerson
  3. Handle edge cases: what if numPeople is 0? What if billAmount is negative?
  4. Test it with at least 3 different inputs and log the results
  5. Bonus: add a roundUp parameter that rounds to the nearest dollar when true

Deliverable: A working tip calculator function with test output. Save as tip-calculator.js.

3
The DOM
โ–ถ

The DOM (Document Object Model) is the browser's live representation of your HTML page. When JavaScript talks to the DOM, it can read, change, add, or remove any element on the page. This is how web pages become interactive.

Selecting Elements

Before you can change something, you need to find it. These are the methods you'll use 99% of the time:

// Select by ID โ€” returns one element
const header = document.getElementById('main-header');

// Select by CSS selector โ€” returns first match
const firstButton = document.querySelector('.btn');
const navLink = document.querySelector('nav a');

// Select multiple elements โ€” returns a NodeList
const allButtons = document.querySelectorAll('.btn');
const allLinks = document.querySelectorAll('a');

// Loop through a NodeList
allButtons.forEach(button => {
  console.log(button.textContent);
});

Use querySelector and querySelectorAll for almost everything. They accept any CSS selector, so you already know the syntax from writing CSS.

Event Listeners

Events are things that happen on the page: clicks, key presses, form submissions, scrolling, hovering. Event listeners let you run code when those things happen:

const button = document.querySelector('#my-button');

// Listen for a click
button.addEventListener('click', () => {
  console.log('Button was clicked!');
});

// Listen for a click with the event object
button.addEventListener('click', (event) => {
  console.log('Clicked element:', event.target);
  console.log('Mouse position:', event.clientX, event.clientY);
});

// Common events:
// 'click'       โ€” mouse click
// 'submit'      โ€” form submission
// 'keydown'     โ€” key pressed
// 'input'       โ€” input value changed
// 'mouseover'   โ€” mouse enters element
// 'mouseout'    โ€” mouse leaves element
// 'scroll'      โ€” page scrolled
// 'DOMContentLoaded' โ€” page finished loading

// Form submission
const form = document.querySelector('form');
form.addEventListener('submit', (event) => {
  event.preventDefault();  // Stop the page from reloading!
  const data = new FormData(form);
  console.log('Name:', data.get('name'));
});

Manipulating Content

Once you've selected an element, you can change anything about it:

const heading = document.querySelector('h1');

// Change text
heading.textContent = 'New Heading Text';

// Change HTML (be careful โ€” don't use with user input)
heading.innerHTML = 'New <em>Heading</em> Text';

// Change styles
heading.style.color = '#a78bfa';
heading.style.fontSize = '2rem';

// Add/remove CSS classes (preferred over inline styles)
heading.classList.add('highlighted');
heading.classList.remove('hidden');
heading.classList.toggle('active');  // Add if missing, remove if present

// Change attributes
const link = document.querySelector('a');
link.setAttribute('href', 'https://exocreate.online');
link.getAttribute('href');  // 'https://exocreate.online'

// Create new elements
const newParagraph = document.createElement('p');
newParagraph.textContent = 'This paragraph was created by JavaScript';
newParagraph.classList.add('dynamic-content');
document.querySelector('article').appendChild(newParagraph);

// Remove elements
const oldElement = document.querySelector('.remove-me');
oldElement.remove();

๐Ÿ’ก Key Takeaway

The DOM is your bridge between JavaScript and the visible page. Select it โ†’ listen for events โ†’ change it. That's the entire pattern for interactive web development.

๐Ÿ”จ Exercise 3.1: Interactive FAQ Accordion

Build a FAQ section where clicking a question reveals (or hides) the answer:

  1. Create an HTML page with at least 5 FAQ items (question + answer for each)
  2. Answers should be hidden by default (CSS: display: none)
  3. Clicking a question toggles its answer visible/hidden
  4. Add a visual indicator (arrow or +/โˆ’) that rotates or changes when open
  5. Only one answer should be open at a time (clicking a new question closes the previous one)

Deliverable: A working FAQ accordion page. HTML + CSS + JavaScript in a single file or separate files.

4
Building Interactive Features
โ–ถ

Now you have the tools. This module is about putting them together into real features you'd find on actual websites. Each project combines HTML structure, CSS styling, and JavaScript interactivity.

Show/Hide Patterns

The most common interactive pattern on the web: click something โ†’ something else appears or disappears. Modals, dropdowns, mobile menus, accordions โ€” all show/hide.

// Basic show/hide toggle
const toggleBtn = document.querySelector('#toggle-btn');
const content = document.querySelector('#hidden-content');

toggleBtn.addEventListener('click', () => {
  content.classList.toggle('visible');
});

// CSS for smooth animation:
// .hidden-content { max-height: 0; overflow: hidden; transition: max-height 0.3s; }
// .hidden-content.visible { max-height: 500px; }

The key insight: don't use JavaScript to change styles directly. Use JavaScript to toggle CSS classes, and let CSS handle the visual change. This keeps your code clean and your animations smooth.

Form Validation

HTML has built-in validation (required, type="email", minlength), but JavaScript lets you create custom validation with better user feedback:

const form = document.querySelector('#signup-form');
const emailInput = document.querySelector('#email');
const passwordInput = document.querySelector('#password');
const errorDisplay = document.querySelector('#error-message');

form.addEventListener('submit', (event) => {
  event.preventDefault();
  const errors = [];

  // Email validation
  const email = emailInput.value.trim();
  if (!email) {
    errors.push('Email is required');
  } else if (!email.includes('@')) {
    errors.push('Please enter a valid email');
  }

  // Password validation
  const password = passwordInput.value;
  if (password.length < 8) {
    errors.push('Password must be at least 8 characters');
  }

  // Show errors or submit
  if (errors.length > 0) {
    errorDisplay.textContent = errors.join('. ');
    errorDisplay.classList.add('visible');
  } else {
    errorDisplay.classList.remove('visible');
    console.log('Form is valid! Submitting...');
    // In a real app, you'd send data to a server here
  }
});

Dark Mode Toggle

Dark mode is a practical feature that teaches you about CSS custom properties, localStorage (remembering user preferences), and class toggling:

// HTML: <button id="theme-toggle">๐ŸŒ™ Dark Mode</button>

const toggle = document.querySelector('#theme-toggle');

// Check for saved preference
const savedTheme = localStorage.getItem('theme');
if (savedTheme === 'dark') {
  document.body.classList.add('dark-mode');
  toggle.textContent = 'โ˜€๏ธ Light Mode';
}

toggle.addEventListener('click', () => {
  document.body.classList.toggle('dark-mode');
  const isDark = document.body.classList.contains('dark-mode');

  // Update button text
  toggle.textContent = isDark ? 'โ˜€๏ธ Light Mode' : '๐ŸŒ™ Dark Mode';

  // Save preference
  localStorage.setItem('theme', isDark ? 'dark' : 'light');
});

// CSS uses custom properties for theming:
// body { --bg: #fff; --text: #111; --accent: #7c3aed; }
// body.dark-mode { --bg: #111827; --text: #d1d5db; --accent: #a78bfa; }
// Use: background: var(--bg); color: var(--text);

Dynamic Content Filtering

Content filters let users show/hide items based on categories โ€” like filtering a portfolio by type or a product list by category:

// HTML: buttons with data-filter attribute + items with data-category
const filterBtns = document.querySelectorAll('[data-filter]');
const items = document.querySelectorAll('.portfolio-item');

filterBtns.forEach(btn => {
  btn.addEventListener('click', () => {
    const filter = btn.dataset.filter;

    // Update active button
    filterBtns.forEach(b => b.classList.remove('active'));
    btn.classList.add('active');

    // Show/hide items
    items.forEach(item => {
      if (filter === 'all' || item.dataset.category === filter) {
        item.style.display = 'block';
      } else {
        item.style.display = 'none';
      }
    });
  });
});

๐Ÿ’ก Key Takeaway

Every interactive feature on the web follows the same pattern: select an element, listen for an event, change the DOM. Once you internalize this pattern, you can build anything โ€” the only limit is knowing which DOM methods to use.

๐Ÿ”จ Exercise 4.1: Dark Mode Toggle

Add a working dark mode toggle to your website (or create a demo page):

  1. Define light and dark themes using CSS custom properties (--bg, --text, --accent, etc.)
  2. Create a toggle button that switches between themes
  3. Save the user's preference to localStorage so it persists across page loads
  4. Load the saved preference when the page opens
  5. Add a smooth transition so colors don't snap instantly

Deliverable: A page with a working dark mode toggle that remembers the user's choice.

๐Ÿ”จ Exercise 4.2: Content Filter (Course Deliverable)

Build a filterable content gallery:

  1. Create at least 12 items with at least 3 different categories
  2. Add filter buttons for each category plus an "All" button
  3. Clicking a filter shows only items in that category
  4. Style the active filter button differently
  5. Bonus: add a smooth fade or slide animation when items show/hide

Deliverable: A working content filter page. This is your main MULT-114 project โ€” make it polished.

๐Ÿ’ก Course Complete

You now write JavaScript with confidence: variables, functions, DOM manipulation, and real interactive features. Your websites aren't static anymore โ€” they respond to users. Next up: NARR-205 Interactive Storytelling & Series Design, where you'll learn to craft serialized narratives that keep audiences coming back.

Next Course โ†’
NARR-205: Interactive Storytelling & Series Design
โ†’