You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为类Trello的简易JavaScript笔记项目集成Local Storage实现数据持久化

为类Trello笔记应用集成Local Storage实现数据持久化

嘿,我看了你的代码,要解决刷新后笔记丢失的问题,用Local Storage是个完美的选择!咱们一步步来改造你的代码,让数据能持久化保存:

核心思路

Local Storage只能存储字符串,所以我们会把所有笔记的信息(内容、是否处于编辑状态)存在一个数组里,每次操作后把数组转成JSON字符串存起来;页面加载时再把JSON字符串转成数组,重新渲染所有笔记。


步骤1:封装Local Storage操作函数

先写两个工具函数,方便读写Local Storage,避免重复代码:

// 从Local Storage获取笔记数据
function getNotes() {
  const notesJSON = localStorage.getItem('notes');
  return notesJSON ? JSON.parse(notesJSON) : [];
}

// 把笔记数据保存到Local Storage
function saveNotes(notes) {
  localStorage.setItem('notes', JSON.stringify(notes));
}

步骤2:页面加载时恢复笔记

页面初始化的时候,我们要从Local Storage读取之前保存的笔记,然后把它们渲染到页面上。这里需要写一个渲染函数:

function renderNotes() {
  const ul = document.querySelector('#list-items');
  // 先清空现有内容,避免重复渲染
  ul.innerHTML = '';
  
  const notes = getNotes();
  notes.forEach((note, index) => {
    // 创建笔记元素,和你原来的逻辑一致
    const newLi = document.createElement("textarea");
    newLi.value = note.content;
    newLi.className = "note-li";
    newLi.disabled = note.isDisabled;
    
    // 创建删除按钮
    const dleLi = document.createElement("button");
    dleLi.textContent = "delete";
    dleLi.className = "list-btn";
    
    // 创建编辑按钮
    const edLi = document.createElement("button");
    edLi.textContent = "Edit";
    edLi.className = "list-btn";
    
    // 创建保存按钮
    const saveLi = document.createElement("button");
    saveLi.textContent = "save";
    saveLi.className = "list-btn";
    
    // 组装元素到页面
    ul.appendChild(newLi);
    ul.appendChild(dleLi);
    ul.appendChild(edLi);
    ul.appendChild(saveLi);
    
    // 绑定删除事件
    dleLi.addEventListener("click", () => {
      // 从数组中删除对应笔记
      notes.splice(index, 1);
      saveNotes(notes);
      // 重新渲染页面
      renderNotes();
    });
    
    // 绑定编辑事件
    edLi.addEventListener("click", () => {
      newLi.disabled = !newLi.disabled;
      // 更新数组里的状态
      notes[index].isDisabled = newLi.disabled;
      saveNotes(notes);
    });
    
    // 绑定保存事件
    saveLi.addEventListener("click", () => {
      newLi.disabled = true;
      notes[index].isDisabled = true;
      // 同时更新笔记内容
      notes[index].content = newLi.value;
      saveNotes(notes);
    });
  });
}

// 页面加载完成后调用渲染函数
document.addEventListener('DOMContentLoaded', renderNotes);

步骤3:修改添加笔记的逻辑

原来的添加笔记代码需要改成:创建新笔记后,先把它加入到笔记数组,保存到Local Storage,然后重新渲染页面(这样更统一,避免重复写创建元素的代码):

var input = document.querySelector('#text-input');
document.querySelector("#ad-note-btn").addEventListener("click", () => {
  if (input.value.trim().length > 1) { // 这里用trim()避免空字符
    const notes = getNotes();
    // 添加新笔记对象,默认是禁用状态(和你原来的edit()逻辑一致)
    notes.push({
      content: input.value.trim(),
      isDisabled: true
    });
    saveNotes(notes);
    // 重新渲染页面
    renderNotes();
    // 清空输入框
    input.value = "";
  } else {
    alert("请输入至少2个字符的内容哦!");
  }
});

步骤4:修复原代码里的小问题

  • 原代码里else { ul.appendChild(); }是空的,没有意义,我们换成了友好的提示
  • 原代码中删除按钮的事件里引用edLi和saveLi会有作用域问题,现在用重新渲染的方式就解决了这个问题
  • 原代码的edit()函数逻辑可以简化到渲染和保存的逻辑里

完整修改后的代码

// Local Storage操作函数
function getNotes() {
  const notesJSON = localStorage.getItem('notes');
  return notesJSON ? JSON.parse(notesJSON) : [];
}

function saveNotes(notes) {
  localStorage.setItem('notes', JSON.stringify(notes));
}

// 渲染笔记函数
function renderNotes() {
  const ul = document.querySelector('#list-items');
  ul.innerHTML = '';
  
  const notes = getNotes();
  notes.forEach((note, index) => {
    const newLi = document.createElement("textarea");
    newLi.value = note.content;
    newLi.className = "note-li";
    newLi.disabled = note.isDisabled;
    
    const dleLi = document.createElement("button");
    dleLi.textContent = "delete";
    dleLi.className = "list-btn";
    
    const edLi = document.createElement("button");
    edLi.textContent = "Edit";
    edLi.className = "list-btn";
    
    const saveLi = document.createElement("button");
    saveLi.textContent = "save";
    saveLi.className = "list-btn";
    
    ul.appendChild(newLi);
    ul.appendChild(dleLi);
    ul.appendChild(edLi);
    ul.appendChild(saveLi);
    
    // 删除事件
    dleLi.addEventListener("click", () => {
      notes.splice(index, 1);
      saveNotes(notes);
      renderNotes();
    });
    
    // 编辑事件
    edLi.addEventListener("click", () => {
      newLi.disabled = !newLi.disabled;
      notes[index].isDisabled = newLi.disabled;
      saveNotes(notes);
    });
    
    // 保存事件
    saveLi.addEventListener("click", () => {
      newLi.disabled = true;
      notes[index].isDisabled = true;
      notes[index].content = newLi.value;
      saveNotes(notes);
    });
  });
}

// 页面加载渲染笔记
document.addEventListener('DOMContentLoaded', renderNotes);

// 添加笔记事件
var input = document.querySelector('#text-input');
document.querySelector("#ad-note-btn").addEventListener("click", () => {
  if (input.value.trim().length > 1) {
    const notes = getNotes();
    notes.push({
      content: input.value.trim(),
      isDisabled: true
    });
    saveNotes(notes);
    renderNotes();
    input.value = "";
  } else {
    alert("请输入至少2个字符的内容哦!");
  }
});

// 清空输入框事件
document.querySelector("#clear-btn").addEventListener("click", () => {
  input.value = "";
});

这样改造后,你的笔记就能在刷新页面后保留下来了!每次添加、删除、编辑、保存笔记,都会同步更新Local Storage里的数据,页面加载时再把数据读出来重新渲染。

内容的提问来源于stack exchange,提问作者daniel asakpa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 12:37:42