const todoList = document.getElementById('todo-list'); const taskInput = document.getElementById('task-input'); const todoForm = document.getElementById('todo-form'); let tasks = []; // --- Local Storage Management --- function loadTasks() { // Attempt to retrieve tasks from localStorage const storedTasks = localStorage.getItem('todoTasks'); if (storedTasks) { try { tasks = JSON.parse(storedTasks); } catch (e) { console.error("Error parsing tasks from localStorage:", e); tasks = []; } } } function saveTasks() { localStorage.setItem('todoTasks', JSON.stringify(tasks)); } // --- Rendering --- function renderTasks() { // Clear the current list content todoList.innerHTML = ''; if (tasks.length === 0) { todoList.innerHTML = '
  • No tasks yet! Add one above.
  • '; return; } // Use a DocumentFragment for performance when appending many nodes const fragment = document.createDocumentFragment(); tasks.forEach((task, index) => { const listItem = document.createElement('li'); listItem.classList.add('todo-item'); listItem.setAttribute('aria-label', `Task: ${task.text}, ${task.completed ? 'Completed' : 'Pending'}`); if (task.completed) { listItem.classList.add('completed'); } const taskContent = document.createElement('span'); taskContent.classList.add('task-content'); taskContent.textContent = task.text; taskContent.setAttribute('role', 'button'); taskContent.setAttribute('tabindex', '0'); // Make span focusable // Event listener for toggling completion (Mark as Complete) taskContent.addEventListener('click', () => toggleComplete(index)); taskContent.addEventListener('keydown', (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggleComplete(index); } }); const deleteButton = document.createElement('button'); deleteButton.classList.add('delete-btn'); deleteButton.innerHTML = '✕'; // X mark deleteButton.setAttribute('aria-label', `Delete task: ${task.text}`); // Event listener for deletion deleteButton.addEventListener('click', () => deleteTask(index)); listItem.appendChild(taskContent); listItem.appendChild(deleteButton); fragment.appendChild(listItem); }); todoList.appendChild(fragment); } // --- Core Functionality --- function addTask(e) { e.preventDefault(); const text = taskInput.value.trim(); if (text) { const newTask = { id: Date.now(), text: text, completed: false }; // Add new task to the beginning of the array tasks.unshift(newTask); taskInput.value = ''; saveTasks(); renderTasks(); // Announce the addition for screen readers (optional but good practice) // Note: Using aria-live="polite" on the UL generally handles this, // but focusing the input might be enough feedback. taskInput.focus(); } } function toggleComplete(index) { if (index >= 0 && index < tasks.length) { tasks[index].completed = !tasks[index].completed; saveTasks(); renderTasks(); } } function deleteTask(index) { if (index >= 0 && index < tasks.length) { const taskText = tasks[index].text; // Simple confirmation before deletion if (confirm(`Are you sure you want to delete "${taskText}"?`)) { tasks.splice(index, 1); saveTasks(); renderTasks(); } } } // --- Initialization --- document.addEventListener('DOMContentLoaded', () => { loadTasks(); renderTasks(); // Setup event listener for the form submission todoForm.addEventListener('submit', addTask); });