You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

页面刷新后LocalStorage出现空字符串标签的问题求助

页面刷新后LocalStorage出现空字符串标签的问题求助

Hey Farshad,我仔细扒了你的代码,找到了空字符串标签冒出来的几个关键原因,咱们一步步把问题解决掉:

问题根源拆解

  1. 逗号分割的漏洞:当输入内容以逗号结尾(比如tag1,),或者直接敲逗号按回车,split(',')会生成包含空字符串的数组,被直接塞进了tags数组里。
  2. 页面加载的逻辑错误:从LocalStorage读数据后你调用了generateTag(),但这个函数会默认处理当前输入框的空值,导致空字符串被再次添加到数组。
  3. indexOf用错了:removeTag里写的tags.indexOf(tag => tag === tagValue)是无效的——indexOf不支持回调函数,会直接返回-1,导致splice(-1,1)错误删除最后一个标签。
  4. 判断逻辑不全面:原代码只在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.20 09:43:13