├── index.html ├── style.css └── script.js /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Todo List 8 | 9 | 10 |

todos

11 |
12 | 13 | 14 | 15 |
16 | Left click to toggle completed.
Right click to delete todo
17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;400&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-color: #f5f5f5; 9 | color: #444; 10 | font-family: 'Poppins', sans-serif; 11 | display: flex; 12 | flex-direction: column; 13 | align-items: center; 14 | justify-content: center; 15 | height: 100vh; 16 | margin: 0; 17 | } 18 | 19 | h1 { 20 | color: rgb(179, 131, 226); 21 | font-size: 10rem; 22 | text-align: center; 23 | opacity: 0.4; 24 | } 25 | 26 | form { 27 | box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); 28 | max-width: 100%; 29 | width: 400px; 30 | } 31 | 32 | .input { 33 | border: none; 34 | color: #444; 35 | font-size: 2rem; 36 | padding: 1rem 2rem; 37 | display: block; 38 | width: 100%; 39 | } 40 | 41 | .input::placeholder { 42 | color: #d5d5d5; 43 | } 44 | 45 | .input:focus { 46 | outline-color: rgb(179, 131, 226); 47 | } 48 | 49 | .todos { 50 | background-color: #fff; 51 | padding: 0; 52 | margin: 0; 53 | list-style-type: none; 54 | } 55 | 56 | .todos li { 57 | border-top: 1px solid #e5e5e5; 58 | cursor: pointer; 59 | font-size: 1.5rem; 60 | padding: 1rem 2rem; 61 | } 62 | 63 | .todos li.completed { 64 | color: #b6b6b6; 65 | text-decoration: line-through; 66 | } 67 | 68 | small { 69 | color: #b5b5b5; 70 | margin-top: 3rem; 71 | text-align: center; 72 | } 73 | 74 | -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | const form = document.getElementById('form') 2 | const input = document.getElementById('input') 3 | const todosUL = document.getElementById('todos') 4 | 5 | const todos = JSON.parse(localStorage.getItem('todos')) 6 | 7 | if(todos) { 8 | todos.forEach(todo => addTodo(todo)) 9 | } 10 | 11 | form.addEventListener('submit', (e) => { 12 | e.preventDefault() 13 | 14 | addTodo() 15 | }) 16 | 17 | function addTodo(todo) { 18 | let todoText = input.value 19 | 20 | if(todo) { 21 | todoText = todo.text 22 | } 23 | 24 | if(todoText) { 25 | const todoEl = document.createElement('li') 26 | if(todo && todo.completed) { 27 | todoEl.classList.add('completed') 28 | } 29 | 30 | todoEl.innerText = todoText 31 | 32 | todoEl.addEventListener('click', () => { 33 | todoEl.classList.toggle('completed') 34 | updateLS() 35 | }) 36 | 37 | todoEl.addEventListener('contextmenu', (e) => { 38 | e.preventDefault() 39 | 40 | todoEl.remove() 41 | updateLS() 42 | }) 43 | 44 | todosUL.appendChild(todoEl) 45 | 46 | input.value = '' 47 | 48 | updateLS() 49 | } 50 | } 51 | 52 | function updateLS() { 53 | todosEl = document.querySelectorAll('li') 54 | 55 | const todos = [] 56 | 57 | todosEl.forEach(todoEl => { 58 | todos.push({ 59 | text: todoEl.innerText, 60 | completed: todoEl.classList.contains('completed') 61 | }) 62 | }) 63 | 64 | localStorage.setItem('todos', JSON.stringify(todos)) 65 | } --------------------------------------------------------------------------------