无法传递循环内文本框数据——Darksky API循环元素更新异常
问题分析与解决方案
嘿,我帮你排查下问题——核心是每次搜索时循环生成的天气卡片只会不断新增,不会替换旧内容,同时代码里还有几个语法和逻辑小坑,我一步步给你拆解修正:
1. 最关键的问题:旧元素没清空,新元素堆在后面
每次调用renderLoop()时,你都直接往.week-stage容器里加新的week-day-container元素,但从来没清理过之前的旧内容。所以看起来像是“没更新”,实际是旧卡片还在,新卡片叠在后面了。
解决办法:在创建新元素前,先清空容器:
const divsholdr = document.querySelector('.week-stage'); // 清空旧的天气卡片 divsholdr.innerHTML = ''; // 再开始循环创建新元素
2. 循环变量未声明导致全局污染
你的i和y没有用let/const声明,会变成全局变量,可能导致循环逻辑乱掉(比如其他代码不小心修改到这两个变量)。一定要加上声明:
// 把原来的 for(i=0;i<8;i++) 改成: for(let i=0;i<8;i++){ // ... 你的创建元素代码 } // 同理处理y: for(let y=0;y<8;y++){ // ... }
3. Skycons图标设置的语法错误
你这里把Skycons类本身给覆盖成字符串了,完全用错了:
// 错误写法:把Skycons(类)赋值成了icon字符串 skycons.set("icon0", Skycons = x.currently.icon); // 正确写法:Darksky返回的是小写连字符格式(比如"clear-day"),要转成Skycons的大写下划线常量(CLEAR_DAY) const currentIcon = x.currently.icon.toUpperCase().replace(/-/g, '_'); skycons.set("icon0", Skycons[currentIcon]);
每日图标也要做同样的转换:
const dayIcon = x.daily.data[y].icon.toUpperCase().replace(/-/g, '_'); skycons.set('icons'+(y+1), Skycons[dayIcon]);
4. 时间戳转可读日期
你直接把Unix时间戳赋值给了日期文本,用户看到的是一串数字,要转成可读格式:
const date = new Date(x.daily.data[i].time * 1000); // 转成类似 "Mon, Oct 16" 的格式 dates.textContent = date.toLocaleDateString('en-US', {weekday: 'short', month: 'short', day: 'numeric'});
修正后的完整renderLoop函数
把这些点整合后,代码应该是这样:
function renderLoop(){ var proxyUrl = 'https://cors-anywhere.herokuapp.com/'; var url1 = 'https://api.darksky.net/forecast/c34e122a56ae30a3090687878bce72c3/' + locres + '?units=auto'; fetch(proxyUrl + url1) .then(x => x.json()) .then(x => { var skycons = new Skycons({"color": "white"}); // 修正当前天气图标设置 const currentIcon = x.currently.icon.toUpperCase().replace(/-/g, '_'); skycons.set("icon0", Skycons[currentIcon]); skycons.play(); console.log(x.daily.data); const divsholdr = document.querySelector('.week-stage'); // 清空旧卡片 divsholdr.innerHTML = ''; for(let i=0;i<8;i++){ console.log(x.daily.data[i].time); console.log(x.daily.data[i].summary); const divs = document.createElement('div'); divs.className = 'week-day-container'; const canv = document.createElement('canvas'); canv.id = 'icons'+(i+1); canv.height = 100; canv.width = 70; divs.appendChild(canv); // 转换时间戳为可读日期 const date = new Date(x.daily.data[i].time * 1000); const dates = document.createElement('p'); dates.textContent = date.toLocaleDateString('en-US', {weekday: 'short', month: 'short', day: 'numeric'}); divs.appendChild(dates); const temp = document.createElement('p'); temp.textContent = 'High: '+ x.daily.data[i].temperatureHigh + ' Low: ' + x.daily.data[i].temperatureLow; divs.appendChild(temp); const summ = document.createElement('p'); summ.textContent = x.daily.data[i].summary; divs.appendChild(summ); divsholdr.appendChild(divs); } for(let y=0;y<8;y++){ const dayIcon = x.daily.data[y].icon.toUpperCase().replace(/-/g, '_'); skycons.set('icons'+(y+1), Skycons[dayIcon]); } }) .catch(err => { // 加个错误处理方便调试 console.error('获取天气数据出错:', err); }); }
额外小建议
- 把
locres改成用let声明的变量,别用全局变量; search函数里别依赖全局event,改成显式传参function search(ele, event);- 加个loading状态,避免用户重复触发搜索;
- 处理Geocode API返回错误的情况(比如地址找不到),防止后续代码因为无效的
locres报错。
内容的提问来源于stack exchange,提问作者DOODpls
相关产品推荐
相关产品推荐

