番外篇(2)一起来做 To Do List!- 实作篇(2)

大家新年快乐!上一篇完成後还剩下这些功能:

  • 可以一次删除全部的代办事项
  • 能删除所有已完成的代办事项的内容及数量
  • 代办事项预设以时间排列
  • 代办事项的顺序可以被使用者拖拉
  • 超过时间还没完成的代办事项以红色显示
  • 有进度、月份、种类的筛选器
  • 有分析按钮,按下去会跳出视窗,显示种类的圆饼图
  • RWD 所以要有手机汉堡选单

刚刚在写文章时才发现,我上一篇不小心把「完成的代办事项会跑到最下方」顺便写好了。如果你 2/13 前已经看过上一篇,我有把怎麽写的补充回上一篇。此外我发现本来判断完成数量的判断式有 bug ,因此换了一种写法,一样有更新。

接着,让我们来处理时间排序的问题吧!

第四步

在日期时间输入的部分,要自己制作也是可以,但因为要规范合理性等等,我最後选择使用知识篇介绍过的套件 flatpickr 。因为想将日期与时间拆分开来,因此要分开设定:

flatpickr(dateInput,{
    altInput: true,
    altFormat: "n/j",
    dateFormat: "m/d",
    minDate: "today", //限定只能选今天以後的日期
    maxDate: "12/31", //限定只能选今年
    disableMobile: "true"
});
flatpickr(timeInput,{
    enableTime: true,
    noCalendar: true,
    dateFormat: "H:i",
    time_24hr: true,
    disableMobile: "true"
});

接着回到需求清单,先从比较简单的「代办事项预设以时间排列」开始。没错,就是 sort() 。我们分别在本地端储存两种资料:todos 和 complete ,并在 function getTodos 中将两种资料取出,用 JSON.parse 转回原来方式。而 sort() 会从最左边的数开始比较。正好我们的阵列是先打日期,再打时间,比较下来没有问题。在 else if(localStorage.getItem('complete') !== null && localStorage.getItem('todos') !== null){...} 後面加上:

todos.sort();
completes.sort();

第五步

要让超过时间还没完成的代办事项以红色显示,这句话要如何拆分呢?首先应该是要先取得现在的时间吧?然後才能做後面的比较。

let d = new Date();
        //把目前日期和时间转成数字
        let thismonth = parseInt(`${d.getMonth()+1}`); 
        let today = parseInt(`${d.getDate()}`); 
        let hourNow = parseInt(`${d.getHours()}`);
        let minNow = parseInt(`${d.getMinutes()}`);

接着要取得代办事项的日期和时间,这里我用 split("/",2) 以 / 开始拆开前後的月份和日期,用 split(":",2) 以 : 开始拆开前後的小时和分钟。拆开後即可得到分别的数。

        let taskDate= todo[0];
        taskDate = taskDate.split("/",2);
        let taskMonth = taskDate[0];
        let taskDay = taskDate[1];

        let taskTime = todo[1];
        taskTime = taskTime.split(":",2);
        let taskHour = taskTime[0]; 
        let taskMin = taskTime[1];

最後当然就要写判断式啦!如果代办事项的月、日、时、分通通小於目前时间,把本来的样式移除掉,加上过期的 css 样式。再到 css 去撰写过期的样式就可以罗!

        if(taskMonth <= thismonth && taskDay <= today && taskHour < hourNow && taskMin < minNow){ 
            todoLi.classList.remove("todo");
            todoLi.classList.add("overdue-todo");
        };

为了让画面跑好的时候就呈现对的资讯,所以上述程序码一样要放到 function getTodos 。

第六步

一次删除的功能大同小异而且挺简单的,加上按键和按键的监听,按下去後除了删掉画面上的数字,也要删掉本地端的。因为我希望即使删掉已完成的工作数量,还是要显示一句「尚未有完成的工作」在画面中,因此我另外放入 innerHTML 做设定。

function clearNumCheck(){
    if(confirm("已完成的丰功伟业将会全数删除,你确定要这麽做吗?")){
        completedTotalNum = 0;
        completedNum.innerHTML= `尚未有完成的工作`;
        localStorage.removeItem('completeTask'); //连同本地端一起清空
        localStorage.removeItem('complete'); //连同本地端一起清空
        window.location.reload();
    }
}
function deleteAllTask(){
    if(confirm("确定删除所有代办事项?")){
        todoList.innerText = "";
        localStorage.removeItem('todos'); //连同本地端一起清空
    }
}

第七步

今天的最後,要完成的是「代办事项的顺序可以被使用者拖拉」这个功能。我使用的是 sortable 外挂,使用方法在知识篇有提过。

new Sortable(todoList, {
    animation: 150,
    ghostClass: 'sortable-ghost' //拖曳时的 css 样式名称
});

我只有用到最简单的设定,并在 css 中设定 sortable-ghost class 细节。

下一篇我们会做完剩下的:

  • 有进度、月份、种类的筛选器
  • 有分析按钮,按下去会跳出视窗,显示种类的圆饼图
  • RWD 所以要有手机汉堡选单

敬请期待!


<<:  React和DOM的那些事-节点更新

>>:  番外篇(2)一起来做 To Do List!- 实作篇(3)

VPN和EAP

-VPN 和 EAP 在 802.1X 中,请求者与身份验证者通信,身份验证者将身份验证消息转发到...

Day-5 :阿公阿嬷都看得懂的前後端分离架构?

前端系虾米? 身为一个麻瓜,当初在看到前端两个字, 着实就猜想不就字面意思?应该系前後面,反之另一个...

Vue ⑅:v-bind 动态绑定 HTML 属性

如标题 (⑅•ᴗ•⑅) v-bind 可以动态绑 HTML 属性、将资料传递到元素上。   几个重点...

30天零负担轻松学会制作APP介面及设计【DAY 18】

大家好,我是YIYI,今天我要来制做制做纪录月经的页面。 纪录经期 这边我把左上角的LIST换成返回...

30天学会Python: Day 8-维度展开 二维容器

用容器装非容器的资料(整数、浮点数、布林)是一维的概念,可以想成是数学中的数列,或是前面举例的火车 ...