--- tags: 六角學院_JavaScript 必修篇 - 前端修練全攻略 --- todolist_音時艾拉 應援筆記 ✧*。٩(ˊωˋ*)و✧*。 === <iframe height="300" style="width: 100%;" scrolling="no" title="8/25 TodoList" src="https://codepen.io/ototoki_error/embed/PojwEoo?default-tab=html%2Cresult&editable=true" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> See the Pen <a href="https://codepen.io/ototoki_error/pen/PojwEoo"> 8/25 TodoList</a> by 音時エラー⚙️ (<a href="https://codepen.io/ototoki_error">@ototoki_error</a>) on <a href="https://codepen.io">CodePen</a>. </iframe> 0.如何內嵌codepen --- 1. 點擊在 Fork 旁邊的 Embed 2. 點選 Inframe , 把code 貼到 HackMD 裡 1.新增資料 --- ### HTML 1. 在標籤 input 內加入 id 2. 在標籤 a 內加入 id ```htmlmixed= <div class="card input"> <input type="text" placeholder="請輸入待辦事項" id="inputText" /> <a href="#" class="btn_add" id="addBTN">+</a> </div> ``` ### JS 1. 創建變數 `inputText addBTN` 存入 DOM 2. 創建陣列 `todoData` 存取代辦事項 3. 監聽 `addBTN` 點擊事件,如果有,執行 `addTodo()` 4. function `addTodo()` 1. 創建物件 `todo` 存取 3 個屬性`txt id checked` 1. `txt: inputText.value` 將輸入欄的內容存進去 2. `id: new Date().getTime()` 創建一個 `Date` 物件,並使用 `.getTime()` 取得毫秒數,用來創造獨一無二的 id 3. `checked: ""` 等下會使用改變 class 的方式更換造型 5. 如果 `todo.txt` 不是空字串,就用 `.unshift()` 加到陣列最前面,並將輸入欄清空 ```javascript= const inputText = document.getElementById("inputText"); const addBTN = document.getElementById("addBTN"); let todoData = []; // 1. 新增 addBTN.addEventListener('click', addTodo); function addTodo() { let todo = { txt: inputText.value, id: new Date().getTime(), checked: '', }; if (todo.txt != '') { todoData.unshift(todo); inputText.value = ''; } updateList(); } ``` 2.渲染 --- ### HTML 1. 在標籤 ul 內加入 id ```htmlmixed= <ul class="list" id="todoList"></ul> ``` ### JS 1. 創建變數 `todoList` 存入 DOM 2. function `render(arr)` 1. 創建變數 `str` 2. `arr.forEach()` 將每個陣列裡的東西跑過一次 1. 將要新增的內容賦予 `str` ,並利用 Template literals 更改成物件內容 3. 使用 `todoList.innerHTML` 更改內容 ```javascript= // 2. 渲染 const todoList = document.getElementById('todoList'); function render(arr) { let str = ''; arr.forEach((i) => { str += ` <li data-id="${i.id}"> <label class="checkbox" for=""> <input type="checkbox" ${i.checked}/> <span>${i.txt}</span> </label> <a href="#" class="delete asd"></a> </li> `; }); todoList.innerHTML = str; } ``` 3.tab 切換 (CSS樣式) --- ### HTML 1. 在標籤 ul 內加入 id ```htmlmixed= <ul class="tab" id="tab"></ul> ``` ### JS 1. 創建變數 `tab` 存入 DOM 2. 創建變數 `toggleStatus` 儲存現在的狀態(全部(預設)、待完成、已完成) 3. 監聽 `tab` 點擊事件,如果有,執行 `changeTab()` 4. function `changeTab()` 1. 將變數 `toggleStatus` 更改成現在點擊的狀態,`.dataset` 可以取得標籤內 `data-*` 的值(以物件方式傳回), `.dataset.tab` 可以取得 li 標籤裡 data-tab 的值 2. 宣告變數 `tabs` 存入 DOM 陣列 3. `tabs.forEach` 將 li 標籤裡 'class' 內的 'active' 移除 4. 將點擊的li 標籤裡 'class' 內的 加上 'active' ```javascript= //3. tab 切換 (CSS樣式) const tab = document.getElementById('tab'); let toggleStatus = 'all'; tab.addEventListener('click', changeTab); function changeTab(e) { toggleStatus = e.target.dataset.tab; let tabs = document.querySelectorAll('#tab li'); tabs.forEach((i) => { i.classList.remove('active'); }); e.target.classList.add('active'); updateList(); } ``` 4.刪除 & 切換 checked 狀態功能 --- ### JS 1. 監聽 `todoList` 點擊事件,如果有,執行`deleteAndChecked()` 2. function `deleteAndChecked()` 1. 宣告變數 `id` ,使用 `.closest('li')` 取得最靠近點選元素的 parents,使用 `.dataset.id` 可以取得 li 標籤裡 data-id 的值 2. 如果點擊的 'class' 內容為 'delete' 1. 取消 a 標籤預設效果 2. 使用 `.filter() ` 將其他的物件留下 3. 否則(切換 checked 狀態功能) 1. 如果這個物件的 checked 屬性等於 'checked',就把 checked 屬性改成空字串 2. 否則就把 checked 屬性改成 'checked' ```javascript= // 刪除 & 切換 checked 狀態功能 todoList.addEventListener('click', deleteAndChecked); function deleteAndChecked(e) { let id = e.target.closest('li').dataset.id; console.log(e.target.classList.value) if (e.target.classList.value == 'delete') { e.preventDefault(); todoData = todoData.filter((i) => i.id != id); } else { // 切換 checked 狀態功能 todoData.forEach((i, index) => { if (i.id == id) { if (todoData[index].checked == 'checked') { todoData[index].checked = ''; } else { todoData[index].checked = 'checked'; } } }); } updateList(); } ``` 5.更新代辦清單 --- ### JS 1. function `updateList()` 1. 宣告空陣列 `showData` 2. 如果現在 `toggleStatus == 'all'`,保持原本 `todoData` 3. 否則如果 `toggleStatus == 'work'` ,將 `todoData` 篩選出還沒完成的(該物件的 checked 屬性是空字串) 4. 否則,將 `todoData` 篩選出還完成的(該物件的 checked 屬性是 'checked') 5. 宣告變數 `workNum` 存入 DOM 6. 宣告變數 `todoLength` 賦予從 `todoData` 篩選出還沒完成的(該物件的 checked 屬性是空字串) 7. 利用 `workNum.textContent` 將內容改成待完成的數量(`todoLength.length`) 8. 用 `render(showData)` 渲染出符合現在 toggleStatus 的物件 6. 呼叫 `updateList()` 初始化頁面 ```javascript= // 5. 更新代辦清單 function updateList() { let showData = []; if (toggleStatus == 'all') { showData = todoData; } else if (toggleStatus == 'work') { showData = todoData.filter((i) => i.checked == ''); } else { showData = todoData.filter((i) => i.checked == 'checked'); } const workNum = document.getElementById('workNum'); let todoLength = todoData.filter((i) => i.checked == ''); workNum.textContent = todoLength.length; render(showData); } //初始 updateList(); ``` 6.刪除已完成 todo --- ### HTML 1. 在標籤 a 內加入 id ```htmlmixed= <a href="#" id="deleteBTN">清除已完成項目</a> ``` ### JS 1. 創建變數 `deleteBTN` 存入 DOM 2. 監聽 `deleteBTN` 點擊事件,如果有,執行 `function(e)` 4. `function(e)` 1. 移除 a 標籤預設效果 2. 篩選出還沒完成的(該物件的 checked 屬性不是 'checked') 3. 使用 `updateList()` 更新 ```javascript= // 6.刪除已完成 todo const deleteBTN = document.getElementById('deleteBTN'); deleteBTN.addEventListener('click', function (e) { e.preventDefault(); todoData = todoData.filter((i) => i.checked != 'checked'); updateList(); }); ``` 7.優化 --- ### JS 1. 監聽 `inputText` 按下鍵盤事件,如果有,執行 `function(e)` 4. `function(e)` 1. 如果鍵盤按下的( e.key ) 是 'Enter' ,就執行 `addTodo()` ```javascript= // 7. 優化 inputText.addEventListener('keypress', function (e) { if (e.key == 'Enter') { addTodo(); } }); ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up