感想:
長達30天的自我挑戰要結束了,其實內心也有點不捨,也感謝這挑戰給了我許多查資料的動力,當道某些講解看不懂就再找其他講解,直到一己看懂,也喜歡自己那份投入的心情。對我來說第30天不是結束,而是馬拉松賽跑的其中一個里程碑,期望自己還有看到這篇文章的你,也保持那股動力持續地走下去。
有些篇章因為時間關係準備的資料不夠齊全,因此我會繼續編輯更新!
製作ToDoList流程-3:
資料補充:
Math.floor():函式會回傳小於等於所給數字的最大整數。
slice():方法會回傳一個新陣列物件,為原陣列選擇之 begin 至 end(不含 end)部分的淺拷貝(shallow copy)。而原本的陣列將不會被修改。
//建立一個物件,可以放todo的資料
let myTodo = {
todoText:todoText,
todoMonth:todoMonth,
todoDate:todoDate
}
//把輸入的資料放進Local Storage,陣列裡面再放todo資料物件
let myList = localStorage.getItem("list");
//如果key是空的,就加入myTodo物件進空陣列,並且用JSON.stringify()轉換成字串
if (myList == null) {
localStorage.setItem("list",JSON.stringify([myTodo]));
} else {
//如果key不是空,就把value用JSON.parse()轉換成陣列
let myListArray = JSON.parse(myList);
//把新增的資料推進myTodo物件
myListArray.push(myTodo);
//再將它轉換成字串,才能顯示在Storage
localStorage.setItem("list",JSON.stringify(myListArray));
};
console.log(myTodo);
loadData();
function loadData(){
// 讓Local Storage資料展示在網頁
let myList = localStorage.getItem("list");
// 如果key不等於空
if (myList !== null) {
let myListArray = JSON.parse(myList);
myListArray.forEach((item)=>{
//建立todo
let todo = document.createElement("div");
todo.classList.add("todo");
let text= document.createElement("p");
text.classList.add("todo-text");
text.innerText = item.todoText;
let time = document.createElement("p");
time.classList.add("todo-time");
time.innerText = item.todoMonth + " / " + item.todoDate;
//看item有什麼
console.log(item);
console.log("item.todoText: " + item.todoText);
console.log("item.todoMonth: " + item.todoMonth);
console.log("item.todoDate: " + item.todoDate);
todo.appendChild(text);
todo.appendChild(time);
//建立勾勾和垃圾桶
let completeButton = document.createElement("button");
completeButton.classList.add("complete");
completeButton.innerHTML = '<i class="fa-regular fa-check"></i>';
//按下勾勾按鈕時的動作
completeButton.addEventListener("click", (e)=>{
//找父元素
let todoItem = e.target.parentElement;
//按下時新增class
todoItem.classList.toggle("done");
})
let trashButton = document.createElement("button");
trashButton.classList.add("trash");
trashButton.innerHTML = '<i class="fa-light fa-trash"></i>';
trashButton.addEventListener("click", (e)=>{
//找父元素
let todoItem = e.target.parentElement;
//動畫先執行完,才會執行這個callback function
todoItem.addEventListener("animationend",()=>{
//讓這裡也能刪掉local Storage的項目
let text = todoItem.children[0].innerText;
let myListArray = JSON.parse(localStorage.getItem("list"));
myListArray.forEach((item, index)=>{
if(item.todoText == text){
//.splice()刪除目前既有元素
myListArray.splice(index,1);
//更新Local Storage
localStorage.setItem("list",JSON.stringify(myListArray));
}
})
//清除目前的父元件
todoItem.remove();
})
todoItem.style.animation = "scaleDown 0.3s forwards"
})
//勾勾和垃圾桶加到todo裡
todo.appendChild(completeButton);
todo.appendChild(trashButton);
//把建立的todo放入section
section.appendChild(todo);
});
}
}
如果不清楚myListArray.forEach((item)的item是麼什麼,可以console出來:
myListArray.forEach((item)=>{
//建立todo
let todo = document.createElement("div");
todo.classList.add("todo");
let text= document.createElement("p");
text.classList.add("todo-text");
text.innerText = item.todoText;
let time = document.createElement("p");
time.classList.add("todo-time");
time.innerText = item.todoMonth + " / " + item.todoDate;
//看item有什麼
console.log(item);
console.log("item.todoText: " + item.todoText);
console.log("item.todoMonth: " + item.todoMonth);
console.log("item.todoDate: " + item.todoDate);
}
console結果:
在上方的清除按鈕事件裡也需要加入這一段:
按「清除」按鈕時也能刪掉local Storage的項目,搭配splice()
//讓這裡也能刪掉local Storage的項目
let text = todoItem.children[0].innerText;
let myListArray = JSON.parse(localStorage.getItem("list"));
myListArray.forEach((item, index)=>{
if(item.todoText == text){
//.splice()刪除目前既有元素
myListArray.splice(index,1);
//更新Local Storage
localStorage.setItem("list",JSON.stringify(myListArray));
}
})
// 根據日期作排列
function mergeTime(arr1,arr2){
let result = [];
let i = 0;
let j = 0;
while(i < arr1.length && j < arr2.length){
if(Number(arr1[i].todoMonth) > Number(arr2[j].todoMonth)){
result.push(arr1[j]);
j++;
} else if (Number(arr1[i].todoMonth) < Number(arr2[j].todoMonth)){
result.push(arr1[i]);
i++;
}else if(Number(arr1[i].todoMonth) == Number(arr2[j].todoMonth)){
//如果月份相同,就比較日期
if(Number(arr1[i].todoDate) > Number(arr2[j].todoDate)){
result.push(arr2[j]);
j++;
} else {
result.push(arr1[i]);
i++;
}
}
}
console.log("我是arr1:");
console.log(arr1);
console.log("我是arr2:");
console.log(arr2);
console.log("我是arr1[i]:");
console.log(arr1[i]);
console.log("我是arr2[j]:");
console.log(arr2[j]);
console.log("i:");
console.log(i);
console.log("j:");
console.log(j);
//如果還是有剩下沒有符合條件的結果,就讓它們全部push到result陣列裡面
while(i < arr1.length){
result.push(arr1[i]);
i++;
}
while(j < arr2.length){
result.push(arr2[j]);
j++;
}
return result;
}
//遞迴演算法
function mergeSort(arr){
// 如果長度是1就不用做任何事
if(arr.length ===1){
return arr;
} else {
//Math.floor()小於等於的最大整數
let middle = Math.floor(arr.length / 2);
//用middle作結束
let right = arr.slice(0,middle);
//用middle作開始
let left = arr.slice(middle,arr.length);
console.log("我是middle:");
console.log(middle);
console.log("我是right:");
console.log(right);
console.log("我是left:");
console.log(left);
return mergeTime(mergeSort(right),mergeSort(left));
}
}
//驗證看是否有做排列
console.log(mergeSort(JSON.parse(localStorage.getItem("list"))));
// 按下sort by time按鈕根據日期作排列
let sortButton = document.querySelector("div.sortbtton");
sortButton.addEventListener("click",()=>{
//排列這些資料,要先找到list
let sortedArry = mergeSort(JSON.parse(localStorage.getItem("list")));
//用stringify()轉換資料型態
localStorage.setItem("list",JSON.stringify(sortedArry));
//先把它們刪掉,再重新排列一次
let len = section.children.length;
for (let i=0;i<len;i++){
section.children[0].remove();
}
//執行讓Local Storage資料展示在網頁的function
loadData();
});
ToDoList 設計草案(持續規劃中...):
需要再一點時間Q_Q
javascript - How can I remove a specific item from an array? - Stack Overflow
Array.prototype.splice() - JavaScript | MDN
Math.floor() - JavaScript | MDN
Array.prototype.slice() - JavaScript | MDN