0

0

如何使用 localStorage 实现动态生成 HTML 元素的页面刷新持久化

碧海醫心

碧海醫心

发布时间:2025-09-25 14:03:18

|

532人浏览过

|

来源于php中文网

原创

如何使用 localstorage 实现动态生成 html 元素的页面刷新持久化

本文详细介绍了如何利用 JavaScript 的 localStorage API 解决动态生成 HTML 元素在页面刷新后消失的问题。通过在用户提交表单时将数据存储到 localStorage,并在页面加载时从 localStorage 中检索并重新渲染这些数据,可以确保用户创建的内容在浏览器会话之间持久存在,极大地提升了用户体验。

前端开发中,我们经常会遇到需要动态创建 HTML 元素来展示用户输入或应用程序状态的场景。然而,这些通过 JavaScript 动态添加到 DOM(文档对象模型)的元素,在用户刷新页面时会随之消失,因为浏览器会重新加载 HTML、CSS 和 JavaScript 文件,并重置整个 DOM 结构。为了解决这一问题,我们可以利用客户端存储机制,如 localStorage,来持久化这些动态生成的数据。

1. 理解问题:动态内容的短暂性

当使用 JavaScript 的 document.createElement() 和 appendChild() 等方法创建并插入元素时,这些操作只影响当前会话的 DOM。一旦页面被重新加载、关闭或导航到其他页面,浏览器会丢弃当前的 DOM 状态,并从服务器重新获取页面内容。因此,所有动态添加的元素都会丢失。

例如,一个表单提交后生成表格行的应用,在不进行数据持久化处理的情况下,刷新页面后表格将变为空白。

<!-- 原始 HTML 结构示例 -->
<div id="party">
  <h1>发布信息</h1>
  <div>
    <label for="nom">派对名称:</label>
    <input type="text" id="nom" name="nom" placeholder="派对名称" required>
  </div>
  <!-- 其他表单字段省略 -->
  <button type="button">发布</button>
</div>
<!-- 动态生成的表格将添加到这里或 body 底部 -->
// 原始 JavaScript 示例 (简化)
let button = document.querySelector('button[type="button"]');
button.addEventListener("click", () => {
  let nom = document.getElementById("nom").value;
  // ... 获取其他表单数据
  if (nom !== "") {
    let table = document.createElement('table');
    document.querySelector('body').appendChild(table);
    // ... 创建表头和数据行
    alert("表单已提交!");
  }
});

上述代码能正常工作,但刷新页面后,动态生成的 <table> 及其内容将不复存在。

立即学习前端免费学习笔记(深入)”;

2. 解决方案:使用 localStorage 进行数据持久化

localStorage 是浏览器提供的一种客户端存储机制,允许网页在用户的浏览器中存储键值对数据。这些数据没有过期时间,即使浏览器关闭再打开,数据依然存在,直到被显式清除。这使得它非常适合存储需要在页面刷新后保持不变的用户数据或应用程序状态。

2.1 localStorage 的基本操作

  • 存储数据: localStorage.setItem(key, value)
    • key: 字符串,数据的名称。
    • value: 字符串,要存储的数据。非字符串数据会被自动转换为字符串。
  • 获取数据: localStorage.getItem(key)
    • 返回与 key 关联的字符串值。如果 key 不存在,则返回 null。
  • 移除数据: localStorage.removeItem(key)
    • 移除与 key 关联的数据。
  • 清除所有数据: localStorage.clear()
    • 清除当前域名下的所有 localStorage 数据。

2.2 实现持久化动态生成表格的步骤

要实现动态生成表格的持久化,我们需要在两个关键时刻进行操作:

  1. 数据提交时: 当用户点击“发布”按钮提交表单并生成新的表格行时,将新的行数据存储到 localStorage 中。
  2. 页面加载时: 当页面首次加载或刷新时,检查 localStorage 中是否有之前存储的数据,如果有,则读取这些数据并重新构建表格。

3. 完整实现示例

下面是一个结合 localStorage 实现动态表格持久化的完整代码示例。

小微助手
小微助手

微信推出的一款专注于提升桌面效率的助手型AI工具

下载

3.1 HTML 结构

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>动态表格持久化示例</title>
  <style>
    body { font-family: Arial, sans-serif; margin: 20px; }
    #party div { margin-bottom: 10px; }
    label { display: inline-block; width: 150px; }
    input { padding: 5px; width: 200px; }
    button { padding: 8px 15px; background-color: #007bff; color: white; border: none; cursor: pointer; }
    button:hover { background-color: #0056b3; }
    table { width: 100%; border-collapse: collapse; margin-top: 20px; }
    th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
    th { background-color: #f2f2f2; }
  </style>
</head>
<body>

  <div id="party">
    <h1>发布派对信息</h1>
    <div>
      <label for="nom">派对名称:</label>
      <input type="text" id="nom" name="nom" placeholder="例如:夏日泳池派对" required>
    </div>
    <div>
      <label for="adresse">派对地址:</label>
      <input type="text" id="adresse" name="adresse" placeholder="例如:海滨大道123号" required>
    </div>
    <div>
      <label for="capacite">容纳人数:</label>
      <input type="text" id="capacite" name="capacite" placeholder="例如:50" required>
    </div>
    <div>
      <label for="phone">联系电话 (选填):</label>
      <input type="text" id="phone" name="phone" placeholder="例如:138XXXXXXXX">
    </div>
    <div>
      <label for="heure1">开始时间:</label>
      <input type="text" id="heure1" name="heure1" placeholder="例如:10:00" required>
    </div>
    <div>
      <label for="heure2">结束时间:</label>
      <input type="text" id="heure2" name="heure2" placeholder="例如:20:00" required>
    </div>
    <button type="button" id="publishButton">发布</button>
  </div>

  <div id="table-container">
    <!-- 动态生成的表格将插入到这里 -->
  </div>

  <script src="script.js"></script>
  <!-- 如果使用 jQuery,需要引入 jQuery 库 -->
  <!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> -->
</body>
</html>

3.2 JavaScript 代码 (script.js)

// 定义 localStorage 的键名,用于存储表格数据
const STORAGE_KEY = "pool_party_data_v1";

// 获取发布按钮
let publishButton = document.getElementById('publishButton');
// 获取表格容器
let tableContainer = document.getElementById('table-container');

/**
 * 创建或获取表格元素,并确保表头存在。
 * @param {boolean} isFirstTime 是否是首次创建表格(例如页面加载时)。
 * @returns {HTMLTableElement} 表格元素。
 */
function ensureTableStructure(isFirstTime) {
  let table = document.querySelector('table'); // 尝试获取现有表格

  if (!table) { // 如果表格不存在,则创建新表格
    table = document.createElement('table');
    tableContainer.appendChild(table); // 将表格添加到指定容器

    // 创建表头
    let headerRow = document.createElement('tr');
    const headers = [
      "派对名称", "开始时间", "结束时间", "地址", "容纳人数", "联系电话"
    ];
    headers.forEach(text => {
      let th = document.createElement('th');
      th.innerHTML = text;
      headerRow.appendChild(th);
    });
    table.appendChild(headerRow);
  }
  return table;
}

/**
 * 从 localStorage 加载并渲染表格数据。
 */
function loadAndRenderTableData() {
  const storedData = localStorage.getItem(STORAGE_KEY);
  if (storedData) {
    let table = ensureTableStructure(true); // 确保表格和表头存在

    // 使用 '¬' 分隔符拆分存储的行数据
    const rowsHtml = storedData.split('¬');

    rowsHtml.forEach(rowHtml => {
      if (rowHtml.trim() !== '') { // 避免添加空行
        let newRow = document.createElement('tr');
        newRow.innerHTML = rowHtml; // 直接将存储的 HTML 字符串设置为行内容
        table.appendChild(newRow);
      }
    });
  }
}

// 页面加载时执行
document.addEventListener('DOMContentLoaded', () => {
  loadAndRenderTableData(); // 加载并渲染之前保存的表格数据
});


// 监听发布按钮的点击事件
publishButton.addEventListener("click", (event) => {
  event.preventDefault(); // 阻止表单默认提交行为,如果按钮在 form 内部

  // 获取表单数据
  let nom = document.getElementById("nom").value.trim();
  let adresse = document.getElementById("adresse").value.trim();
  let capacite = document.getElementById("capacite").value.trim();
  let phone = document.getElementById("phone").value.trim();
  let heure1 = document.getElementById("heure1").value.trim();
  let heure2 = document.getElementById("heure2").value.trim();

  // 验证必填字段
  if (nom === "" || adresse === "" || capacite === "" || heure1 === "" || heure2 === "") {
    alert("请填写所有必填信息!");
    return;
  }

  // 确保表格结构存在
  let table = ensureTableStructure(false);

  // 创建新的数据行
  let newRow = document.createElement('tr');
  const rowData = [nom, heure1, heure2, adresse, capacite, phone];

  rowData.forEach(data => {
    let td = document.createElement('td');
    td.innerHTML = data;
    newRow.appendChild(td);
  });

  // 将新行添加到表格
  table.appendChild(newRow);

  // 将新行的 innerHTML 存储到 localStorage
  let currentStoredRows = localStorage.getItem(STORAGE_KEY) || '';
  // 使用特殊字符 '¬' 作为分隔符,避免与 HTML 内容冲突
  let updatedStoredRows = currentStoredRows + '¬' + newRow.innerHTML;
  localStorage.setItem(STORAGE_KEY, updatedStoredRows);

  alert("表单已提交并保存!");

  // 清空表单字段以便下次输入
  document.getElementById("nom").value = '';
  document.getElementById("adresse").value = '';
  document.getElementById("capacite").value = '';
  document.getElementById("phone").value = '';
  document.getElementById("heure1").value = '';
  document.getElementById("heure2").value = '';
});

// 可选:添加一个清除 localStorage 的按钮,用于测试或重置
// let clearButton = document.createElement('button');
// clearButton.textContent = '清除所有数据';
// clearButton.addEventListener('click', () => {
//   localStorage.removeItem(STORAGE_KEY);
//   tableContainer.innerHTML = ''; // 清空表格显示
//   alert('所有数据已清除!');
// });
// document.body.appendChild(clearButton);

4. 代码解析与注意事项

4.1 ensureTableStructure 函数

这个函数负责检查页面上是否存在表格。如果不存在,它会创建一个新的 <table> 元素并添加表头 (<th>)。这保证了无论是在页面加载时恢复数据,还是在用户首次提交数据时,表格结构都能正确地被创建。

4.2 loadAndRenderTableData 函数

在 DOMContentLoaded 事件(即页面 DOM 完全加载后)中调用此函数。它会:

  1. 从 localStorage 中获取存储的字符串。
  2. 如果存在数据,则调用 ensureTableStructure 来确保表格和表头已准备好。
  3. 使用自定义分隔符 '¬' 将存储的字符串拆分成单个表格行的 HTML 内容。
  4. 遍历这些 HTML 片段,为每个片段创建一个新的 <tr> 元素,并将其 innerHTML 设置为存储的片段,然后添加到表格中。

4.3 publishButton 事件监听器

当用户点击“发布”按钮时:

  1. event.preventDefault():阻止按钮的默认行为(例如,如果按钮在一个 <form> 标签内,它可能会导致页面刷新)。
  2. 获取所有表单字段的值。
  3. 进行基本的输入验证。
  4. 调用 ensureTableStructure 确保表格存在。
  5. 创建一个新的 <tr> 元素,并用表单数据填充 <td> 元素。
  6. 将新行添加到 DOM 中的表格。
  7. 持久化操作:
    • 获取 localStorage 中当前存储的所有行数据。如果为空,则初始化为空字符串。
    • 将新行的 innerHTML 附加到现有数据中,并使用 '¬' 作为分隔符。这个分隔符的选择很重要,它应该是一个不太可能出现在实际 HTML 内容中的字符,以避免解析错误。
    • 将更新后的字符串重新存回 localStorage。
  8. 清空表单字段,方便用户继续输入。

4.4 数据序列化与反序列化

在这个例子中,我们直接存储了 <tr> 元素的 innerHTML。这对于简单的表格行来说是有效的。对于更复杂的数据结构(例如包含事件监听器或复杂对象),建议使用 JSON.stringify() 将 JavaScript 对象转换为 JSON 字符串进行存储,并在读取时使用 JSON.parse() 转换回对象。

// 存储对象示例
const partyData = {
  nom: nom,
  adresse: adresse,
  capacite: capacite,
  phone: phone,
  heure1: heure1,
  heure2: heure2
};
let allParties = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]');
allParties.push(partyData);
localStorage.setItem(STORAGE_KEY, JSON.stringify(allParties));

// 读取对象示例
const storedParties = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]');
storedParties.forEach(party => {
  // 根据 party 对象的内容重新构建表格行
});

使用 JSON 存储数据,可以更灵活地处理数据,例如编辑或删除特定行。

4.5 localStorage 的局限性

  • 存储容量: 大多数浏览器对 localStorage 的存储容量有限制,通常为 5MB 到 10MB。不适合存储大量数据。
  • 同步操作: localStorage 的操作是同步的,这意味着在读写数据时会阻塞主线程。频繁或大量操作可能导致页面卡顿。
  • 安全性: localStorage 中的数据没有加密,容易受到跨站脚本 (XSS) 攻击。不应存储敏感信息。
  • 仅限字符串: localStorage 只能存储字符串。存储 JavaScript 对象时需要进行序列化(如 JSON.stringify())。

5. 总结

通过 localStorage,我们可以轻松实现前端动态生成内容的持久化,确保用户数据在页面刷新后不会丢失,从而显著提升用户体验。在设计持久化方案时,应根据数据的复杂度和数量选择合适的存储策略,并注意 localStorage 的容量和安全限制。对于更复杂或大量的数据存储需求,可以考虑使用 IndexedDB 或将数据发送到后端服务器进行持久化。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

457

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

549

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

337

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

82

2025.09.10

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

254

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1111

2024.03.01

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

761

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

49

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.9万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

CSS教程
CSS教程

共754课时 | 43.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号