Core Concepts: Behavior
addEventListener tells the browser: "When a user submits this form, run my function."
<li> elements on the fly.
// Select elements from the DOM
const form = document.getElementById('todo-form');
const input = document.getElementById('todo-input');
const list = document.getElementById('todo-list');
const counter = document.getElementById('todo-counter');
// Imperative state syncing: manually read the DOM
function updateCounter() {
const total = list.querySelectorAll('.todo-item').length;
const done = list.querySelectorAll('.todo-checkbox:checked').length;
counter.textContent = `${done} of ${total} tasks completed`;
}
// Event Listener for form submission
form.addEventListener('submit', function(e) {
e.preventDefault(); // Prevent page refresh
if (!input.value) return;
// Imperatively build the DOM elements
const li = document.createElement('li');
li.className = 'todo-item';
li.innerHTML = `
<label class="todo-label">
<input type="checkbox" class="todo-checkbox">
<span class="todo-text">${input.value}</span>
</label>
<button class="btn btn-icon btn-delete">×</button>
`;
// Add delete logic
const delBtn = li.querySelector('.btn-delete');
delBtn.addEventListener('click', () => {
li.remove();
updateCounter();
});
// Add toggle logic
const checkbox = li.querySelector('.todo-checkbox');
checkbox.addEventListener('change', updateCounter);
list.appendChild(li);
input.value = '';
updateCounter();
});