2024-10-01 課後作業-JavaScript 系列五:第2課 ── 學會 Local Storage 相關功能

課後作業-JavaScript 系列五:第2課 ── 學會 Local Storage 相關功能

02_js_local-storage.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript 系列五:第2課 ── 學會 Local Storage 相關功能</title>
<link rel="stylesheet" href="./02_js_local-storage.css">
</head>
<body>
<div class="bg-container">

<div class="input_text">
<h1>
To Do List
</h1>
<div class="input_container">
<input type="text" id="to_do" class="to_do" placeholder="新增待辦事項...">
<select id="list_level" class="list_level" >
<option value="normal" selected>一般</option>
<option value="important" >重要</option>
<option value="urgent" >緊急</option>
</select>
<button id ="add_list" class="add_list" onclick="addList()">+</button>
<button class="todo_btn export_btn" onclick="exportList('export')">匯出清單</button>
<button class="todo_btn save_btn" onclick="exportList('save')">儲存</button>

</div>


</div>
<div class="to_do_list">
<h3>待辦事項的清單</h3>
<div class="to_do_list_container">
<ul id="to_do_list_ul" class="to_do_list_ul">

</ul>
</div>
</div>
</div>
<script src="./02_js_local-storage.js"></script>
</body>
</html>

02_js_local-storage.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261

let elem_toDo = document.querySelector('#to_do') ;
let elem_toDo_class= elem_toDo.className ;
elem_toDo.addEventListener("keypress",
function(event)
{
if(event.key === "Enter") {
document.querySelector('#add_list').click();
}
}
)



let elem_select = document.querySelector("#list_level");
let elem_select_class= elem_select.className ;
// 監聽選擇框的變化
elem_select.addEventListener("change",
function() {
// 取得當前選擇的選項值
let selectedValue = elem_select.value;
// 根據選擇的值來決定文字顏色
if (selectedValue === "important") {
elem_select.className = elem_select_class +
" important_li";
elem_toDo.className =
elem_toDo_class +
" important_li";
} else if (selectedValue === "urgent") {
elem_select.className =
elem_select_class +
" urgent_li";
elem_toDo.className =
elem_select_class +
" urgent_li";
} else if (selectedValue === "normal") {
elem_select.className =
elem_select_class +
" normal_li";
elem_toDo.className =
elem_select_class +
" normal_li";
}
// else {
// elem_select.className = elem_select_class;
// elem_toDo.className = elem_toDo_class
// }
}
);



function addList(){
let toDoValue = document.querySelector('#to_do').value;
let elem_value_select =
document.querySelector('#list_level').value;


if (toDoValue!="") {

let elem_li = document.createElement('li');

if (elem_value_select == 'important'){
elem_li.className = "important_li";
}
if (elem_value_select == 'urgent'){

elem_li.className = "urgent_li";
}
if (elem_value_select == 'normal'){

elem_li.className = "normal_li";
}


let elem_ul = document.querySelector('#to_do_list_ul');
let elem_div = document.createElement('div');
let elem_span_txt = document.createElement('span');

elem_ul.append(elem_li);
elem_li.append(elem_div);
elem_div.setAttribute('class' , "todo_group")
elem_div.append(elem_span_txt);
elem_span_txt.textContent= toDoValue;
elem_span_txt.value=toDoValue;
elem_span_txt.setAttribute('class' , "todo_txt");

let elem_span_done = document.createElement('span');

elem_div.append(elem_span_done );
elem_span_done.textContent="(已完成)";
elem_span_done.setAttribute('class' , "done");

let elem_del_btn = document.createElement('button');
elem_del_btn.textContent="✖︎";
elem_del_btn.setAttribute('class', "del_btn");
elem_del_btn.onclick= delItem;
elem_div.append(elem_del_btn);

let elem_toggle_btn = document.createElement('button');
elem_toggle_btn.textContent="";
elem_toggle_btn.value="未完成";
elem_toggle_btn.setAttribute("class", "on_off_btn");
elem_toggle_btn.onclick = function() {
toggleButtonText(elem_toggle_btn);
};
elem_div.append(elem_toggle_btn);

}
elem_toDo.value="";
elem_toDo.focus();

}


function delItem() {
let grandParent = event.target.closest('li');
// alert(grandParent);
grandParent.remove();
}

function toggleButtonText(button) {
var elem_done = button.parentElement.querySelector('.done')
if (button.value === "未完成") {
button.value ="已完成"
button.textContent = "✔";
elem_done.style.display = 'inline-block';
elem_done.value=" (已完成)";

} else {
button.value ="未完成"
button.textContent = "";
elem_done.style.display = 'none';
elem_done.value="";
}
}


function exportList(action) {
let lists = document.querySelectorAll('li');

if (lists.length !== 0) {
let list = [];
let num = 1;
let text = "";
let stars = "";
let list_level = "";

for (let i = 0; i < lists.length; i++) {
let listItems = lists[i].querySelectorAll('span');
let span_text = "";
let listItem_txt = "";
let done = "no";

for (let j = 0; j < listItems.length; j++) {
let para_classname = lists[i].className;
if (para_classname === 'important_li') {
list_level = "important_li";
stars = "*";
} else if (para_classname === 'urgent_li') {
list_level = "urgent_li";
stars = "**";
} else if (para_classname === 'normal_li') {
list_level = "normal_li";
}

if (listItems[j].className === 'todo_txt') {
listItem_txt = listItems[j].value;
}
if (listItems[j].className === 'done')
{
if (listItems[j].style.display === 'inline-block')
{
done = "yes";
listItems[j].value ="(已完成)";
} else {
listItems[j].value ="";
}
}

span_text += listItems[j].value + ' ';
}

if (span_text.trim() !== "") { // Check if the text content is not empty
let listItemData = {
num: num.toString(),
list_level: list_level,
todo_txt: listItem_txt,
done: done
};
list.push(listItemData);
text += num.toString() + '. ' + stars + ' ' + span_text.trim() + ' ' + stars + "\n";
num += 1;
}
}

// If the action is 'save', store the list in localStorage
if (action === 'save') {
localStorage.setItem('todoList', JSON.stringify(list));
alert('待辦事項已儲存');
} else if (action === 'export') {
alert('今日待辦:\n' + text);
}
}
}



function loadList() {
let storedList = JSON.parse(localStorage.getItem('todoList'));

if (storedList && storedList.length > 0) {
storedList.forEach(function(item) {
let elem_li = document.createElement('li');
elem_li.className = item.list_level;

let elem_div = document.createElement('div');
elem_div.setAttribute('class', 'todo_group');

let elem_span_txt = document.createElement('span');
elem_span_txt.textContent = item.todo_txt;
elem_span_txt.setAttribute('class', 'todo_txt');
elem_span_txt.value = item.todo_txt; // 確保 `value` 屬性被設置

elem_div.appendChild(elem_span_txt);

let elem_span_done = document.createElement('span');
elem_span_done.textContent = '(已完成)';
elem_span_done.setAttribute('class', 'done');
elem_span_done.style.display = item.done === 'yes' ? 'inline-block' : 'none';

elem_div.appendChild(elem_span_done);

let elem_del_btn = document.createElement('button');
elem_del_btn.textContent = '✖︎';
elem_del_btn.setAttribute('class', 'del_btn');
elem_del_btn.onclick = delItem;

elem_div.appendChild(elem_del_btn);

let elem_toggle_btn = document.createElement('button');
elem_toggle_btn.textContent = item.done === 'yes' ? '✔' : '';
elem_toggle_btn.value = item.done === 'yes' ? '已完成' : '未完成';
elem_toggle_btn.setAttribute('class', 'on_off_btn');
elem_toggle_btn.onclick = function() {
toggleButtonText(elem_toggle_btn);
};

elem_div.appendChild(elem_toggle_btn);

elem_li.appendChild(elem_div);

document.querySelector('#to_do_list_ul').appendChild(elem_li);
});
}
}


// 頁面載入時調用 loadList 函數
window.onload = loadList;

02_js_local-storage.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
* {
margin: 0;
padding: 0;
}
body{
color: #82715f;
}
.bg-container{
background-image: url('https://imgur.com/0GIPhB0.jpg');
width: 640px;
min-height: 100px;
border-radius: 8px;
margin:auto;
padding-top: 20px;
padding-bottom: 30px;

}

select{
padding: 5px 10px;
/* height: 2.2em; */
font-size: 18px;
}
.input_text h1{
margin-left: 40px;
}
.input_container{
margin-left: 40px;
width: 560px;
display: flex;

}

.input_text input{
min-width: 300px;
/* height: 2em; */
font-size: 18px;
padding-left: 10px;

}

.add_list{
border: none;
color: #fff;
background-color: #82715f;
width: 50px;
font-size: 30px;


}

.todo_btn{
border: none;
color: #fff;
background-color: #82715f;
width: 100px;
border-radius: 8px;
margin-left: 10px;
padding: 5px 10px;
font-size: 18px;
cursor: pointer;

}

.to_do_list{
background-color: #f2eee2;
border-radius: 10px;
width: 530px;
min-height: 500px;
margin: auto;
margin-top: 20px;
padding: 10px 10px;

}
.to_do_list h3{
text-align: center;
line-height: 2;
letter-spacing: 0.3em;
border-bottom: 1px dashed #C8C8C8 ;
}


.to_do_list_ul{
padding-left: 20px;
}

.to_do_list_ul li{
padding: 10px 10px;
border-bottom: 1px dashed #C8C8C8 ;
}
.todo_group{
position:relative;
width: 480px;
}
.todo_txt{
width: 380px;
word-wrap: break-word;
word-break: break-all;
display: inline-block; /* 確保 span 元素遵守寬度規則 */
}

.important_li{
color:#ff8c00;
}

.urgent_li{
color:#ff0000;
}

.del_btn{
position: absolute;
right: 5px;
/* float: right; */
width: 25px;
height: 25px;
color: #fff;
background-color:#82715f;
font-size: 20px;

}
.del_btn:hover{
background-color: #ff0000;
cursor: pointer;
}

.on_off_btn {
position: absolute;
right:-25px;
/* float: right; */
width: 25px;
height: 25px;
border: 1px solid #82715f;
font-size: 20px;

}

.done{
width: 60px;
padding-left: 5px;
display:none;
}

作業取自: https://codelove.tw/@howtomakeaturn/post/gqBkPx
by 站長阿川