CSS3 & jQuery 天气预报

<!DOCTYPE html>

<html lang="zh-***">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>CSS3 & jQuery 天气预报</title>

<style>

/ 基础样式 /

{
margin: 0;
padding: 0;

box-sizing: border-box;

font-family: 'Arial', sans-serif;

}

body {

background: linear-gradient(135deg, #1e5799 0%, #207***a 51%, #2989d8 100%);

min-height: 100vh;

display: flex;

justify-content: center;

align-items: center;

padding: 20px;

}

/ 天气卡片容器 /

.weather-container {

width: 100%;

max-width: 800px;

background: rgba(255, 255, 255, 0.2);

backdrop-filter: blur(10px);

border-radius: 20px;

box-shadow: 0 15px 30px rgba(0, 0, 0, 0.2);

overflow: hidden;

color: white;

position: relative;

transition: all 0.5s ease;

}

/ 当前天气区域 /

.current-weather {

padding: 30px;

text-align: center;

position: relative;

z-index: 1;

}

.location {

font-size: 24px;

margin-bottom: 10px;

font-weight: 300;

}

.date {

font-size: 14px;

opacity: 0.8;

margin-bottom: 20px;

}

.temp {

font-size: 72px;

font-weight: 300;

margin: 20px 0;

position: relative;

display: inline-block;

}

.temp:after {

content: "°C";

position: absolute;

top: 10px;

right: -25px;

font-size: 24px;

}

.weather-icon {

width: 120px;

height: 120px;

margin: 0 auto;

background-size: contain;

background-repeat: no-repeat;

background-position: center;

position: relative;

animation: float 3s ease-in-out infinite;

}

@keyframes float {

0%, 100% { transform: translateY(0); }

50% { transform: translateY(-10px); }

}

.description {

font-size: 18px;

text-transform: capitalize;

margin-bottom: 20px;

}

.details {

display: flex;

justify-content: space-around;

margin-top: 30px;

}

.detail-item {

text-align: center;

}

.detail-item i {

font-size: 24px;

margin-bottom: 10px;

display: block;

}

.detail-value {

font-size: 18px;

font-weight: 300;

}

.detail-label {

font-size: 12px;

opacity: 0.8;

margin-top: 5px;

}

/ 天气预报区域 /

.forecast {

background: rgba(0, 0, 0, 0.1);

padding: 20px;

display: flex;

overflow-x: auto;

scrollbar-width: none;

}

.forecast::-webkit-scrollbar {

display: none;

}

.forecast-day {

min-width: 100px;

text-align: center;

padding: 10px;

margin-right: 10px;

border-radius: 10px;

transition: all 0.3s ease;

cursor: pointer;

}

.forecast-day:hover {

background: rgba(255, 255, 255, 0.1);

transform: translateY(-5px);

}

.forecast-day:last-child {

margin-right: 0;

}

.day-name {

font-size: 14px;

margin-bottom: 10px;

}

.forecast-icon {

width: 50px;

height: 50px;

margin: 0 auto 10px;

background-size: contain;

background-repeat: no-repeat;

background-position: center;

}

.forecast-temp {

font-size: 16px;

}

/ 搜索区域 /

.search-container {

padding: 20px;

display: flex;

justify-content: center;

}

.search-input {

padding: 12px 20px;

border: none;

border-radius: 30px;

width: 70%;

max-width: 400px;

font-size: 16px;

outline: none;

background: rgba(255, 255, 255, 0.2);

color: white;

transition: all 0.3s ease;

}

.search-input::placeholder {

color: rgba(255, 255, 255, 0.7);

}

.search-input:focus {

background: rgba(255, 255, 255, 0.3);

box-shadow: 0 0 10px rgba(255, 255, 255, 0.2);

}

/ 天气背景效果 /

.weather-bg {

position: absolute;

top: 0;

left: 0;

width: 100%;

height: 100%;

z-index: 0;

opacity: 0.3;

}

/ 响应式设计 /

@media (max-width: 600px) {

.temp {

font-size: 60px;

}

.weather-icon {

width: 100px;

height: 100px;

}

.forecast-day {

min-width: 80px;

}

}

/ 天气图标动画 /

.sun {

background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23FFD700"><circle cx="12" cy="12" r="5"/><path d="M12 1v2m0 18v2M4.22 4.22l1.42 1.42m12.72 12.72l1.42 1.42M1 12h2m18 0h2M4.22 19.78l1.42-1.42m12.72-12.72l1.42-1.42"/></svg>');

animation: pulse 2s infinite alternate;

}

.cloud {

background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23FFFFFF"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96z"/></svg>');

animation: float 4s ease-in-out infinite;

}

.rain {

background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23FFFFFF"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM7 17l-3.17-3.17 1.41-1.41L7 14.17l4.59-4.58 1.41 1.41L7 17z"/></svg>');

position: relative;

}

.rain:after {

content: "";

position: absolute;

bottom: -15px;

left: 50%;

transform: translateX(-50%);

width: 60px;

height: 10px;

background: radial-gradient(circle, rgba(255,255,255,0.8) 0%, rgba(255,255,255,0) 70%);

animation: rainDrops 1s linear infinite;

}

@keyframes rainDrops {

0% { opacity: 0; transform: translateX(-50%) translateY(0) scale(0.3); }

50% { opacity: 1; }

100% { opacity: 0; transform: translateX(-50%) translateY(20px) scale(1); }

}

.snow {

background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23FFFFFF"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM12 18c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></svg>');

position: relative;

}

.snow:after {

content: "";

position: absolute;

bottom: -15px;

left: 50%;

transform: translateX(-50%);

width: 60px;

height: 10px;

background: radial-gradient(circle, rgba(255,255,255,0.8) 0%, rgba(255,255,255,0) 70%);

animation: snowFlakes 2s linear infinite;

}

@keyframes snowFlakes {

0% { opacity: 0; transform: translateX(-50%) translateY(0) scale(0.3) rotate(0deg); }

50% { opacity: 1; }

100% { opacity: 0; transform: translateX(-50%) translateY(20px) scale(1) rotate(360deg); }

}

.thunder {

background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23FFFFFF"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 17h-4l2-4h-3l3-6 1 2h3l-2 4h3z"/></svg>');

animation: flash 3s infinite;

}

@keyframes flash {

0%, 100% { opacity: 1; }

50% { opacity: 0.5; }

}

/ 加载动画 /

.loading {

position: absolute;

top: 0;

left: 0;

width: 100%;

height: 100%;

background: rgba(0, 0, 0, 0.5);

display: flex;

justify-content: center;

align-items: center;

z-index: 10;

opacity: 0;

pointer-events: none;

transition: opacity 0.3s ease;

}

.loading.active {

opacity: 1;

pointer-events: all;

}

.spinner {

width: 50px;

height: 50px;

border: 5px solid rgba(255, 255, 255, 0.3);

border-radius: 50%;

border-top-color: white;

animation: spin 1s ease-in-out infinite;

}

@keyframes spin {

to { transform: rotate(360deg); }

}

/ 版权信息 /

.copyright {

text-align: center;

font-size: 12px;

margin-top: 20px;

opacity: 0.7;

}

.copyright a {

color: white;

text-decoration: none;

}

.copyright a:hover {

text-decoration: underline;

}

</style>

</head>

<body>

<div class="weather-container">

<div class="loading">

<div class="spinner"></div>

</div>

<div class="current-weather">

<h1 class="location">加载中...</h1>

<div class="date">--年--月--日 星期-</div>

<div class="weather-icon sun"></div>

<div class="temp">--</div>

<div class="description">加载天气数据...</div>

<div class="details">

<div class="detail-item">

<i>💧</i>

<div class="detail-value">--%</div>

<div class="detail-label">湿度</div>

</div>

<div class="detail-item">

<i>🌬️</i>

<div class="detail-value">-- km/h</div>

<div class="detail-label">风速</div>

</div>

<div class="detail-item">

<i>☁️</i>

<div class="detail-value">--%</div>

<div class="detail-label">云量</div>

</div>

</div>

</div>

<div class="forecast">

<!-- 天气预报将通过JavaScript动态生成 -->

</div>

<div class="search-container">

<input type="text" class="search-input" placeholder="输入城市名称..." id="city-input">

</div>

</div>

<script src="https://code.jquery.***/jquery-3.6.0.min.js"></script>

<script>

$(document).ready(function() {

// 默认城市

let currentCity = "北京";

// 天气图标映射

const weatherIcons = {

"clear": "sun",

"clouds": "cloud",

"rain": "rain",

"snow": "snow",

"thunderstorm": "thunder",

"drizzle": "rain",

"mist": "cloud",

"smoke": "cloud",

"haze": "cloud",

"dust": "cloud",

"fog": "cloud",

"sand": "cloud",

"ash": "cloud",

"squall": "thunder",

"tornado": "thunder"

};

// 星期映射

const weekDays = ["日", "一", "二", "三", "四", "五", "六"];

// 初始化获取天气数据

getWeatherData(currentCity);

// 搜索城市

$("#city-input").on("keypress", function(e) {

if (e.which === 13) {

currentCity = $(this).val().trim();

if (currentCity) {

getWeatherData(currentCity);

$(this).val("");

}

}

});

// 获取天气数据

function getWeatherData(city) {

showLoading(true);

// 这里使用模拟数据,实际应用中应该调用天气API

setTimeout(() => {

// 模拟API响应

const mockData = generateMockWeatherData(city);

updateWeatherUI(mockData);

showLoading(false);

}, 1000);

}

// 更新天气UI

function updateWeatherUI(data) {

// 更新当前天气

$(".location").text(data.city);

const date = new Date(data.current.dt * 1000);

const dateStr = ${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日 星期${weekDays[date.getDay()]}`;

$(".date").text(dateStr);

$(".temp").text(Math.round(data.current.temp));

$(".description").text(data.current.weather[0].description);

// 更新天气图标
const weatherMain = data.current.weather[0].main.toLowerCase();

const iconClass = weatherIcons[weatherMain] || "sun";

$(".weather-icon").removeClass().addClass("weather-icon " + iconClass);

// 更新详情

$(".detail-item:nth-child(1) .detail-value").text(data.current.humidity + "%");

$(".detail-item:nth-child(2) .detail-value").text(data.current.wind_speed + " km/h");

$(".detail-item:nth-child(3) .detail-value").text(data.current.clouds + "%");

// 更新天气预报

$(".forecast").empty();

data.daily.slice(1, 6).forEach(day => {

const dayDate = new Date(day.dt * 1000);

const dayName = weekDays[dayDate.getDay()];

const dayWeatherMain = day.weather[0].main.toLowerCase();

const dayIconClass = weatherIcons[dayWeatherMain] || "sun";

$(".forecast").append(

<div class="forecast-day">

<div class="day-name">${dayName}</div>

<div class="forecast-icon ${dayIconClass}"></div>

<div class="forecast-temp">${Math.round(day.temp.day)}°</div>

</div>

);

});

}

// 显示/隐藏加载动画

function showLoading(show) {

if (show) {

$(".loading").addClass("active");

} else {

$(".loading").removeClass("active");

}

}

// 生成模拟天气数据

function generateMockWeatherData(city) {

const weatherConditions = [

{ main: "Clear", description: "晴天" },

{ main: "Clouds", description: "多云" },

{ main: "Rain", description: "小雨" },

{ main: "Snow", description: "小雪" },

{ main: "Thunderstorm", description: "雷阵雨" }

];

// 随机选择当前天气

const currentWeather = weatherConditions[Math.floor(Math.random() * weatherConditions.length)];

// 当前天气数据

const current = {

dt: Math.floor(Date.now() / 1000),

temp: 10 + Math.floor(Math.random() * 20), // 10-30度

humidity: 30 + Math.floor(Math.random() * 60), // 30-90%

wind_speed: 1 + Math.floor(Math.random() * 15), // 1-15 km/h

clouds: 10 + Math.floor(Math.random() * 80), // 10-90%

weather: [currentWeather]

};

// 每日预报数据

const daily = [];

for (let i = 0; i < 7; i++) {

const dayWeather = weatherConditions[Math.floor(Math.random() * weatherConditions.length)];

daily.push({

dt: current.dt + (i * 86400),

temp: {

day: current.temp - 2 + Math.floor(Math.random() * 8) // 当前温度±5度

},

weather: [dayWeather]

});

}

return {

city: city,

current: current,

daily: daily

};

}

// 添加背景动画效果

function addBackgroundEffects() {

const container = $(".weather-container");

const effects = ["sunny", "cloudy", "rainy", "snowy"];

// 每10秒切换一次背景效果

setInterval(() => {

const effect = effects[Math.floor(Math.random() * effects.length)];

container.removeClass(effects.join(" ")).addClass(effect);

}, 10000);

}

// 初始化背景效果

addBackgroundEffects();

});

</script>

</body>

</html>

转载请说明出处内容投诉
CSS教程网 » CSS3 &amp; jQuery 天气预报

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买