页面刷新后LocalStorage出现空字符串标签的问题求助
页面刷新后LocalStorage出现空字符串标签的问题求助
Hey Farshad,我仔细扒了你的代码,找到了空字符串标签冒出来的几个关键原因,咱们一步步把问题解决掉:
问题根源拆解
- 逗号分割的漏洞:当输入内容以逗号结尾(比如
tag1,),或者直接敲逗号按回车,split(',')会生成包含空字符串的数组,被直接塞进了tags数组里。 - 页面加载的逻辑错误:从LocalStorage读数据后你调用了
generateTag(),但这个函数会默认处理当前输入框的空值,导致空字符串被再次添加到数组。 indexOf用错了:removeTag里写的tags.indexOf(tag => tag === tagValue)是无效的——indexOf不支持回调函数,会直接返回-1,导致splice(-1,1)错误删除最后一个标签。- 判断逻辑不全面:原代码只在keypress事件里判断单个标签,没处理逗号分割的多个标签的重复、空值情况。
修复步骤及代码调整
1. 单独抽离标签渲染函数
把生成标签DOM的逻辑独立出来,避免和新增标签的逻辑混在一起,减少冗余:
//***********渲染标签到页面************/ function renderTags() { tagListContainer.innerHTML = ''; // 先清空容器 [...tags].reverse().forEach(tag => { const html = `<li>${tag} <i class="uit uit-multiply" onclick="removeTag(this, '${tag}')"></i></li>`; tagListContainer.insertAdjacentHTML("afterbegin", html); }); }
2. 修复generateTag,过滤无效标签
修改逗号分割后的处理逻辑,确保只有非空、不重复且未达数量上限的标签才会被添加:
//***********Generate tag ************/ function generateTag() { let tagTitle = input.value.toLowerCase().trim(); // 处理逗号分割的标签,过滤空值、重复值,同时限制数量 tagTitle.split(',').forEach(tag => { const trimmedTag = tag.trim(); if (trimmedTag && !tags.includes(trimmedTag) && tags.length < 10) { tags.push(trimmedTag); } }); renderTags(); // 使用新的渲染函数 count(); setDataToLocal(); input.value = ''; };
3. 修正页面加载逻辑,避免重复加空值
从LocalStorage读数据后,直接调用renderTags渲染已有标签,不再调用generateTag:
//***********get data from local storage ************/ window.addEventListener('load', () => { let getData = JSON.parse(localStorage.getItem('tags')); if (getData?.length) { tags = getData; renderTags(); count(); // 更新剩余数量显示 } })
4. 修复removeTag的索引错误
把indexOf换成支持回调的findIndex,确保能正确找到要删除的标签:
//***********Remove tags by clicking ************/ function removeTag (tagElem, tagValue) { tagElem.parentElement.remove() let findIndexTag = tags.findIndex(tag => tag === tagValue) // 替换成findIndex tags.splice(findIndexTag, 1) count() setDataToLocal() }
5. 简化keypress事件逻辑
因为generateTag里已经做了全面判断,keypress事件可以简化:
input.addEventListener('keypress', (e) => { if (e.key === 'Enter') { generateTag(); } })
6. 删除冗余的removePreviousTag函数
现在renderTags会自动清空容器,removePreviousTag可以删掉,同时把removeAllBtn里的调用换成renderTags:
//***********Remove all tags ************/ removeAllBtn.addEventListener('click', () => { tags = [] renderTags() // 替换成renderTags count() setDataToLocal() })
修复后的完整JavaScript代码
const input = document.querySelector('input') const removeAllBtn = document.querySelector('.removeAll') const tagListContainer = document.querySelector('.tagListContainer') let counterText = document.querySelector('.details p span') let tags = []; let currentNumber = 10 //***********counter number ************/ function count () { input.focus() counterText.textContent = currentNumber - tags.length } //***********Remove all tags ************/ removeAllBtn.addEventListener('click', () => { tags = [] renderTags() count() setDataToLocal() }) //***********Remove tags by clicking ************/ function removeTag (tagElem, tagValue) { tagElem.parentElement.remove() let findIndexTag = tags.findIndex(tag => tag === tagValue) tags.splice(findIndexTag, 1) count() setDataToLocal() } //***********渲染标签到页面************/ function renderTags() { tagListContainer.innerHTML = ''; [...tags].reverse().forEach(tag => { const html = `<li>${tag} <i class="uit uit-multiply" onclick="removeTag(this, '${tag}')"></i></li>`; tagListContainer.insertAdjacentHTML("afterbegin", html); }); } //***********Generate tag ************/ function generateTag() { let tagTitle = input.value.toLowerCase().trim(); tagTitle.split(',').forEach(tag => { const trimmedTag = tag.trim(); if (trimmedTag && !tags.includes(trimmedTag) && tags.length < 10) { tags.push(trimmedTag); } }); renderTags(); count(); setDataToLocal(); input.value = ''; }; input.addEventListener('keypress', (e) => { if (e.key === 'Enter') { generateTag(); } }) //***********Set data in local storage ************/ function setDataToLocal () { localStorage.setItem('tags', JSON.stringify(tags)) } //***********get data from local storage ************/ window.addEventListener('load', () => { let getData = JSON.parse(localStorage.getItem('tags')); if (getData?.length) { tags = getData; renderTags(); count(); } })
这样修改后,空字符串标签的问题就彻底解决了,同时还优化了标签的添加逻辑,避免重复添加和超出数量限制的问题。
备注:内容来源于stack exchange,提问作者Farshad Bahari
相关产品推荐
相关产品推荐

