用 localStorage 打造本地待办清单:一个轻量级的前端实践

用 localStorage 打造本地待办清单:一个轻量级的前端实践

在现代网页开发中,我们常常需要在浏览器端保存一些用户数据,比如用户的偏好设置、临时输入内容,或者像本文要实现的------一个本地待办事项列表(Todo List)。借助浏览器提供的 localStorage,我们可以轻松地将数据持久化存储在用户的设备上,即使关闭页面或重启浏览器,数据也不会丢失。

localStorage 是什么?

localStorage 是 Web Storage API 的一部分,它为每个域名提供了一块独立的存储空间。它的特点是:

  • 永久存储:除非用户手动清除或通过代码删除,否则数据不会过期。
  • 键值对结构 :所有数据都以字符串形式存储,因此通常需要配合 JSON.stringify()JSON.parse() 来处理对象。
  • 同源策略限制:只能被同一协议、域名和端口下的页面访问。

实现一个本地待办清单

下面是一个完整的待办清单示例,使用 HTML、CSS 和原生 JavaScript 构建,并利用 localStorage 实现数据持久化。

HTML 结构

xml 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>LOCAL TAPAS</title>
    <link rel="stylesheet" href="./common.css">
</head>
<body>
    <div class="wrapper">
        <h2>LOCAL TAPAS</h2>
        <ul class="plates">
            <li>Loading Tapas...</li>
        </ul>
        <form class="add-items">
            <input type="text" placeholder="Item Name" required name="item">
            <input type="submit" value="+ Add Item">
        </form>
    </div>
    <!-- JavaScript 脚本 -->
</body>
</html>

页面包含一个标题、一个待办项列表容器(<ul class="plates">)以及一个用于添加新事项的表单。

CSS 样式亮点

css 复制代码
html {
    box-sizing: border-box;
    min-height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    text-align: center;
}

*, *::before, *::after {
    box-sizing: inherit;
}

.plates li {
    display: flex;
}

.plates input {
    display: none;
}

.plates input + label:before {
    content: "⬜️";
    margin-right: 10px;
}

.plates input:checked + label:before {
    content: "✅";
}

这里有几个关键点:

  • 使用 flex 布局让页面整体居中,同时让每个待办项内部也采用弹性布局。
  • 利用 input[type=checkbox] 配合 label 和伪元素 ::before 实现自定义复选框样式。
  • outline 属性用于高亮输入框焦点状态,且不占用盒模型空间。
  • overflow: hidden 可防止子元素溢出父容器(虽然本例未直接使用,但属于常用技巧)。

注意:CSS 中并非所有属性都会继承。例如 font-sizecolor 会从父元素继承,而 backgroundwidthheight 等则不会。开发者需根据需求显式设置。

JavaScript 逻辑

核心逻辑围绕三个函数展开:

1. 初始化数据
ini 复制代码
const items = JSON.parse(localStorage.getItem('todos')) || [];

尝试从 localStorage 中读取名为 'todos' 的数据,若不存在则初始化为空数组。

2. 渲染列表
ini 复制代码
function populateList(plates = [], platesList) {
    platesList.innerHTML = plates.map((plate, i) => `
        <li>
            <input type="checkbox" data-index=${i} id="item${i}" ${plate.done ? 'checked' : ''} />
            <label for="item${i}">${plate.text}</label>
        </li>
    `).join('');
}

该函数接收待办项数组和 DOM 容器,动态生成带复选框的列表项,并通过 data-index 记录索引以便后续操作。

3. 添加与切换状态
ini 复制代码
function addItem(event) {
    event.preventDefault();
    const text = this.querySelector('[name=item]').value.trim();
    if (!text) return;
    items.push({ text, done: false });
    localStorage.setItem('todos', JSON.stringify(items));
    populateList(items, itemsList);
    this.reset();
}

function toggleDone(event) {
    if (event.target.tagName === 'INPUT') {
        const index = event.target.dataset.index;
        items[index].done = !items[index].done;
        localStorage.setItem('todos', JSON.stringify(items));
        populateList(items, itemsList);
    }
}
  • 表单提交时阻止默认刷新行为,提取输入值并存入 items 数组。
  • 点击复选框时,根据 data-index 更新对应项的完成状态。
  • 每次变更后立即同步到 localStorage,确保数据持久化。

最后绑定事件监听器:

scss 复制代码
addItems.addEventListener('submit', addItem);
itemsList.addEventListener('click', toggleDone);
populateList(items, itemsList); // 初次渲染

小结

这个"Local Tapas"(本地小食清单)虽小,却完整展示了前端开发中的多个核心概念:

  • 数据持久化 :通过 localStorage 实现无服务器依赖的本地存储。
  • DOM 操作与事件委托:高效更新界面,避免重复绑定事件。
  • CSS 继承与布局:理解哪些样式可继承,合理使用 Flexbox 实现响应式结构。
  • 函数式思维:将逻辑封装为可复用函数,提升代码可读性与维护性。

无需后端、不依赖框架,仅用浏览器原生能力,就能构建一个实用又美观的交互应用------这正是现代 Web 开发的魅力所在。

相关推荐
qq_589666059 小时前
TypeScript 完整入门教程
前端·javascript·typescript
绘梨衣的sakura路9 小时前
Fastjson ≤ 1.2.83 新型 RCE 漏洞深度分析:三层绕过机制与完整利用链
安全·web安全·json
星栈独行10 小时前
翻完 Pi 源码:它和 Codex、Claude Code 有何不同
开发语言·javascript·人工智能·程序人生
落落Plus11 小时前
浏览器缓存机制详解
javascript·缓存·浏览器缓存
用户0595401744612 小时前
LLM对话记忆测试踩坑实录:手工回归30分钟,自动化后2分钟发现3个隐藏Bug
前端·css
浅水壁虎13 小时前
vue基础(第二章 )
前端·javascript·vue.js
界面开发小八哥13 小时前
界面控件DevExtreme v26.1新版亮点——支持Angular 22
前端·javascript·angular.js·devexpress·ui开发·devextreme
mONESY15 小时前
React useState 核心原理与最佳实践:从异步更新到性能优化全解
javascript
腻害兔15 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:CRM 客户关系模块深度解析——从线索到回款,一套完整的 B2B 销售闭环是怎么搭的?
java·前端·javascript·vue.js·产品经理·ai编程
gis开发之家16 小时前
《Vue3 从入门到大神37篇》Vue3 源码详解(七):watch 与 watchEffect 源码对比——副作用是如何被追踪的?
javascript·前端框架·vue3·vue3源码