如何避免重复复制粘贴JavaScript阅读状态管理相关函数?
动态实现阅读状态标记(告别重复代码)
问题分析
你完全不用写100个重复函数,通过通用化函数+数据属性就能动态处理任意数量的短篇故事,彻底解决代码冗余问题。
先回顾你当前的重复代码:
原JavaScript代码
function readunread() { // Short Story 1 currentvalue = document.getElementById("readunread").value; if (currentvalue == "Mark as Unread") { document.getElementById("readunread").value = "Mark as Read"; document.getElementsByClassName("read").value = "White"; localStorage.setItem("readunread", "Mark as Read"); localStorage.setItem("read", "White"); } else { document.getElementById("readunread").value = "Mark as Unread"; document.getElementsByClassName("read").value = "Gray"; localStorage.setItem("readunread", "Mark as Unread"); localStorage.setItem("read", "Gray"); } } function readunread2() { // Short Story 2 currentvalue2 = document.getElementById("readunread2").value; if (currentvalue2 == "Mark as Unread") { document.getElementById("readunread2").value = "Mark as Read"; document.getElementsByClassName("read2").value = "White"; localStorage.setItem("readunread2", "Mark as Read"); localStorage.setItem("read2", "White"); } else { document.getElementById("readunread2").value = "Mark as Unread"; document.getElementsByClassName("read2").value = "Gray"; localStorage.setItem("readunread2", "Mark as Unread"); localStorage.setItem("read2", "Gray"); } } function readunread3() { // Short Story 3 currentvalue3 = document.getElementById("readunread3").value; if (currentvalue3 == "Mark as Unread") { document.getElementById("readunread3").value = "Mark as Read"; document.getElementsByClassName("read3").value = "White"; localStorage.setItem("readunread3", "Mark as Read"); localStorage.setItem("read3", "White"); } else { document.getElementById("readunread3").value = "Mark as Unread"; document.getElementsByClassName("read3").value = "Gray"; localStorage.setItem("readunread3", "Mark as Unread"); localStorage.setItem("read3", "Gray"); } } function loadInitialValue() { // Short Story 1 const localValue = localStorage.getItem("readunread"); console.log(localValue); if (localValue == "Mark as Unread") { document.getElementById("readunread").value = "Mark as Unread"; } else { document.getElementById("readunread").value = "Mark as Read"; } } function loadInitialValue2() { // Short Story 2 const localValue2 = localStorage.getItem("readunread2"); console.log(localValue2); if (localValue2 == "Mark as Unread") { document.getElementById("readunread2").value = "Mark as Unread"; } else { document.getElementById("readunread2").value = "Mark as Read"; } } function loadInitialValue3() { // Short Story 3 const localValue3 = localStorage.getItem("readunread3"); console.log(localValue3); if (localValue3 == "Mark as Unread") { document.getElementById("readunread3").value = "Mark as Unread"; } else { document.getElementById("readunread3").value = "Mark as Read"; } } function loadFontColor() { const localValue = localStorage.getItem("read"); const localValue2 = localStorage.getItem("read2"); const localValue3 = localStorage.getItem("read3"); const fontColor = document.getElementsByClassName("read"); const fontColor2 = document.getElementsByClassName("read2"); const fontColor3 = document.getElementsByClassName("read3"); console.log(localValue); console.log(localValue2); console.log(localValue3); if (localValue == "Gray") { // Short Story 1 document.getElementsByClassName("read").value = "Gray"; fontColor[0].style.color = "gray"; } else { document.getElementsByClassName("read").value = "White"; fontColor[0].style.color = ""; } if (localValue2 == "Gray") { // Short Story 2 document.getElementsByClassName("read2").value = "Gray"; fontColor2[0].style.color = "gray"; } else { document.getElementsByClassName("read2").value = "White"; fontColor2[0].style.color = ""; } if (localValue3 == "Gray") { // Short Story 3 document.getElementsByClassName("read3").value = "Gray"; fontColor3[0].style.color = "gray"; } else { document.getElementsByClassName("read3").value = "White"; fontColor3[0].style.color = ""; } }
原CSS代码
body { background:black; } .button { border: none; color: white; font-family: Corbel; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; background-color: black; } input[type=button] { font-size: 20px; font-family: Corbel; text-decoration: none; color: white; border: none; background: none; cursor: pointer; margin: 0; padding: 0; } .shortstories { font-family: Corbel; font-size: 25px; }
原HTML代码
<input type = "button" value = "Mark as Read" id = "readunread" onclick = "readunread();"> <input type = "button" value = "Mark as Read" id = "readunread2" onclick = "readunread2();"> <input type = "button" value = "Mark as Read" id = "readunread3" onclick = "readunread3();"> <script> loadInitialValue(); </script> <script> loadInitialValue2(); </script> <script> loadInitialValue3(); </script> <div class = "shortstories"> <table cellspacing = "50" cellpadding = "5" border-collapse = "collapse", border = "0", style = "text-align: justify;"> <tr> <td class = "read"><p><a href = "shortstory1.html"> Short Story 1 </a></p></td> <td class = "read2"><p><a href = "shortstory2.html"> Short Story 2 </a></p></td> <td class = "read3"><p><a href = "shortstory3.html"> Short Story 3 </a></p></td> </tr> </table> </div> <script> loadFontColor(); </script>
优化方案:动态实现,无需重复代码
1. 重构HTML结构,用统一类名+数据属性关联元素
给所有按钮加统一类名read-toggle-btn,用data-story-id标记对应故事的唯一ID;给所有故事标题的td加统一类名story-title,同样用data-story-id绑定对应按钮:
<!-- 按钮部分 --> <input type="button" value="Mark as Read" class="read-toggle-btn" data-story-id="story1"> <input type="button" value="Mark as Read" class="read-toggle-btn" data-story-id="story2"> <input type="button" value="Mark as Read" class="read-toggle-btn" data-story-id="story3"> <div class="shortstories"> <table cellspacing="50" cellpadding="5" border-collapse="collapse" border="0" style="text-align: justify;"> <tr> <td class="story-title" data-story-id="story1"><p><a href="shortstory1.html"> Short Story 1 </a></p></td> <td class="story-title" data-story-id="story2"><p><a href="shortstory2.html"> Short Story 2 </a></p></td> <td class="story-title" data-story-id="story3"><p><a href="shortstory3.html"> Short Story 3 </a></p></td> </tr> </table> </div> <script> // 初始化所有故事状态 initAllStoryStates(); </script>
2. 编写通用JavaScript函数
只需要两个核心函数,不管多少个故事都不用改代码:
// 切换单个故事的阅读状态 function toggleReadState(btn) { const storyId = btn.dataset.storyId; const currentValue = btn.value; // 找到对应标题元素 const titleElement = document.querySelector(`.story-title[data-story-id="${storyId}"]`); if (currentValue === "Mark as Unread") { // 切换为已读状态 btn.value = "Mark as Read"; titleElement.style.color = ""; localStorage.setItem(`readunread-${storyId}`, "Mark as Read"); localStorage.setItem(`read-${storyId}`, "White"); } else { // 切换为未读状态 btn.value = "Mark as Unread"; titleElement.style.color = "gray"; localStorage.setItem(`readunread-${storyId}`, "Mark as Unread"); localStorage.setItem(`read-${storyId}`, "Gray"); } } // 初始化所有故事的状态(读取本地存储+绑定事件) function initAllStoryStates() { const toggleButtons = document.querySelectorAll(".read-toggle-btn"); toggleButtons.forEach(btn => { const storyId = btn.dataset.storyId; // 读取按钮状态,默认已读 const savedBtnState = localStorage.getItem(`readunread-${storyId}`) || "Mark as Read"; btn.value = savedBtnState; // 读取标题颜色状态,默认白色 const savedColorState = localStorage.getItem(`read-${storyId}`) || "White"; const titleElement = document.querySelector(`.story-title[data-story-id="${storyId}"]`); titleElement.style.color = savedColorState === "Gray" ? "gray" : ""; // 绑定点击事件 btn.addEventListener("click", () => toggleReadState(btn)); }); }
3. 保留原有CSS(仅补全缺失的闭合括号)
body { background:black; } .button { border: none; color: white; font-family: Corbel; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; background-color: black; } input[type=button] { font-size: 20px; font-family: Corbel; text-decoration: none; color: white; border: none; background: none; cursor: pointer; margin: 0; padding: 0; } .shortstories { font-family: Corbel; font-size: 25px; }
优化优势
- 新增成本为0:加新故事时,只需要在HTML里添加按钮(带
read-toggle-btn类和唯一data-story-id)和对应story-title类的td,完全不用改JS。 - 存储更规范:本地存储键名用
readunread-${storyId}格式,避免冲突,方便管理。 - 代码更简洁:去掉HTML里的
onclick属性,用动态事件绑定,结构更清晰。
内容的提问来源于stack exchange,提问作者ROOK
相关产品推荐
相关产品推荐

