JS Projects
On this page
JS Projects
This page includes small beginner-friendly projects to practice DOM and events. Each project contains minimal HTML, CSS (optional), and JavaScript.
JS Counter
A simple counter with increment, decrement, and reset.
<div class="card p-3" style="max-width:320px;">
<h3 class="h5 mb-2">Counter</h3>
<div id="countValue" class="display-6">0</div>
<div class="d-flex gap-2 mt-3">
<button id="btnDec" class="btn btn-outline-secondary">-</button>
<button id="btnInc" class="btn btn-primary">+</button>
<button id="btnReset" class="btn btn-outline-danger">Reset</button>
</div>
</div>
<script>
let count = 0;
const el = document.querySelector("#countValue");
const btnDec = document.querySelector("#btnDec");
const btnInc = document.querySelector("#btnInc");
const btnReset = document.querySelector("#btnReset");
function render() {
el.textContent = count;
}
btnInc.addEventListener("click", () => {
count++;
render();
});
btnDec.addEventListener("click", () => {
count--;
render();
});
btnReset.addEventListener("click", () => {
count = 0;
render();
});
render();
</script>
JS Event Listener
Learn how to attach and remove an event listener.
<div class="card p-3" style="max-width:420px;">
<h3 class="h5 mb-2">Event Listener</h3>
<p class="mb-2">Click "Enable" then click the button.</p>
<div class="d-flex gap-2">
<button id="enable" class="btn btn-success">Enable</button>
<button id="disable" class="btn btn-outline-danger">Disable</button>
<button id="target" class="btn btn-primary">Click Me</button>
</div>
<div id="log" class="mt-3 small text-muted"></div>
</div>
<script>
const log = document.querySelector("#log");
const enable = document.querySelector("#enable");
const disable = document.querySelector("#disable");
const target = document.querySelector("#target");
function handler() {
log.textContent = "Button clicked at " + new Date().toLocaleTimeString();
}
enable.addEventListener("click", () => {
target.addEventListener("click", handler);
log.textContent = "Listener enabled";
});
disable.addEventListener("click", () => {
target.removeEventListener("click", handler);
log.textContent = "Listener disabled";
});
</script>
JS To-Do List
A minimal to-do list: add items, mark as done, delete items (event delegation).
<div class="card p-3" style="max-width:520px;">
<h3 class="h5 mb-3">To-Do List</h3>
<div class="input-group">
<input id="todoInput" type="text" class="form-control" placeholder="Add a new task...">
<button id="todoAdd" class="btn btn-primary">Add</button>
</div>
<ul id="todoList" class="list-group mt-3"></ul>
</div>
<script>
const input = document.querySelector("#todoInput");
const addBtn = document.querySelector("#todoAdd");
const list = document.querySelector("#todoList");
function addItem(text) {
const li = document.createElement("li");
li.className = "list-group-item d-flex align-items-center justify-content-between";
li.innerHTML = `
<div class="d-flex align-items-center gap-2">
<input class="form-check-input todo-check" type="checkbox">
<span class="todo-text"></span>
</div>
<button class="btn btn-sm btn-outline-danger todo-delete">Delete</button>
`;
li.querySelector(".todo-text").textContent = text;
list.appendChild(li);
}
addBtn.addEventListener("click", () => {
const text = input.value.trim();
if (!text) return;
addItem(text);
input.value = "";
input.focus();
});
input.addEventListener("keydown", (e) => {
if (e.key === "Enter") addBtn.click();
});
// Event delegation for delete + done
list.addEventListener("click", (e) => {
const li = e.target.closest("li");
if (!li) return;
if (e.target.classList.contains("todo-delete")) {
li.remove();
return;
}
});
list.addEventListener("change", (e) => {
const li = e.target.closest("li");
if (!li) return;
if (e.target.classList.contains("todo-check")) {
const text = li.querySelector(".todo-text");
if (e.target.checked) {
text.style.textDecoration = "line-through";
text.style.opacity = "0.6";
} else {
text.style.textDecoration = "none";
text.style.opacity = "1";
}
}
});
</script>
JS Modal Popup
A simple modal popup using Bootstrap 5 classes (no Bootstrap JS required). Click outside or press ESC to close.
<button id="openModal" class="btn btn-primary">Open Modal</button>
<div id="modalBackdrop" class="position-fixed top-0 start-0 w-100 h-100 d-none" style="background: rgba(0,0,0,.5);"></div>
<div id="modalBox" class="position-fixed top-50 start-50 translate-middle bg-white rounded shadow p-3 d-none" style="max-width:520px; width: calc(100% - 24px);">
<div class="d-flex align-items-center justify-content-between">
<h3 class="h5 m-0">Modal Title</h3>
<button id="closeModal" class="btn btn-sm btn-outline-secondary">Close</button>
</div>
<p class="mt-3 mb-0">This is a simple modal popup. Click outside or press ESC to close.</p>
</div>
<script>
const openBtn = document.querySelector("#openModal");
const closeBtn = document.querySelector("#closeModal");
const backdrop = document.querySelector("#modalBackdrop");
const modal = document.querySelector("#modalBox");
function openModal() {
backdrop.classList.remove("d-none");
modal.classList.remove("d-none");
}
function closeModal() {
backdrop.classList.add("d-none");
modal.classList.add("d-none");
}
openBtn.addEventListener("click", openModal);
closeBtn.addEventListener("click", closeModal);
backdrop.addEventListener("click", closeModal);
document.addEventListener("keydown", (e) => {
if (e.key === "Escape") closeModal();
});
</script>
Next Step
Next, you can continue with JS Advanced topics (classes, async, modules) or start building larger projects.