28.Weather Query Widget
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>天气查询小工具</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background: linear-gradient(45deg, #3498db, #8e44ad);
}
.container {
background: rgba(255, 255, 255, 0.1);
padding: 2em;
border-radius: 30px;
width: 100%;
max-width: 420px;
margin: 1em;
backdrop-filter: blur(10px);
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
}
.search {
display: flex;
align-items: center;
justify-content: center;
}
button {
margin: 0.5em;
border-radius: 50%;
border: none;
height: 44px;
width: 44px;
outline: none;
background: #7c7c7c2b;
color: white;
cursor: pointer;
transition: 0.2s ease-in-out;
}
input.search-bar {
border: none;
outline: none;
padding: 0.4em 1em;
border-radius: 24px;
background: #7c7c7c2b;
color: white;
font-family: inherit;
font-size: 105%;
width: calc(100% - 100px);
}
button:hover {
background: #7c7c7c6b;
}
h1.temp {
margin: 0;
margin-bottom: 0.4em;
}
.flex {
display: flex;
align-items: center;
}
.description {
text-transform: capitalize;
margin-left: 8px;
}
.weather.loading {
visibility: hidden;
max-height: 20px;
position: relative;
}
.weather.loading:after {
visibility: visible;
content: "Loading...";
color: white;
position: absolute;
top: 0;
left: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="search">
<input type="text" class="search-bar" placeholder="输入城市名">
<button><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024" height="1.5em"
width="1.5em" xmlns="http://www.w3.org/2000/svg">
<path
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0 0 11.6 0l43.6-43.5a8.2 8.2 0 0 0 0-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z">
</path>
</svg></button>
</div>
<div class="weather loading">
<h2 class="city">天气在 北京</h2>
<h1 class="temp">51°C</h1>
<div class="flex">
<img src="https://openweathermap.org/img/wn/04n.png" alt="" class="icon" />
<div class="description">多云</div>
</div>
<div class="humidity">湿度: 60%</div>
<div class="wind">风速: 6.2 km/h</div>
</div>
</div>
<script>
let weather = {
apiKey: "YOUR_API_KEY_HERE",
fetchWeather: function (city) {
fetch(
"https://api.openweathermap.org/data/2.5/weather?q=" +
city +
"&units=metric&appid=" +
this.apiKey
)
.then((response) => {
if (!response.ok) {
alert("No weather found.");
throw new Error("No weather found.");
}
return response.json();
})
.then((data) => this.displayWeather(data));
},
displayWeather: function (data) {
const { name } = data;
const { icon, description } = data.weather[0];
const { temp, humidity } = data.main;
const { speed } = data.wind;
document.querySelector(".city").innerText = "天气在 " + name;
document.querySelector(".icon").src =
"https://openweathermap.org/img/wn/" + icon + ".png";
document.querySelector(".description").innerText = description;
document.querySelector(".temp").innerText = temp + "°C";
document.querySelector(".humidity").innerText =
"湿度: " + humidity + "%";
document.querySelector(".wind").innerText =
"风速: " + speed + " km/h";
document.querySelector(".weather").classList.remove("loading");
document.body.style.backgroundImage =
"url('https://source.unsplash.com/1600x900/?" + name + "')";
},
search: function () {
this.fetchWeather(document.querySelector(".search-bar").value);
},
};
document.querySelector(".search button").addEventListener("click", function () {
weather.search();
});
document
.querySelector(".search-bar")
.addEventListener("keyup", function (event) {
if (event.key == "Enter") {
weather.search();
}
});
weather.fetchWeather("北京");
</script>
</body>
</html>