Master JavaScript through hands-on coding challenges. Write real code, get instant feedback, and build practical web development skills.
Learn to interact with web pages and build object-oriented JavaScript applications.
document.getElementById() - The most common and fastest way to select a single element by its unique ID attribute.const element = document.getElementById("myId");
// Returns the element with id="myId" or null if not founddocument.querySelector() - Uses CSS selector syntax to select the FIRST matching element. Very flexible!const element = document.querySelector(".className"); // By class
const element = document.querySelector("#myId"); // By ID
const element = document.querySelector("div > p"); // CSS selector
const element = document.querySelector("[data-id]"); // By attributequerySelectorAll() - Returns a NodeList of ALL matching elements (use forEach to iterate).const elements = document.querySelectorAll(".item");
elements.forEach(el => console.log(el.textContent));
// Or convert to array: [...elements] or Array.from(elements)textContent and innerHTMLelement.textContent = "Plain text (safe, escapes HTML)";
element.innerHTML = "HTML content (can be XSS risk!)";
// textContent is faster and safer for plain text// Inline styles (camelCase properties)
element.style.backgroundColor = "blue";
element.style.fontSize = "20px";
// Class manipulation (preferred for styling)
element.classList.add("active");
element.classList.remove("hidden");
element.classList.toggle("visible");
element.classList.contains("active"); // returns true/falseconst newDiv = document.createElement("div");
newDiv.textContent = "New element!";
newDiv.className = "my-class";
document.body.appendChild(newDiv);
// Or insert at specific position
parent.insertBefore(newDiv, referenceElement);
parent.append(newDiv); // Appends to end
parent.prepend(newDiv); // Prepends to beginninggetElementById is fastest, but querySelector is more flexibletextContent over innerHTML when possible (security + performance)classList methods over directly manipulating classNamedataset property to access data-* attributes: element.dataset.userIdinnerHTML with user input (XSS vulnerability)querySelectorAll returns NodeList, not ArraySelected element by ID: <div id="demo">
Selected element by class: <p class="intro">
All items: NodeList(3) [li, li, li]
Text content changed!
New element created and appended!
document.getElementById("myId")document.querySelector(".class")document.querySelectorAll("li")element.textContent = "text"element.classList.add("class")document.createElement("div")Review feedback below
addEventListener() - The modern, preferred way to attach event handlers.const button = document.querySelector("#myButton");
button.addEventListener("click", function(event) {
console.log("Button clicked!");
console.log("Event target:", event.target);
});
// Arrow function version:
button.addEventListener("click", (e) => {
console.log("Clicked!", e.target);
});document.addEventListener("keydown", (event) => {
console.log("Key pressed:", event.key); // "Enter", "a", etc.
console.log("Key code:", event.code); // "Enter", "KeyA", etc.
console.log("Ctrl held?", event.ctrlKey); // true/false
if (event.key === "Enter") {
console.log("Enter was pressed!");
}
});const form = document.querySelector("form");
form.addEventListener("submit", (event) => {
event.preventDefault(); // Stop form from submitting/reloading
const formData = new FormData(form);
const name = formData.get("name");
// Or: const name = document.querySelector("#name").value;
console.log("Form submitted with name:", name);
});element.addEventListener("click", (event) => {
event.target; // Element that triggered the event
event.currentTarget; // Element listener is attached to
event.type; // "click", "keydown", etc.
event.preventDefault(); // Stop default behavior
event.stopPropagation(); // Stop event bubbling
});// Instead of adding listener to each button:
document.querySelector("#buttonContainer").addEventListener("click", (e) => {
if (e.target.matches("button")) {
console.log("Button clicked:", e.target.textContent);
}
});const handleClick = () => console.log("Clicked!");
button.addEventListener("click", handleClick);
// Later...
button.removeEventListener("click", handleClick);addEventListener over onclick attributesevent.preventDefault() for links/forms you want to handle with JSremoveEventListener (no reference){ once: true } option for one-time listenersaddEventListener("click", fn()) ❌event.preventDefault() for form submissionsEvent listener added!
Button clicked!
Key pressed: Enter
Form submitted - Name: John
Event delegation working!
element.addEventListener("click", handler)document.addEventListener("keydown", handler)form.addEventListener("submit", handler)event.preventDefault()event.target gives clicked elementif (event.target.matches("selector"))Review feedback below
constructor method is called when creating new instances.class Person {
constructor(name, age) {
this.name = name; // Instance property
this.age = age;
}
}
const person = new Person("Alice", 25);this.class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
return `Hello, I'm ${this.name}`;
}
haveBirthday() {
this.age++;
return `Happy birthday! Now ${this.age} years old.`;
}
}class MathUtils {
static add(a, b) {
return a + b;
}
static PI = 3.14159; // Static property
}
MathUtils.add(5, 3); // 8 (called on class)
MathUtils.PI; // 3.14159class Circle {
constructor(radius) {
this._radius = radius; // Convention: _ for private
}
get radius() {
return this._radius;
}
set radius(value) {
if (value > 0) this._radius = value;
}
get area() {
return Math.PI * this._radius ** 2;
}
}extends - Create child classes that inherit from parent classes.class Animal {
constructor(name) {
this.name = name;
}
speak() {
return `${this.name} makes a sound`;
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // MUST call super() first!
this.breed = breed;
}
speak() {
return `${this.name} barks!`; // Override parent method
}
}super to call parent methodsclass Cat extends Animal {
speak() {
const parentSound = super.speak(); // Call parent method
return `${parentSound}... actually, ${this.name} meows!`;
}
}# prefix for truly private fields: #privateFieldinstanceof checks if object is instance of a classnew keyword when creating instancessuper() in child constructorthis)Created: Person { name: 'Alice', age: 25 }
Greeting: Hello, I'm Alice
Static method: 8
Circle area: 78.54
Dog says: Buddy barks!
class ClassName { constructor() {} }constructor(params) { this.prop = params; }methodName() { return this.prop; }static methodName() { }get propName() { return this._prop; }class Child extends Parent { }Review feedback below