Practice Questions
1. What is the purpose of each of the three core web technologies (HTML, CSS, JavaScript)? Give a one-sentence description for each.
Solution
- HTML provides the structure and content of a web page (headings, paragraphs, buttons, etc.).
- CSS controls the visual styling and layout (colors, fonts, spacing, positioning).
- JavaScript adds interactivity and behavior (responding to clicks, updating the page dynamically).
2. What is the DOM? How does JavaScript use it to interact with a web page?
Solution
The DOM (Document Object Model) is a programming interface that represents an HTML document as a tree of objects. JavaScript uses the document object to access and manipulate this tree: for example, finding elements with document.getElementById(), changing their content, or creating new elements. The DOM is only available in the browser environment, not in Node.js.
3. Explain three different ways to include JavaScript in an HTML page. What are the trade-offs of each approach?
Solution
-
Inline event handler – writing JS directly in an HTML attribute like
onclick="doSomething()". This is quick but mixes HTML and JS, making code harder to maintain. -
Internal script tag – placing JS inside a
<script>tag in the HTML file. This separates logic from markup somewhat but keeps everything in one file. -
External JS file – writing JS in a separate
.jsfile and linking it with<script src="index.js"></script>. This is the preferred approach because it fully separates concerns, makes code reusable, and allows the JS to be tested independently.
The <script> tag should be placed right before the closing </body> tag so the HTML elements exist before the script tries to access them.
4. Given the following HTML, write JavaScript that finds the button by its ID and attaches a click handler that changes the paragraph text to “Clicked!”:
<p id="message">Hello</p>
<button id="my-btn">Click me</button>
Solution
const btn = document.getElementById("my-btn");
const message = document.getElementById("message");
btn.onclick = function () {
message.textContent = "Clicked!";
};
Key points: use getElementById to get references, assign a function (without parentheses) to onclick, and use textContent to update the displayed text.
5. Write JavaScript that creates three <li> elements with the text “Item 1”, “Item 2”, and “Item 3”, and appends them to an existing <ul> with id="my-list". Each <li> should have a unique ID like item-1, item-2, etc.
Solution
const list = document.getElementById("my-list");
for (let i = 1; i <= 3; i++) {
const li = document.createElement("li");
li.setAttribute("id", `item-${i}`);
li.textContent = `Item ${i}`;
list.appendChild(li);
}
The pattern is: createElement to create the element (not yet in the DOM), setAttribute and textContent to configure it, then appendChild to insert it into the page.
6. What is the difference between getElementById, querySelector, and querySelectorAll? When would you use each?
Solution
getElementById("myId")returns the single element with the matchingid, ornullif none exists. Use it when you know the element’s ID.querySelector(".myClass")returns the first element that matches any CSS selector (ID, class, tag, attribute, etc.), ornull. It is more flexible thangetElementByIdbecause it accepts any valid CSS selector.querySelectorAll("li.active")returns aNodeListof all elements matching the CSS selector. Use it when you need to work with multiple matching elements.
const header = document.getElementById("header"); // by ID
const firstBtn = document.querySelector(".btn"); // first match
const allBtns = document.querySelectorAll(".btn"); // all matches
Use getElementById for simple ID lookups (it is the fastest). Use querySelector when you need CSS selector flexibility for a single element. Use querySelectorAll when you need all matching elements.
7. Name the three main types of CSS selectors and give the syntax for each. Which one is the most specific?
Solution
- Element selector – selects by tag name:
body { ... },p { ... } - Class selector – selects by class attribute, prefixed with
.:.cycle { ... } - ID selector – selects by id attribute, prefixed with
#:#calc-btn { ... }
ID selectors are the most specific. When two rules conflict, the more specific one wins. The specificity order from lowest to highest is: element < class < ID.
Pseudo-selectors like :hover and :active can be added to any selector to apply styles in specific states (e.g., #calc-btn:hover).
8. Explain three ways to apply CSS to an HTML page. Which is generally preferred and why?
Solution
-
Inline styles – using the
styleattribute directly on an element:<p style="color: red;">. Quick but hard to maintain and cannot be reused. -
Internal stylesheet – using a
<style>tag in the<head>of the HTML file. Better separation but still couples styles to the HTML file. -
External stylesheet – writing CSS in a separate
.cssfile and linking it with<link rel="stylesheet" href="index.css">. This is preferred because it fully separates structure from presentation, makes styles reusable across pages, and keeps files focused on a single concern.
9. Given an element with id="panel", write JavaScript to hide it by adding a CSS class called "hidden", and then write a separate function that shows it again. Assume the hidden class is already defined in CSS as display: none.
Solution
const panel = document.getElementById("panel");
function hidePanel() {
panel.classList.add("hidden");
}
function showPanel() {
panel.classList.remove("hidden");
}
The classList property provides add() and remove() methods to manipulate an element’s CSS classes. Adding "hidden" applies display: none, and removing it makes the element visible again. This is a common pattern for toggling visibility between different sections of a page.
10. The JavaScript Date object has getter and setter methods. Explain the “get-modify-set” pattern and write code that creates a Date for the current time and then adds 45 minutes to it. Display the result using toLocaleTimeString.
Solution
The “get-modify-set” pattern means: retrieve a value using a getter, perform a calculation on it, then write the result back using the corresponding setter.
const time = new Date();
time.setMinutes(time.getMinutes() + 45);
console.log(time.toLocaleTimeString("en-US", { timeStyle: "short" }));
getMinutes() returns the current minutes, we add 45, and setMinutes() writes it back. The Date object handles overflow automatically (e.g., if the current minutes are 30, setting to 75 correctly rolls over to the next hour).
11. Why does const copy = originalDate not create an independent copy of a Date object? How do you create a true copy?
Solution
In JavaScript, objects are assigned by reference, not by value. Writing const copy = originalDate makes both variables point to the same Date object in memory. Modifying one will modify the other.
To create an independent copy, pass the original Date to the Date constructor:
const original = new Date();
const copy = new Date(original);
// Now modifying copy does not affect original
copy.setMinutes(copy.getMinutes() + 90);
This creates a new Date object with the same time value. Changes to copy will not affect original.
12. If an element has both an ID-based style rule (#result-section { display: flex; }) and a class-based rule (.hidden { display: none; }), which one wins? How can you ensure the class-based rule always takes effect when the class is applied?
Solution
The ID-based rule wins because ID selectors are more specific than class selectors in CSS’s specificity hierarchy. Even though .hidden sets display: none, the #result-section rule with display: flex overrides it.
To ensure the class-based rule always works, use the !important flag:
.hidden {
display: none !important;
}
The !important flag overrides normal specificity rules. It should be used sparingly because it makes CSS harder to maintain, but for utility classes like .hidden that must always work regardless of other rules, it is the right choice.