0

0

实现按月周组合持久化保存与加载日程列表数据的完整方案

花韻仙語

花韻仙語

发布时间:2026-03-06 14:11:12

|

357人浏览过

|

来源于php中文网

原创

实现按月周组合持久化保存与加载日程列表数据的完整方案

本文详解如何在基于月/周选择器的动态日程界面中,正确使用 localStorage 实现“按月-周-日三级键名”精准存取 列表数据,避免误清历史记录,并确保切换选项后自动加载对应数据。

本文详解如何在基于月/周选择器的动态日程界面中,正确使用 localstorage 实现“按月-周-日三级键名”精准存取 `

  • ` 列表数据,避免误清历史记录,并确保切换选项后自动加载对应数据。

    在构建可持久化的周/月计划表(如教学安排、任务看板)时,一个常见痛点是:用户输入的

  • 条目在切换月份或周次后全部丢失——表面看是“清空了”,实则是未建立上下文感知的数据隔离机制。核心问题在于:原始代码中 saveData() 和 loadData() 使用了动态生成的键(如 "January - Week 1 - 1"),但缺乏配套的条件化清除逻辑时机可控的数据加载流程,导致每次切换都触发全局清空,而加载又未在正确时机执行。

    ✅ 正确的数据隔离策略:三级键名 + 精准清除

    应采用 month-week-dayIndex 作为唯一存储键(例如 "January-Week 1-1"),确保不同日期组合的数据完全独立。关键在于:清除操作不应清空整个 DOM 或所有 localStorage 数据,而应仅重置当前选中月周范围内的

      内容

    为此,需重构 clearData() 函数,使其:

    • 读取当前选中的 month 和 week;
    • 构造前缀 keyPrefix = "${month}-${week}";
    • 遍历所有 .day 元素,为每个
        设置或校验 data-key 属性(如 "January-Week 1-1");
    • 仅清空 data-key 匹配当前前缀的
        ,而非无差别清空所有列表。

      以下是优化后的 clearData() 实现:

      通义灵码
      通义灵码

      阿里云出品的一款基于通义大模型的智能编码辅助工具,提供代码智能生成、研发智能问答能力

      下载
      const clearData = () => {
        const month = document.getElementById('select-month').value;
        const week = document.getElementById('select-week').value;
        const keyPrefix = `${month}-${week}`;
      
        document.querySelectorAll('.day').forEach(dayElement => {
          const dayIndex = dayElement.getAttribute('data-day');
          const key = `${keyPrefix}-${dayIndex}`;
          const ul = dayElement.querySelector('ul');
      
          // 为 ul 绑定当前上下文键,便于后续精准识别
          ul.setAttribute('data-key', key);
          ul.innerHTML = ''; // 清空本日列表,但保留键标识
        });
      
        saveData(); // 立即保存空状态,确保 localStorage 同步
      };

      ⚠️ 注意:原答案中 if (ul.getAttribute('data-key') === key) 的判断逻辑易因初始化缺失导致失效;改为统一设置 data-key 并直接清空更健壮,且避免首次加载时键不匹配的问题。

      ✅ 可靠的数据加载时机:清除 → 更新标题 → 加载

      loadData() 必须在 DOM 结构就绪、data-key 已写入且

        为空后执行,否则将找不到目标容器或重复追加。因此,应在月/周下拉框的 change 事件中严格遵循三步顺序:
        const selectMonth = document.getElementById('select-month');
        const selectWeek = document.getElementById('select-week');
        
        selectMonth.addEventListener('change', () => {
          clearData();
          updateDayTitles(); // 重新渲染周一至周日标题(如 "Jan 1", "Jan 2")
          loadData();        // ✅ 此时 ul 已有 data-key,且为空,可安全注入历史 li
        });
        
        selectWeek.addEventListener('change', () => {
          clearData();
          updateDayTitles();
          loadData();
        });

        ✅ 增强版 loadData():防御性解析与 DOM 安全插入

        原始 loadData() 存在潜在风险:若 savedData[key] 为 undefined 或非数组,values.forEach 将报错;且直接 innerHTML = value 可能引入 XSS 风险。推荐改写为:

        const loadData = () => {
          const savedData = JSON.parse(localStorage.getItem('scheduleData')) || {};
          const month = document.getElementById('select-month').value;
          const week = document.getElementById('select-week').value;
        
          document.querySelectorAll('.day').forEach(dayElement => {
            const dayIndex = dayElement.getAttribute('data-day');
            const key = `${month}-${week}-${dayIndex}`;
            const values = Array.isArray(savedData[key]) ? savedData[key] : [];
        
            const ul = dayElement.querySelector('ul');
            ul.innerHTML = ''; // 确保干净起始状态
        
            values.forEach(text => {
              const li = document.createElement('li');
              li.textContent = text; // ✅ 使用 textContent 防 XSS
        
              // 添加删除按钮(×)
              const span = document.createElement('span');
              span.textContent = '×';
              span.className = 'delete-btn';
              span.addEventListener('click', () => {
                li.remove();
                saveData();
                checkScroll();
              });
        
              // 添加勾选交互
              li.addEventListener('click', () => li.classList.toggle('checked'));
        
              li.appendChild(span);
              ul.appendChild(li);
            });
          });
        };

        ✅ 最终验证要点

        检查项 说明
        ✅ localStorage 键结构 打开浏览器开发者工具 → Application → Local Storage,确认键名为 scheduleData,值为形如 {"January-Week 1-1": ["Hello"], "February-Week 3-2": ["Review"]} 的对象
        ✅ 切换不丢失 从 "January-Week 1" 输入 "Hello" → 切到 "February-Week 2" → 返回 "January-Week 1","Hello" 应完好重现
        ✅ 新增即保存 每次点击 + 按钮添加
      • 后,立即调用 saveData()(建议在添加逻辑末尾显式调用)
      • ✅ 样式与交互 .checked 类、删除按钮点击效果、滚动检测 checkScroll() 均正常工作

        通过以上结构化改造,你将获得一个真正「会记忆」的日程组件:它理解月、周、日的层级关系,只在必要时清除局部状态,并在每次视图就绪后精准还原用户的历史输入——这才是专业级前端持久化体验的核心所在。

    • 本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

      热门AI工具

      更多
      DeepSeek
      DeepSeek

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

      豆包大模型
      豆包大模型

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

      通义千问
      通义千问

      阿里巴巴推出的全能AI助手

      腾讯元宝
      腾讯元宝

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

      文心一言
      文心一言

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

      讯飞写作
      讯飞写作

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

      即梦AI
      即梦AI

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

      ChatGPT
      ChatGPT

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

      相关专题

      更多
      if什么意思
      if什么意思

      if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

      841

      2023.08.22

      php中foreach用法
      php中foreach用法

      本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

      204

      2025.12.04

      undefined是什么
      undefined是什么

      undefined是代表一个值或变量不存在或未定义的状态。它可以作为默认值来判断一个变量是否已经被赋值,也可以用于设置默认参数值。尽管在不同的编程语言中,undefined可能具有不同的含义和用法,但理解undefined的概念可以帮助我们更好地理解和编写程序。本专题为大家提供undefined相关的各种文章、以及下载和课程。

      6137

      2023.07.31

      网页undefined是什么意思
      网页undefined是什么意思

      网页undefined是指页面出现了未知错误的意思,提示undefined一般是在开发网站的时候定义不正确或是转换不正确,或是找不到定义才会提示undefined未定义这个错误。想了解更多的相关内容,可以阅读本专题下面的文章。

      3306

      2024.08.14

      网页undefined啥意思
      网页undefined啥意思

      本专题整合了undefined相关内容,阅读下面的文章了解更多详细内容。后续继续更新。

      1569

      2025.12.25

      DOM是什么意思
      DOM是什么意思

      dom的英文全称是documentobjectmodel,表示文件对象模型,是w3c组织推荐的处理可扩展置标语言的标准编程接口;dom是html文档的内存中对象表示,它提供了使用javascript与网页交互的方式。想了解更多的相关内容,可以阅读本专题下面的文章。

      4212

      2024.08.14

      DOM是什么意思
      DOM是什么意思

      dom的英文全称是documentobjectmodel,表示文件对象模型,是w3c组织推荐的处理可扩展置标语言的标准编程接口;dom是html文档的内存中对象表示,它提供了使用javascript与网页交互的方式。想了解更多的相关内容,可以阅读本专题下面的文章。

      4212

      2024.08.14

      li是什么元素
      li是什么元素

      li是HTML标记语言中的一个元素,用于创建列表。li代表列表项,它是ul或ol的子元素,li标签的作用是定义列表中的每个项目。本专题为大家li元素相关的各种文章、以及下载和课程。

      436

      2023.08.03

      Rust内存安全机制与所有权模型深度实践
      Rust内存安全机制与所有权模型深度实践

      本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

      19

      2026.03.05

      热门下载

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

      精品课程

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

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