
本文介绍一种基于表单与事件监听的轻量级 todo 列表实现方案:用户在输入框中按下 enter 键时,自动插入一个含 checkbox 和文本输入的新待办项;按 backspace 清空当前输入后可删除该项,界面简洁无干扰。
本文介绍一种基于表单与事件监听的轻量级 todo 列表实现方案:用户在输入框中按下 enter 键时,自动插入一个含 checkbox 和文本输入的新待办项;按 backspace 清空当前输入后可删除该项,界面简洁无干扰。
要构建一个响应式、语义清晰且符合用户直觉的 Todo 应用,避免使用 <textarea></textarea> 是关键一步。原方案中 textarea 无法自然区分“行”概念,导致 Enter 键默认换行而非新增条目,Backspace 也无法精准识别“条目边界”。改用结构化 <form></form> + 多个 <fieldset></fieldset> 嵌套 <input> 的方式,既能保持 DOM 可控性,又能模拟纯文本编辑体验。
✅ 核心实现逻辑
-
Enter 键拦截:监听表单的
keydown事件,当焦点在name="title"的输入框且按键为Enter时,调用add_item()创建新条目; -
Backspace 智能删除:仅当当前输入框为空(
value === '')且按键为Backspace时,移除其所在<fieldset></fieldset>,并将焦点回退至上一项的输入框; -
DOM 结构设计:
- 每个待办项封装为独立
<fieldset></fieldset>(语义化分组,便于定位与操作); - 内含
<input type="checkbox" name="item">和<input type="text" name="title">,顺序固定,便于 CSS 控制布局; - 使用
form.items.append(fs)统一管理所有条目容器,确保插入位置准确。
- 每个待办项封装为独立
? 完整代码示例
<style>
fieldset {
border: none;
margin: 0;
padding: 0;
}
input[type="text"] {
border: none;
font-size: 16px;
padding: 4px 0;
width: 100%;
background: transparent;
}
input[type="text"]:focus {
outline: none;
}
input[type="checkbox"] {
margin-right: 8px;
vertical-align: middle;
}
</style>
<script>
document.forms.form01.addEventListener('keydown', e => {
switch(e.key) {
case 'Enter':
e.preventDefault();
if (e.target.name === 'title') {
add_item(e.target.form);
}
break;
case 'Backspace':
if (e.target.name === 'title' && e.target.value === '') {
e.preventDefault();
remove_item(e.target);
}
break;
}
});
function add_item(form) {
const fs = document.createElement('fieldset');
const cb = document.createElement('input');
cb.type = 'checkbox';
cb.name = 'item';
fs.append(cb);
const tb = document.createElement('input');
tb.type = 'text';
tb.name = 'title';
fs.append(tb);
form.items.append(fs);
tb.focus(); // 新增后立即聚焦,提升操作流
}
function remove_item(input) {
const fs = input.closest('fieldset');
const prevFs = fs.previousElementSibling;
if (prevFs && prevFs.querySelector('input[name="title"]')) {
prevFs.querySelector('input[name="title"]').focus();
fs.remove();
}
}
</script>⚠️ 注意事项与增强建议
-
无障碍支持:当前 checkbox 缺少关联
<label></label>,建议为每个复选框添加id并用for属性绑定,或使用aria-label提升可访问性; -
数据持久化:
<button type="submit">Save</button>仅为占位,实际应用中应绑定form.submit事件,收集所有form.elements.item和form.elements.title的值,序列化为 JSON 存入 localStorage 或提交至后端; - 防误删保护:可增加判断——若只剩最后一项,则禁用 Backspace 删除(避免清空全部);
-
样式微调:可通过
display: flex; align-items: center;优化 checkbox 与文本对齐,或添加transition: opacity 0.2s实现平滑删除动画。
该方案兼顾语义化、可维护性与用户体验,在不依赖框架的前提下,以约 30 行核心 JS 实现了专业级 Todo 输入交互逻辑。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










