Complete solution (100% reference)
index.html- Main HTML pagescript.js- JavaScript logicstyles.css- Styling and layoutpackage.json- Dependenciessetup.sh- Setup scriptREADME.md- Instructions (below)💡 Download the ZIP, extract it, and follow the instructions below to get started!
This is the complete solution for Activity 09: DOM Manipulation. This directory contains working code that demonstrates all DOM concepts covered in the activity.
Purpose: Instructor reference for teaching, grading, and troubleshooting student work.
activity-09-dom/
├── script.js ← Complete solution with detailed teaching comments
├── index.html ← HTML structure (same as student template)
├── package.json ← Project dependencies
├── setup.sh ← Setup script for dev environment
└── README.md ← This file (instructor guide)
By completing this activity, students will:
querySelector() and getElementById()document.createElement()appendChild().remove().valueclassList.add()onclick attributeGoal: Add a new list item "Milk" to an existing unordered list.
Key Concepts:
document.querySelector("ul") - Selecting parent elementdocument.createElement("li") - Creating new element.textContent - Setting element content.appendChild() - Adding element to DOMCommon Mistakes:
querySelector(ul) -> ✅ querySelector("ul")newli.text = "Milk" -> ✅ newli.textContent = "Milk"append() instead of appendChild() (support issues)Success Criteria:
Goal: Remove a paragraph element using the .remove() method.
Key Concepts:
.remove-medocument.querySelector(".classname") - Selecting by class.remove() - Removing element from DOMCommon Mistakes:
p.delete() -> ✅ p.remove()querySelector("remove-me") -> ✅ querySelector(".remove-me")querySelectorAll() instead of querySelector()Success Criteria:
Goal: Create calculator that multiplies two numbers and displays result history.
Key Concepts:
getElementById() - Selecting elements by ID.value - Reading input field values.classList.add() - Adding multiple CSS classesonclick event - Making button interactiveCommon Mistakes:
onclick="calculate()" in HTML button.value: num1 * num2 -> ✅ num1.value * num2.valuediv.appendChild(answer) -> ✅ div.appendChild(newAnswer)+ for calculation: "3" + "4" = "34" -> ✅ Use * or convert to NumberclassList.add("text-success m-0") as one stringquerySelector("num1") -> ✅ querySelector("#num1") or getElementById("num1")Success Criteria:
// Before running script:
- List should have 2 items: Coffee, Tea
// After running script:
- List should have 3 items: Coffee, Tea, Milk
- Milk should be last item
- All items should be <li> elements
// Before running script:
- Paragraph with class="remove-me" should be visible
- Text should read "This paragraph should be removed!"
// After running script:
- Paragraph should be completely gone
- No empty space where paragraph was
- Other elements unaffected
| Test Input | Expected Output | Notes |
|---|---|---|
| 3, 4 | "3 x 4 = 12" | Basic multiplication |
| 10, 5 | "10 x 5 = 50" | Larger numbers |
| 3.5, 2 | "3.5 x 2 = 7" | Decimal support |
| -3, 4 | "-3 x 4 = -12" | Negative numbers |
| 0, 5 | "0 x 5 = 0" | Zero handling |
| (empty), 5 | "0" or validation | Edge case |
Additional Tests:
The DOM is a Tree Structure
Elements vs Values
.value for inputs, .textContent for most elementsCreate Before Append
createElement() makes element in memoryCSS Selectors in JavaScript
.class for classes, #id for IDsWhy use JavaScript instead of HTML?
What's the difference between querySelector and getElementById?
getElementById() faster, only works with IDsquerySelector() flexible, works with any CSS selectorWhy does multiplication work with string inputs?
* operator converts strings to numbers+ concatenates (watch out!)Can we undo a .remove()?
parent.appendChild(removedElement)null removes reference completely"Creating element adds it to page"
createElement() only creates in memoryappendChild() to add to DOM"querySelector returns array"
querySelectorAll() returns NodeList".value is a number for type='number'"
"onclick in HTML is bad practice"
addEventListener() in real appsAdd Multiple Items
const items = ["Milk", "Juice", "Water"];
items.forEach(item => {
const li = document.createElement("li");
li.textContent = item;
ul.appendChild(li);
});
Style New Elements
newli.classList.add("text-success");
newli.style.fontWeight = "bold";
Add Clear Results Button
function clearResults() {
const results = document.querySelectorAll("#calc p");
results.forEach(p => p.remove());
}
Input Validation
if (!num1.value || !num2.value) {
alert("Please enter both numbers!");
return;
}
More Calculator Operations
function calculate(operation) {
let answer;
switch(operation) {
case '+': answer = Number(num1.value) + Number(num2.value); break;
case '-': answer = num1.value - num2.value; break;
case '*': answer = num1.value * num2.value; break;
case '/': answer = num1.value / num2.value; break;
}
// Display result...
}
Remove Individual Results
// Add delete button to each result
const deleteBtn = document.createElement("button");
deleteBtn.textContent = "X";
deleteBtn.onclick = () => newAnswer.remove();
newAnswer.appendChild(deleteBtn);
Keyboard Support
num2.addEventListener("keypress", (e) => {
if (e.key === "Enter") calculate();
});
Result Animations
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.result { animation: fadeIn 0.5s; }
Scientific Calculator
Possible Causes:
<script> at bottom of <body><script src="script.js"> pathCause: Selected element doesn't exist
Solutions:
.class vs #id vs tagif (element) { ... }Cause: String concatenation instead of addition
Solution:
// WRONG:
const answer = num1.value + num2.value; // "3" + "4" = "34"
// RIGHT:
const answer = Number(num1.value) + Number(num2.value); // 3 + 4 = 7
// OR use multiplication (auto-converts):
const answer = num1.value * num2.value; // "3" * "4" = 12 ✅
Possible Causes:
onclick="calculate()" in HTML
Cause: Wrong classList syntax
// WRONG:
element.classList = "text-success m-0"; // Overwrites entire classList
element.class = "text-success"; // Wrong property
// RIGHT:
element.classList.add("text-success");
element.classList.add("m-0");
// OR:
element.classList.add("text-success", "m-0");
<ul> element (7 pts)<li> element (8 pts)// SELECTING ELEMENTS
document.querySelector("selector") // Returns first match
document.querySelectorAll("selector") // Returns all matches
document.getElementById("id") // Returns element by ID
// CREATING ELEMENTS
document.createElement("tagname") // Creates new element
// MODIFYING ELEMENTS
element.textContent = "text" // Set text content
element.innerHTML = "<b>html</b>" // Set HTML content (use carefully!)
element.value // Get/set input value
// ADDING ELEMENTS
parent.appendChild(child) // Add as last child
parent.append(child1, child2) // Add multiple (ES6+)
parent.prepend(child) // Add as first child
// REMOVING ELEMENTS
element.remove() // Remove from DOM
parent.removeChild(child) // Older method
// CSS CLASSES
element.classList.add("class") // Add class
element.classList.remove("class") // Remove class
element.classList.toggle("class") // Toggle class
element.classList.contains("class") // Check if has class
// EVENT HANDLING
element.onclick = function() {} // Property assignment
element.addEventListener("click", fn) // Add listener (recommended)
// By tag name
document.querySelector("div")
// By class
document.querySelector(".classname")
// By ID
document.querySelector("#idname")
// By attribute
document.querySelector("[type='text']")
// Combined
document.querySelector("div.classname")
document.querySelector("ul li")
Q: "Why do we need to select elements? Can't we just change HTML?" A: JavaScript runs AFTER HTML loads. We need to find elements to modify them dynamically based on user interaction.
Q: "What's the difference between textContent and innerHTML?" A: textContent sets plain text (safe), innerHTML parses HTML (powerful but risky with user input).
Q: "Why does my element not appear?" A: Did you append it? Creating an element doesn't add it to the page automatically.
Q: "Can I use jQuery instead?" A: Modern JavaScript (vanilla) is powerful enough. Learn fundamentals first!
Q: "Why use onclick instead of addEventListener?" A: For learning, onclick is simpler. In real projects, addEventListener is better (can have multiple listeners, easier to remove).
Last Updated: October 2025 Author: Telebort Engineering Course: W2 Advanced JavaScript Foundations
Changelog:
For questions or issues with this solution:
Remember: This is a teaching tool! The verbose comments are intentional to help instructors understand common pitfalls and teaching opportunities. Student-facing code should be cleaner and more concise.