如何将下拉菜单选中状态存入localStorage并在刷新后加载
下拉菜单刷新后无法恢复选中状态的解决方案
问题原因
你的代码存在两个核心问题:
- 重复监听
DOMContentLoaded事件,导致恢复选中状态的函数执行时机混乱,且此时异步获取的国家数据可能还未加载完成 - 未处理首次访问时localStorage无数据的情况,直接设置下拉菜单值为
null会导致显示异常
修复代码
替换你的script.js为以下代码,关键修改点已标注:
const darkModeToggle = document.getElementById("darkmode-toggle"); function toggleDarkMode() { const elementBody = document.body; elementBody.classList.toggle("dark-mode"); } darkModeToggle.addEventListener("click", toggleDarkMode); document.addEventListener('DOMContentLoaded', async function () { const countriesContainer = document.getElementById('countries'); const searchInput = document.getElementById('searchCountry'); const regionDropdown = document.getElementById('dropdown-region'); const countriesData = await getCountries(); function renderCountries(countries) { countriesContainer.innerHTML = ''; countries.forEach(country => { const countryCard = document.createElement('div'); countryCard.classList.add('country-card'); const heading = document.createElement('h2'); heading.textContent = country.name.common; const regionParagraph = document.createElement('p'); regionParagraph.textContent = `Region: ${country.region}`; const capitalParagraph = document.createElement('p'); capitalParagraph.textContent = `Capital: ${country.capital}`; const flagImage = document.createElement('img'); flagImage.src = country.flags.png; flagImage.alt = `${country.name.common} flag`; countryCard.appendChild(heading); countryCard.appendChild(regionParagraph); countryCard.appendChild(capitalParagraph); countryCard.appendChild(flagImage); countriesContainer.appendChild(countryCard); }); } function debounce(func, delay = 300) { let timerId; return (...args) => { clearTimeout(timerId); timerId = setTimeout(() => { func.apply(this, args); }, delay); }; } function searchFunc() { const searchTerm = searchInput.value.toLowerCase(); const filteredCountries = countriesData.filter(country => country.name.common.toLowerCase().includes(searchTerm) ); renderCountries(filteredCountries); } const debouncedSearchFunc = debounce(searchFunc); searchInput.addEventListener('input', debouncedSearchFunc); function saveSelectedRegion(selectedRegion) { localStorage.setItem("lastSelectedRegion", selectedRegion); } function getLastSelectedRegion() { return localStorage.getItem("lastSelectedRegion"); } function loadLastSelectedRegion() { const lastSelectedRegion = getLastSelectedRegion(); // 处理无存储数据的情况,默认选中第一个选项 const targetRegion = lastSelectedRegion || regionDropdown.options[0].value; regionDropdown.value = targetRegion; // 根据选中区域过滤国家 const filteredCountries = countriesData.filter(country => country.region.toLowerCase() === targetRegion.toLowerCase() ); renderCountries(filteredCountries); } // 移除嵌套的DOMContentLoaded监听,直接在数据加载完成后调用 loadLastSelectedRegion(); regionDropdown.addEventListener('change', function () { const selectedRegion = regionDropdown.value; const filteredCountries = countriesData.filter(country => country.region.toLowerCase() === selectedRegion.toLowerCase() ); renderCountries(filteredCountries); saveSelectedRegion(selectedRegion); }); }); let loadingTimer; function loadingPage() { loadingTimer = setTimeout(showPage, 2000); } function showPage() { clearTimeout(loadingTimer); document.querySelector(".loader").style.display = "none"; document.querySelector(".wrapper").style.display = "flex"; } document.addEventListener("DOMContentLoaded", loadingPage);
关键修改说明
- 移除嵌套事件监听:删掉内部重复的
DOMContentLoaded监听,直接在countriesData异步获取完成后调用loadLastSelectedRegion(),确保数据已准备好,避免执行时机错误。 - 添加默认值处理:在
loadLastSelectedRegion里,当localStorage没有存储的区域时,默认使用下拉菜单第一个选项的值,保证下拉菜单始终有选中项,同时渲染对应区域的国家。 - 统一初始渲染逻辑:不再单独渲染所有国家,而是通过
loadLastSelectedRegion统一处理初始渲染,无论是有存储数据还是首次访问,都能正确显示对应内容。
内容的提问来源于stack exchange,提问作者Ярослав Кудрявцев
相关产品推荐
相关产品推荐

