问题描述
我正在尝试创建一个 for 循环来获取每天的最低和最高温度并输出它。我正在使用开放天气 API。我附上了一张图片,显示了调用时数据的样子。请随时提出任何问题。我不知道要澄清哪些类型的事情。这是我的 javascript。
fetch('https://api.openweathermap.org/data/2.5/onecall?lat=43.6121&lon=-116.3915&exclude=hourly,minutely&units=imperial&APPID=98cbc04c44e9fc2905a70710f2643e4e')
.then((response) => response.json())
.then((jsObject) => {
console.log(jsObject);
let temp = jsObject.current.temp;
let minTemp = jsObject.daily[0].temp.min;
let maxTemp = jsObject.daily[0].temp.max;
document.getElementById('condition').textContent = jsObject.current.weather[0].main;
document.getElementById('temp-min').textContent = Math.round(minTemp);
document.getElementById('temp-max').textContent = Math.round(maxTemp);
document.getElementById('temp-current').textContent = Math.round(temp);
var weekday = new Array(7);
weekday[0] = "Sun";
weekday[1] = "Mon";
weekday[2] = "Tue";
weekday[3] = "Wed";
weekday[4] = "Thu";
weekday[5] = "Fri";
weekday[6] = "Sat";
var data = jsObject.daily;
var dayOfWeek = document.getElementsByClassName("forecast-day");
var weatherIcon = document.getElementsByClassName("weatherIcon");
var tempMax = document.getElementsByClassName("forecast-max");
var tempMin = document.getElementsByClassName("forecast-min");
for (var i = 0; i < data.length; i++) {
var d = new Date(data[i]);
dayOfWeek[i].textContent = weekday[d.getDay()];
const imagesrc = 'https://openweathermap.org/img/w/' + data[i].weather[i].icon + '.png';
const description = data[i].weather[i].description;
weatherIcon[i].setAttribute('src',imagesrc);
weatherIcon[i].setAttribute('alt',description);
tempMax[i].innerHTML = Math.round(data[i].temp.max) + " °F";
tempMin[i].innerHTML = Math.round(data[i].temp.min) + " °F";
}
https://i.stack.imgur.com/boWF9.png
解决方法
根据我在该服务器的响应中看到的,weather
数组的每个元素的 daily
属性只有一个元素。然而,您的代码正在尝试使用 data[i].weather[i].icon
表达式访问更多内容,从循环的第二次迭代开始(当 i
为 1 时)。
然后代码就会出错,因为 data[i].weather[i]
未定义,而您正试图像处理对象一样使用它(访问其 icon
属性)。由于所有这些都是在 then
内执行的,因此您应该在控制台中看到 Unhandled promise rejection
... 或者(这真的很糟糕)它只是因为一些宽容的 catch
处理程序而静默失败。
解决方案似乎相当简单:用 data[i].weather[i]
部分替换所有 data[i].weather[0]
。或者(更好)将其存储在某个临时变量中,如下所示:
const weather = data[i].weather[0];
const imagesrc = 'https://openweathermap.org/img/w/' + weather.icon + '.png';
weatherIcon[i].setAttribute('src',imagesrc);
weatherIcon[i].setAttribute('alt',weather.description);
作为旁注,我建议重构您的代码,以便它遍历收集到的 DOM 元素,而不是服务器的响应。有可能出现不匹配,因为那里有 8 个元素(天),但很难说有多少 .forecast-day
、.forecast-max
等...元素在您的 DOM 中。
这是您的代码的工作片段。您没有正确访问日期值 var d = new Date(data[i].dt);
(不是 new Date(data[i])
),这导致其他依赖日期的项目失败。修复后,一周中的哪一天需要调整为 weekday[d.getDay()+i];
。所需的 data[i].weather[i]
引用不正确(天气只有一个索引)data[i].weather[0]
。
为了测试,我生成了 divs 和 img 元素,所以格式是关闭的,但你可以看到它们都被填充了。
/* this section is just to generate the elements for testing */
let a = ['condition','temp-min','temp-max','temp-current'];
a.forEach(b => {
document.querySelector('#boxes').innerHTML += "<div id='" + b + "'>---" + b + "---</div>";
})
a = ["forecast-day","forecast-max","forecast-min"];
a.forEach(b => {
for (let x = 0; x < 7; x++) document.querySelector('#boxes').innerHTML += "<div class='" + b + "'>---" + b + "---</div>";
})
a = ["weatherIcon"];
a.forEach(b => {
for (let x = 0; x < 7; x++) document.querySelector('#boxes').innerHTML += "<img class='" + b + "'>";
})
/* Your code */
fetch('https://api.openweathermap.org/data/2.5/onecall?lat=43.6121&lon=-116.3915&exclude=hourly,minutely&units=imperial&APPID=98cbc04c44e9fc2905a70710f2643e4e')
.then((response) => response.json())
.then((jsObject) => {
let temp = jsObject.current.temp;
let minTemp = +jsObject.daily[0].temp.min;
let maxTemp = +jsObject.daily[0].temp.max;
document.getElementById('condition').textContent = jsObject.current.weather[0].main;
document.getElementById('temp-min').textContent = Math.round(minTemp);
document.getElementById('temp-max').textContent = Math.round(maxTemp);
document.getElementById('temp-current').textContent = Math.round(temp);
var weekday = new Array(7);
weekday[0] = "Sun";
weekday[1] = "Mon";
weekday[2] = "Tue";
weekday[3] = "Wed";
weekday[4] = "Thu";
weekday[5] = "Fri";
weekday[6] = "Sat";
var data = jsObject.daily;
var dayOfWeek = document.getElementsByClassName("forecast-day");
var weatherIcon = document.getElementsByClassName("weatherIcon");
var tempMax = document.getElementsByClassName("forecast-max");
var tempMin = document.getElementsByClassName("forecast-min");
for (var i = 0; i < data.length; i++) {
var d = new Date(data[i].dt);
dayOfWeek[i].textContent = weekday[d.getDay()+i];
const imagesrc = 'https://openweathermap.org/img/w/' + data[i].weather[0].icon + '.png';
const description = data[i].weather[0].description;
weatherIcon[i].setAttribute('src',imagesrc);
weatherIcon[i].setAttribute('alt',description);
tempMax[i].innerHTML = Math.round(data[i].temp.max) + " °F";
tempMin[i].innerHTML = Math.round(data[i].temp.min) + " °F";
}
})
div {
margin: 2px;
border: 1px solid #ccc;
}
<div id='boxes'></div>