本文介绍一种高效、健壮的方式,遍历当前周对应的 localStorage 键值对,按工作日分组识别内容相同的输入框,并统一添加 double-input 或 no-double-input CSS 类,实现跨输入框的重复内容高亮逻辑。
本文介绍一种高效、健壮的方式,遍历当前周对应的 localstorage 键值对,按工作日分组识别内容相同的输入框,并统一添加 `double-input` 或 `no-double-input` css 类,实现跨输入框的重复内容高亮逻辑。
在构建周计划表格(如周一至周五课表/排班表)时,常需校验同一工作日内多个输入框是否填写了相同内容——例如“会议”、“休假”等重复值。为提升用户体验,我们希望自动为这些重复项添加视觉标识(如红色边框或背景色),而将唯一值标记为“安全状态”。该需求的核心在于:从 localStorage 中提取结构化数据、按语义(工作日 + 值)聚类、批量更新 DOM 元素样式类。
以下是一个完整、可直接集成的解决方案:
function getAnyDoubleInput() {
// 1. 确定当前周编号(支持 localStorage 持久化或回退到 moment.js 动态计算)
const week = localStorage.getItem('currentWeek') || moment().isoWeek();
// 2. 筛选出属于本周的所有 localStorage 键(格式如 '40_tdMontag1')
const weekKeys = Object.keys(localStorage)
.filter(key => key.startsWith(`${week}_`)); // 注意:原示例中键含下划线,应严格匹配 '_'
// 3. 构建映射:input ID → 所有对应存储值(实际每 ID 只存一个值,但保留数组结构便于扩展)
const inputs = {};
weekKeys.forEach(key => {
const id = key.split('_').pop(); // 更健壮地提取 ID(如 'tdMontag1'),避免 indexOf 不稳定
const value = localStorage.getItem(key);
if (!inputs[id]) inputs[id] = [];
inputs[id].push(value);
});
// 4. 定义工作日列表(与 HTML ID 命名约定一致)
const weekDays = ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag'];
// 5. 对每一天独立处理:找出当日所有 ID,再比对值是否重复
weekDays.forEach(day => {
// 获取当日所有 input ID(如 tdMontag1, tdMontag2)
const dayIds = Object.keys(inputs).filter(id => id.includes(day));
// 收集当日所有「值 → 对应 ID 列表」的映射,用于高效查重
const valueToIds = new Map();
dayIds.forEach(id => {
const value = inputs[id][0] || ''; // 取首个值(localStorage 单值存储)
if (!valueToIds.has(value)) valueToIds.set(value, []);
valueToIds.get(value).push(id);
});
// 标记逻辑:值出现次数 ≥ 2 → 所有对应 ID 添加 double-input;否则 no-double-input
dayIds.forEach(id => {
const element = document.getElementById(id);
if (!element) return; // 安全防护:ID 不存在则跳过
const value = inputs[id][0] || '';
const idsForValue = valueToIds.get(value) || [];
if (idsForValue.length >= 2) {
element.classList.add('double-input');
element.classList.remove('no-double-input');
} else {
element.classList.add('no-double-input');
element.classList.remove('double-input');
}
});
});
}
✅ 关键优化说明:
- 使用 key.split('_').pop() 替代 substring(indexOf('_') + 1),避免因键名含多个 _ 导致截取错误;
- 引入 Map 实现 O(1) 值聚合,替代嵌套循环(原方案时间复杂度 O(n²),新方案为 O(n));
- 显式检查 document.getElementById(id) 是否存在,防止控制台报错中断执行;
- 严格匹配 startsWith(${week}_),确保只处理本周数据,避免跨周污染;
- double-input / no-double-input 类互斥管理,避免样式残留。
⚠️ 注意事项:
- 确保页面加载完成后调用该函数(如放在 DOMContentLoaded 或 window.onload 中);
- 若 localStorage 值为空字符串或 null,建议在比较前做标准化处理(如 String(value).trim());
- 如需实时响应输入变化,可结合 input 事件节流触发此函数,或使用 StorageEvent 监听跨标签页同步。
通过该方案,你不仅能精准识别重复内容,还能以声明式、低耦合的方式维护 UI 状态,为后续扩展(如提示气泡、冲突弹窗)奠定坚实基础。











