├── index.html
├── style.css
└── script.js
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Todo List
8 |
9 |
10 | todos
11 |
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 | }
--------------------------------------------------------------------------------