練習 TodoList 的原因 TodoList 看似簡單的介面,但其實隱藏了很多小細節,記錄一下這次的練習,預計要完成的畫面如下:
練習重點
切版的熟悉度。
綁定 DOM 元素。
紀錄資料再 localStorage。
透過 setItem
與 getItem
實現新增待辦。
透過 dataset
與 splice
屬性抓出排序與刪除資料。
製作 TodoList
navbar 用 Bootstrap 4 套件很快速就可以完成了,相關的 CSS 再看 codepen,就不做太多陳述。
下方的 content 分成兩欄,這邊稍微紀錄一下:
左邊 siderbar
設定為 Width:30%
右邊 inputbar
為 width: 67%
,再往左邊推 margin-left: 3%
,總共為 70%
。
因為最下面的 taskList
清單想要再 inputbar
下方,且限制其寬度, CSS 設定為 width: 70%
跟 margin-left: 26%
。
HTML 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <div class ="content" > <div class ="siderbar" > <ul > <li > <a href ="#" > 今天</a > </li > <li > <a href ="#" > 明天</a > </li > <li > <a href ="#" > 未來七天</a > </li > </ul > </div > <div class ="inputbar" > <input type ="text" name ="task" id ="task" placeholder ="請輸入待辦事項" > <button class ="btn" > <i class ="fas fa-plus" > </i > </button > </div > </div > <ul class ="taskList" > </ul > </div >
SCSS 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 .content { margin-top : 3% ; display : flex; .siderbar { width : 30%; line-height : 2; margin-right : 0; a { text-decoration : none; color : $primary-color; &:hover { font-weight : bold ; } } } .inputbar { display : flex; margin-left : 3% ; width : 100% ; height : 42px ; //限制高度,就能讓 inputbar 的高度固定,不會受 flex 影響 input { width : 100% ; margin-right : 0.3em ; } } .btn { background-color : $primary-color; padding : 5px ; color : #fff ; font-size : 16px ; width : 42px ; &:hover { background-color: (darken($color: $primary-color, $amount: 20%)); color : #fff ; } } }
以上是靜態頁面 會呈現的樣子,但 todolist 需要有互動,可增加與刪除事項的功能,所以要加入 JavaScript。
JavaScript 先綁定資料,
1 2 3 4 5 6 var btn = document .querySelector(".btn" );var input = document .querySelector("#task" );var list = document .querySelector(".taskList" );
宣告 getData 變數作為從 localStorage
取出 value
,typeof 會是 string,
1 var getData = localStorage.getItem("task" );
先宣告一個 getDataAry = 空值,如果 getData 是 true,會去解析 getDataAry 字串資料成陣列,否則就會空陣列。
1 2 3 4 5 6 7 var getDataAry = "" ;if (getData) { getDataAry = JSON .parse(getData); } else { getDataAry = []; } var taskList = getDataAry;
更新清單,組完字串後,會放在 .taskList
的 ul
中,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 updateList(); function updateList ( ) { var len = taskList.length; var str = "" ; for (var i = 0 ; i < len; i++) { str += ` <li> <a data-num=${i} > <i class='fas fa-times-circle'></i> </a>${taskList[i]} </li>` ; } list.innerHTML = str; var taskListStr = JSON .stringify(taskList); localStorage.setItem("task" , taskListStr); }
建立新增資料 與刪除資料 監聽事件,
1 2 3 4 btn.addEventListener("click" , getInput, false ); list.addEventListener("click" , delTask, false );
當使用者輸入資料,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function getInput ( ) { console .log(input.value); var text = input.value; if (text === "" ) { alert("您未輸入事項" ); return ; } taskList.push(text); input.value = "" ; updateList(); }
當使用者刪除資料,點擊到的 nodeName
為 A
或是 I
就中斷,造成點選A
和 I
就結束動作,而點到後面文字,也就是 LI
則被刪除,所以要把刪除的動作放在 if
判斷內就能點 icon 圖示刪除 todo
1 2 3 4 5 6 7 8 9 10 function delTask (e ) { var current = e.target.nodeName; if (current == "A" || current == "I" ) { var currentNum = e.target.dataset.num; taskList.splice(currentNum, 1 ); } else { return ; } updateList(); }
結語 JS 的互動行為有點細,跟人腦思維不太一樣,要一個口令一個動作,也不用想得太難,要直觀一點,可能人腦的思維可以很快速的整合一件事情的內容,但 JS 是要透過很多的行為告訴電腦該怎麼完成這些很細的動作。很有趣的練習!!
附上 codepen,可以玩玩看: https://codepen.io/hnzxewqw/pen/eYmRgoJ