下拉列表选择城市后时间无法持续更新问题排查
问题原因与修复方案
问题根源
选择新城市时,你仅隐藏了旧的城市容器,但这些容器仍保留在DOM中。updateTime函数会遍历所有.current-time元素(包括隐藏的),但传入的城市数组只有1个元素。当循环到索引大于0的元素时,cityName[i]会变为undefined,此时moment.tz(undefined)会使用默认时区(此处为伦敦),导致新添加的城市时间被覆盖成伦敦时间。
修复方案
两种简洁的修复方式,任选其一即可:
方式一:删除旧容器而非隐藏
选择新城市时直接移除旧容器,避免DOM中残留多余元素,确保updateTime只处理新添加的单个时间元素。
修改updateSelectElement函数中的这段代码:
cityRowContainer.forEach((el) => { if (city) el.style.display = "none"; });
替换为:
cityRowContainer.forEach((el) => el.remove());
方式二:只更新可见的时间元素
调整updateTime函数,仅查找可见城市容器下的时间元素,跳过隐藏的旧容器:
const updateTime = function (cityName) { // 仅选择可见容器内的时间元素 const cityTimeEl = document.querySelectorAll(".city-container:not([style*='display: none']) .current-time"); cityTimeEl.forEach((el, i) => { const city = cityName[i]; if (!city) return; // 避免处理undefined的情况 const currentTime = formatTime(city); el.innerHTML = currentTime; }); };
完整修复代码(以方式一为例)
let updateInterval; let mainCities = [ "Europe/Paris", "America/New_York", "Europe/London", "Europe/Vilnius", ]; const formatDate = function (city) { const now = moment().tz(city).format("MMMM Do, YYYY"); return now; }; const formatTime = function (city) { const now = moment.tz(city); const currTime = now.format("HH:mm:ss [<small>]A[</small>]"); return currTime; }; const formatCityName = function (city) { const name = moment().tz(city); const nameExtracted = name.tz(); const showCityName = nameExtracted.split("/").slice(-1).join(" "); if (showCityName.includes("_")) { return showCityName.split("_").join(" "); } return showCityName; }; function displaySelectInputs() { const cityNames = moment.tz.names(); cityNames.forEach((city) => { const updatedName = city .split("/") .slice(-1) .join(" ") .replaceAll("_", " "); if (updatedName === "") return; const html = ` <option value="${city}">${updatedName}</option> `; selectCityElement.insertAdjacentHTML("beforeend", html); }); } displaySelectInputs(); const updateTime = function (cityName) { const cityTimeEl = document.querySelectorAll(".current-time"); cityTimeEl.forEach((el, i) => { const city = cityName[i]; const currentTime = formatTime(city); el.innerHTML = currentTime; }); }; const renderCityTimeData = function (cityName) { cityName.forEach(function (city) { const html = ` <div class="city-container"> <div class="city"> <h3 class="city-name">${formatCityName(city)}</h3> <p class="date">${formatDate(city)}</p> </div> <div class="city-time"> <p class="current-time"> ${formatTime(city)} </p> </div> </div> `; citiesContainer.insertAdjacentHTML("beforeend", html); }); updateInterval = setInterval(updateTime, 1000, mainCities); }; renderCityTimeData(mainCities); const updateSelectElement = function (e) { const city = e.target.value; const cityRowContainer = document.querySelectorAll(".city-container"); if (!city) return; // 删除所有旧容器 cityRowContainer.forEach((el) => el.remove()); const html = ` <div class="city-container"> <div class="city"> <h3 class="city-name">${formatCityName(city)}</h3> <p class="date">${formatDate(city)}</p> </div> <div class="city-time"> <p class="current-time"> ${formatTime(city)} </p> </div> </div>`; clearInterval(updateInterval); updateInterval = setInterval(updateTime, 1000, [city]); citiesContainer.insertAdjacentHTML("beforeend", html); }; selectCityElement.addEventListener("change", updateSelectElement);
内容的提问来源于stack exchange,提问作者A-Renata
相关产品推荐
相关产品推荐

