天气应用localStorage搜索历史按钮重复及清空后复现问题修复
问题根因说明
重复城市按钮问题
你的去重逻辑存在格式不匹配的bug:saveStorage中判断重复时用的是用户原始输入的字符串,但实际存入数组的是首字母大写的格式化后字符串,二者大小写不一致时includes()无法匹配,会重复添加城市。比如第一次输入beijing存入Beijing,第二次再输入小写的beijing,判断时会认为beijing不在数组中,就会重复插入一条Beijing。
清空localStorage后历史按钮仍渲染问题
核心是状态没有同步清理:
handleClear函数只清空了localStorage和页面上的按钮DOM,没有重置全局变量citiesArr中存储的旧城市数据,内存中的旧数据一直残留。- 页面加载事件中没有做非空判断,只要触发
handleWeather请求成功,就会调用saveStorage把内存中残留的citiesArr重新写回localStorage,同时重新渲染按钮,相当于清空操作白做。 - 初始化时用
eval解析localStorage没有做错误捕获,当localStorage为空时eval(undefined)会抛出异常,导致|| []的兜底空数组逻辑无法正常生效,进一步加剧状态混乱。 - 脚本最顶层无参数直接调用
saveStorage(),页面一加载就会把当前citiesArr的内容写入localStorage,哪怕localStorage已经被清空,也会被内存里的旧值覆盖。
修复位置和具体修改方案
按以下位置调整代码即可解决所有问题:
替换最顶层的初始化逻辑,换掉危险的
eval,做好空值容错,拆分渲染和存储逻辑:
把原来的let citiesArr = eval(localStorage.cities) || []; saveStorage();替换为
let citiesArr = []; // 安全解析本地存储数据 try { const storedCities = localStorage.getItem('cities'); if (storedCities) { citiesArr = JSON.parse(storedCities); if (!Array.isArray(citiesArr)) citiesArr = []; } } catch (e) { citiesArr = []; } // 初始化只渲染历史按钮,不做无意义的存储写入 renderHistoryButtons();抽离独立的历史按钮渲染函数,解耦渲染和存储逻辑,方便多处调用:
在saveStorage函数前新增function renderHistoryButtons() { $('#searchHistory').html(''); citiesArr.forEach(city => { $('#searchHistory').append(`<button class="btn-primary" onclick="handleHistory('${city}')">${city}</button>`) }); }修复
saveStorage的去重逻辑,统一城市名格式后再做存在性判断:
把原来的saveStorage函数替换为function saveStorage(city) { if (city){ // 统一格式化城市名:首字母大写,其余小写,从根源避免大小写导致的去重失效 const formattedCity = city[0].toUpperCase() + city.substr(1).toLowerCase(); if (!citiesArr.includes(formattedCity)) citiesArr.push(formattedCity); } renderHistoryButtons(); localStorage.setItem('cities', JSON.stringify(citiesArr)); };修复
handleClear函数,清空时同步重置内存状态:
把原来的handleClear替换为function handleClear(){ localStorage.removeItem('cities'); citiesArr = []; // 核心:清空内存中存储的旧城市数据 renderHistoryButtons(); // 清空输入框和已展示的天气内容,避免残留状态 $('#city-input').val(''); document.querySelector(".hide").style.display = "none"; $('#icon, #cityDescription, #cityTemp, #cityHumididty, #cityWindSpeed, #cityUVI, #cityName, #currentDate, #forecast').html(''); }修复页面加载事件逻辑,增加非空判断,空历史时不自动调用接口:
把原来的window.load回调替换为$(window).on("load", function () { if (citiesArr.length > 0) { $("#city-input").val(citiesArr[0]); handleWeather(); } })补充输入容错,在
handleWeather开头获取输入值时增加去空格处理,避免用户输入前后空格导致匹配异常:
把let city = document.querySelector('input').value;修改为let city = document.querySelector('input').value.trim();
内容的提问来源于stack exchange,提问作者ChrisWill303
相关产品推荐
相关产品推荐

