如何为API天气项目添加匹配天气状况的背景图片?
问题
我近期正在通过天气应用项目学习API,但仍是JavaScript新手,想了解如何为用户所选城市添加匹配天气状况的背景图片。
我计划在CSS中创建多个以天气命名的类(如.clear、.clouds、.rain等),然后根据OpenWeatherMap的数据,使用classList.add()方法切换body的类。我尝试在.then回调中添加document.getElementsByTagName("body")[0].classList.add(weatherValue);但未生效,希望得到帮助,也想了解更简便的实现方式。
以下是我的代码:
var button = document.querySelector(".button"); var inputValue = document.querySelector(".inputValue"); var cityName = document.querySelector(".name"); var weather = document.querySelector(".weather"); var desc = document.querySelector(".desc"); var temp = document.querySelector(".temp"); var humi = document.querySelector(".humi"); button.addEventListener("click", function() { fetch("https://api.openweathermap.org/data/2.5/weather?q="+inputValue.value+"&appid={myapikey}") .then(response => response.json()) .then(data => { var nameValue = data['name']; var weatherValue = data['weather'][0]['main']; var tempValue = data['main']['temp']; var descValue = data['weather'][0]['description']; var humiValue = data['main']['humidity']; cityName.innerHTML = nameValue; weather.innerHTML = weatherValue; // this gives "clear" "clouds" etc to <p> element desc.innerHTML = descValue; temp.innerHTML = "Temperature: " + tempValue; humi.innerHTML = "Humidity: " + humiValue; }) .catch(err => alert("Wrong city name!")) })
* { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: "Nunito", sans-serif; background-repeat: no-repeat; background-size: cover; } .input { text-align: center; margin: 100px 0; } input[type="text"] { height: 50px; width: 600px; background: #e7e7e7; font-family: "Nunito", sans-serif; font-weight: bold; font-size: 20px; border: none; border-radius: 2px; padding: 10px 10px; } input[type="submit"] { height: 50px; width: 100px; background: #e7e7e7; font-family: "Nunito", sans-serif; font-weight: bold; font-size: 20px; border: none; border-radius: 2px; } .display { text-align: center; } .clear { /* background image here */ } .clouds { /* another background image here */ }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="weather_app.css"> </head> <body> <div class="input"> <input type="text" class="inputValue" placeholder="Enter a city"> <input type="submit" value="Submit" class="button"> </div> <div class="display"> <h1 class="name"></h1> <p class="weather"></p> <p class="desc"></p> <p class="temp"></p> <p class="humi"></p> </div> <script src= "weather_app.js"></script> </body> </html>
解决方案
1. 修复类切换失效问题
你的核心思路没问题,失效是两个细节没处理:
- 大小写不匹配:OpenWeatherMap返回的
weather[0].main是首字母大写格式(比如Clear、Clouds),但你CSS里的类是小写的,添加类时要转成小写。 - 重复类堆积:多次查询不同天气后,body会积累多个天气类导致样式冲突,每次添加新类前要先移除旧的天气类。
修改后的JavaScript逻辑(加到.then回调末尾):
.then(data => { // ... 原有的DOM更新代码 ... // 定义所有可能用到的天气类 const weatherClassList = ['clear', 'clouds', 'rain', 'snow', 'thunderstorm', 'drizzle']; // 移除body上所有旧的天气类 weatherClassList.forEach(cls => document.body.classList.remove(cls)); // 添加新的天气类(转小写) document.body.classList.add(weatherValue.toLowerCase()); })
直接用document.body替代document.getElementsByTagName("body")[0],写法更简洁可靠。
2. 完善CSS背景图配置
确保每个天气类里正确设置背景图片路径:
.clear { background-image: url('./images/clear.jpg'); } .clouds { background-image: url('./images/clouds.jpg'); } .rain { background-image: url('./images/rain.jpg'); }
3. 更简便的实现方式(无需CSS类)
如果不想维护多个CSS类,可以直接通过对象映射天气类型和图片路径,动态设置body背景图:
.then(data => { // ... 原有的DOM更新代码 ... // 建立天气与图片的映射关系 const weatherImageMap = { 'Clear': './images/clear.jpg', 'Clouds': './images/clouds.jpg', 'Rain': './images/rain.jpg', 'Snow': './images/snow.jpg', 'Thunderstorm': './images/thunderstorm.jpg', 'Drizzle': './images/drizzle.jpg' }; // 设置背景图,找不到匹配项时用默认图 document.body.style.backgroundImage = `url(${weatherImageMap[weatherValue] || './images/default.jpg'})`; })
这种方式不需要额外写CSS类,直接通过JS完成映射,适合新手快速落地功能。
内容的提问来源于stack exchange,提问作者media.queeries
相关产品推荐
相关产品推荐

