拖延症晚期的我,终于用原生JS撸了个To-Do List!

279 阅读3分钟

“人生苦短,待办太多。”
——一位每天都在立flag的前端萌新

前言:为什么要造轮子?

作为一名拖延症晚期患者,我的待办事项总是像薛定谔的猫一样,既存在又不存在。市面上的To-Do List工具千千万,但我偏要用代码“自虐”一把,亲手撸一个属于自己的便签应用。
别问,问就是“造轮子使我快乐”!


【页面效果图】

image.png

一、项目结构一览

项目一共三个文件:

  • index.html:页面结构担当
  • style.css:颜值担当
  • index.js:灵魂担当

目录结构如下:

/todoList
  ├── index.html
  ├── style.css
  └── index.js

二、HTML:简洁不简单

先来看看页面结构:

<div class="container">
  <div class="heading">
    <h1 class="heading_title">To-Do List</h1>
  </div>
  <form class="form">
    <label for="todo" class="form_label">~ Today I want to ~</label>
    <input type="text" class="form_input" id="todo" size="30" required>
    <button class="button"><span>submit</span></button>
  </form>
  <ul class="todo_list"></ul>
</div>
  • 表单:输入今天的flag,按下submit,梦想起飞。
  • ul.todo_list:动态渲染所有待办事项。
  • 无多余div,结构清爽,强迫症患者狂喜。

三、CSS:高颜值的秘密

你以为To-Do List只能“丑拒”?不!
本项目采用手写体字体(Gochi Hand),配色温柔,圆角、阴影、渐变、波浪线……
每一处细节都在说:“我很可爱,快来用我!”

亮点速览

  • 背景:温柔的粉色+渐变点阵,治愈系满分。
  • 输入框:下边框虚线,聚焦时高亮,手感一流。
  • 按钮:自带动效,点击有旋转,像极了你点外卖的手速。
  • 待办项:鼠标悬停自动划掉,体验“完成任务”的快感。
.form_input:focus{
    outline: none;
    border: dashed 3px #95a9ea;
}
.button:active, .button:focus{
    outline: 0;
    transform: rotate(0deg);
}
.todo_list li:hover{
    text-decoration: line-through wavy red;
}

【页面效果图】

ezgif-52e00a33721bc9.gif

四、JavaScript:灵魂交互

1. 添加待办事项

  • 监听表单提交事件,阻止默认刷新。
  • 获取输入内容,生成唯一ID(用时间戳,绝不撞车)。
  • 新事项加入数组和DOM,页面即刻更新。
form.addEventListener('submit', function(e){
    e.preventDefault();
    let itemId = String(Date.now());
    let toDoItem = input.value;
    addItemToArray(itemId, toDoItem);
    addItemToDom(itemId, toDoItem);
});

2. 数据结构

  • 用一个数组toDoListArray存储所有待办事项,每个事项是{id, todoItem}对象。
  • 这样方便后续扩展,比如本地存储、同步云端等。

3. 渲染到页面

  • 每次添加都动态创建li,设置data-id,方便后续操作。
function addItemToDom (id, item) {
    const li = document.createElement('li');
    li.textContent = item;
    li.setAttribute('data-id', id);
    ul.appendChild(li);
}

4. 删除待办事项

  • 监听ul的点击事件,点谁删谁,体验“秒杀”任务的快感。
  • 先从数组删,再从DOM删,数据和视图双保险。
ul.addEventListener('click', function(e) {
    removeItemFromArray(e.target.getAttribute('data-id'));
    removeItemFromDom(e.target.getAttribute('data-id'));
});

五、技术细节与进阶思考

1. 事件委托

  • 只给ul加事件监听,所有li都能响应,性能优雅,代码简洁。

2. 唯一ID生成

  • Date.now()生成时间戳,保证每个待办项的id独一无二。

3. 数据与视图分离

  • 先操作数组,再操作DOM,便于后续维护和功能扩展。

4. 可扩展性

  • 目前只实现了添加和删除,后续可以加本地存储、编辑、优先级、拖拽排序等功能。
  • 甚至可以用React/Vue重构,体验“前端三件套”的快乐。

六、初学者的“踩坑”与“收获”

  • 表单默认行为:不阻止会刷新页面,输入全没了,血泪教训。
  • 事件绑定:直接给li绑定事件?太麻烦,事件委托yyds。
  • 样式细节:outline: 0; 虽然美观,但要注意无障碍体验。
  • 代码分层:数据和视图分开,后续维护不头秃。

七、总结

用原生JS撸To-Do List,不只是为了“造轮子”,更是一次前端基础能力的全方位锻炼。从结构、样式到交互,每一步都能学到新东西。
如果你也有拖延症,不妨试试自己写一个,或许能让你的人生flag倒得慢一点点!

“写代码的快乐,只有亲手敲下去才懂!”
“To-Do List写完了,人生的待办清单也能慢慢清零!”