灵感源于偷掉月亮
准备工作
- 和风天气账号
- 你的站点
开始作业
HTML直接实现
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>简约天气小组件</title>
<style>
/* 天气小组件样式 */
.weather-widget {
display: flex;
align-items: center;
font-family: 'Arial', sans-serif;
background-color: rgba(255, 255, 255, 0.2);
border-radius: 15px;
padding: 5px 12px;
color: #fff;
backdrop-filter: blur(5px);
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
}
.weather-widget:hover {
background-color: rgba(255, 255, 255, 0.3);
}
.weather-icon {
width: 30px;
height: 30px;
margin-right: 8px;
}
.weather-temp {
font-size: 16px;
font-weight: bold;
margin-right: 8px;
}
.weather-desc {
font-size: 12px;
opacity: 0.9;
}
/* 加载动画 */
@keyframes pulse {
0% { opacity: 0.6; }
50% { opacity: 1; }
100% { opacity: 0.6; }
}
.weather-loading {
animation: pulse 1.5s infinite;
}
</style>
</head>
<body>
<!-- 导航栏示例 -->
<nav style="display: flex; justify-content: space-between; align-items: center; padding: 10px 20px; background-color: #333; color: white;">
<div>网站Logo</div>
<div class="weather-widget" id="weatherWidget">
<div class="weather-loading">加载天气...</div>
</div>
</nav>
<script>
// 和风天气API配置
const weatherConfig = {
key: 'YOUR_HEFENG_API_KEY', // 替换为你的和风天气API Key
location: '101010100', // 默认北京的城市代码,可以根据需要修改
unit: 'c' // 温度单位: c-摄氏度, f-华氏度
};
// 天气图标映射表 (根据和风天气的天气代码)
const weatherIcons = {
'100': '☀️', // 晴
'101': '🌤️', // 多云
'102': '⛅', // 少云
'103': '☁️', // 阴
'104': '🌫️', // 雾
'200': '💨', // 有风
'201': '🌬️', // 平静
'202': '🌀', // 台风
'203': '🌪️', // 龙卷风
'300': '🌧️', // 雨
'301': '⛈️', // 雷雨
'302': '🌩️', // 雷暴
'303': '❄️', // 雪
'304': '🌨️', // 雨夹雪
'305': '🌦️', // 阵雨
'306': '🌧️', // 大雨
'307': '🌧️', // 暴雨
'308': '🌊', // 大暴雨
'309': '☔', // 特大暴雨
'400': '❄️', // 小雪
'401': '❄️', // 中雪
'402': '❄️', // 大雪
'403': '❄️', // 暴雪
'404': '🌨️', // 雨夹雪
'405': '🌨️', // 阵雪
'500': '🌫️', // 薄雾
'501': '🌫️', // 雾
'502': '🌫️', // 霾
'503': '💨', // 扬沙
'504': '💨', // 浮尘
'507': '💨', // 沙尘暴
'508': '💨' // 强沙尘暴
};
// 天气描述映射表
const weatherDescriptions = {
'100': '晴',
'101': '多云',
'102': '少云',
'103': '阴',
'104': '雾',
'200': '有风',
'201': '平静',
'202': '台风',
'203': '龙卷风',
'300': '雨',
'301': '雷雨',
'302': '雷暴',
'303': '雪',
'304': '雨夹雪',
'305': '阵雨',
'306': '大雨',
'307': '暴雨',
'308': '大暴雨',
'309': '特大暴雨',
'400': '小雪',
'401': '中雪',
'402': '大雪',
'403': '暴雪',
'404': '雨夹雪',
'405': '阵雪',
'500': '薄雾',
'501': '雾',
'502': '霾',
'503': '扬沙',
'504': '浮尘',
'507': '沙尘暴',
'508': '强沙尘暴'
};
// 获取天气数据
async function fetchWeather() {
const url = `https://devapi.qweather.com/v7/weather/now?location=${weatherConfig.location}&key=${weatherConfig.key}`;
try {
const response = await fetch(url);
const data = await response.json();
if (data.code === '200') {
updateWeatherWidget(data.now);
} else {
console.error('天气数据获取失败:', data);
document.getElementById('weatherWidget').innerHTML = '<div class="weather-error">天气数据获取失败</div>';
}
} catch (error) {
console.error('获取天气数据时出错:', error);
document.getElementById('weatherWidget').innerHTML = '<div class="weather-error">天气服务不可用</div>';
}
}
// 更新天气小组件
function updateWeatherWidget(weatherData) {
const widget = document.getElementById('weatherWidget');
const weatherCode = weatherData.icon;
const temp = weatherData.temp;
const icon = weatherIcons[weatherCode] || '🌍';
const desc = weatherDescriptions[weatherCode] || '未知';
widget.innerHTML = `
<span class="weather-icon">${icon}</span>
<span class="weather-temp">${temp}°${weatherConfig.unit.toUpperCase()}</span>
<span class="weather-desc">${desc}</span>
`;
}
// 页面加载时获取天气
document.addEventListener('DOMContentLoaded', fetchWeather);
// 每小时更新一次天气
setInterval(fetchWeather, 3600000);
</script>
</body>
</html>
JS分离
// 和风天气API配置
const weatherConfig = {
key: 'YOUR_HEFENG_API_KEY', // 替换为你的和风天气API Key
location: '101010100', // 默认北京的城市代码
unit: 'c' // 温度单位: c-摄氏度, f-华氏度
};
// 天气图标映射表 (根据和风天气的天气代码)
const weatherIcons = {
'100': '☀️', // 晴
'101': '🌤️', // 多云
'102': '⛅', // 少云
'103': '☁️', // 阴
'104': '🌫️', // 雾
'200': '💨', // 有风
'201': '🌬️', // 平静
'202': '🌀', // 台风
'203': '🌪️', // 龙卷风
'300': '🌧️', // 雨
'301': '⛈️', // 雷雨
'302': '🌩️', // 雷暴
'303': '❄️', // 雪
'304': '🌨️', // 雨夹雪
'305': '🌦️', // 阵雨
'306': '🌧️', // 大雨
'307': '🌧️', // 暴雨
'308': '🌊', // 大暴雨
'309': '☔', // 特大暴雨
'400': '❄️', // 小雪
'401': '❄️', // 中雪
'402': '❄️', // 大雪
'403': '❄️', // 暴雪
'404': '🌨️', // 雨夹雪
'405': '🌨️', // 阵雪
'500': '🌫️', // 薄雾
'501': '🌫️', // 雾
'502': '🌫️', // 霾
'503': '💨', // 扬沙
'504': '💨', // 浮尘
'507': '💨', // 沙尘暴
'508': '💨' // 强沙尘暴
};
// 天气描述映射表
const weatherDescriptions = {
'100': '晴',
'101': '多云',
'102': '少云',
'103': '阴',
'104': '雾',
'200': '有风',
'201': '平静',
'202': '台风',
'203': '龙卷风',
'300': '雨',
'301': '雷雨',
'302': '雷暴',
'303': '雪',
'304': '雨夹雪',
'305': '阵雨',
'306': '大雨',
'307': '暴雨',
'308': '大暴雨',
'309': '特大暴雨',
'400': '小雪',
'401': '中雪',
'402': '大雪',
'403': '暴雪',
'404': '雨夹雪',
'405': '阵雪',
'500': '薄雾',
'501': '雾',
'502': '霾',
'503': '扬沙',
'504': '浮尘',
'507': '沙尘暴',
'508': '强沙尘暴'
};
// 获取天气数据
async function fetchWeather() {
const url = `https://devapi.qweather.com/v7/weather/now?location=${weatherConfig.location}&key=${weatherConfig.key}`;
try {
const response = await fetch(url);
const data = await response.json();
if (data.code === '200') {
updateWeatherWidget(data.now);
} else {
console.error('天气数据获取失败:', data);
showWeatherError('天气数据获取失败');
}
} catch (error) {
console.error('获取天气数据时出错:', error);
showWeatherError('天气服务不可用');
}
}
// 更新天气小组件
function updateWeatherWidget(weatherData) {
const widget = document.getElementById('weatherWidget');
const weatherCode = weatherData.icon;
const temp = weatherData.temp;
const icon = weatherIcons[weatherCode] || '🌍';
const desc = weatherDescriptions[weatherCode] || '未知';
widget.innerHTML = `
<span class="weather-icon">${icon}</span>
<span class="weather-temp">${temp}°${weatherConfig.unit.toUpperCase()}</span>
<span class="weather-desc">${desc}</span>
`;
}
// 显示错误信息
function showWeatherError(message) {
const widget = document.getElementById('weatherWidget');
widget.innerHTML = `<div class="weather-error">${message}</div>`;
}
// 页面加载时获取天气
document.addEventListener('DOMContentLoaded', () => {
fetchWeather();
// 每小时更新一次天气
setInterval(fetchWeather, 3600000);
});
CSS分离
/* 天气小组件样式 */
.weather-widget {
display: flex;
align-items: center;
font-family: 'Arial', sans-serif;
background-color: rgba(255, 255, 255, 0.2);
border-radius: 15px;
padding: 5px 12px;
color: #fff;
backdrop-filter: blur(5px);
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
}
.weather-widget:hover {
background-color: rgba(255, 255, 255, 0.3);
}
.weather-icon {
width: 30px;
height: 30px;
margin-right: 8px;
font-size: 20px;
text-align: center;
}
.weather-temp {
font-size: 16px;
font-weight: bold;
margin-right: 8px;
}
.weather-desc {
font-size: 12px;
opacity: 0.9;
}
/* 加载状态样式 */
.weather-loading {
animation: pulse 1.5s infinite;
}
.weather-error {
color: #ff6b6b;
font-size: 12px;
}
/* 加载动画 */
@keyframes pulse {
0% { opacity: 0.6; }
50% { opacity: 1; }
100% { opacity: 0.6; }
}
下一步
自动检测城市
// 和风天气API配置
const weatherConfig = {
key: 'YOUR_HEFENG_API_KEY', // 替换为你的和风天气API Key
defaultLocation: '101010100', // 默认北京的城市代码
unit: 'c' // 温度单位: c-摄氏度, f-华氏度
};
// 天气图标和描述映射表
const weatherIcons = {
'100': '☀️', '101': '🌤️', '102': '⛅', '103': '☁️', '104': '🌫️',
'200': '💨', '201': '🌬️', '202': '🌀', '203': '🌪️',
'300': '🌧️', '301': '⛈️', '302': '🌩️', '303': '❄️', '304': '🌨️',
'305': '🌦️', '306': '🌧️', '307': '🌧️', '308': '🌊', '309': '☔',
'400': '❄️', '401': '❄️', '402': '❄️', '403': '❄️', '404': '🌨️', '405': '🌨️',
'500': '🌫️', '501': '🌫️', '502': '🌫️', '503': '💨', '504': '💨',
'507': '💨', '508': '💨'
};
const weatherDescriptions = {
'100': '晴', '101': '多云', '102': '少云', '103': '阴', '104': '雾',
'200': '有风', '201': '平静', '202': '台风', '203': '龙卷风',
'300': '雨', '301': '雷雨', '302': '雷暴', '303': '雪', '304': '雨夹雪',
'305': '阵雨', '306': '大雨', '307': '暴雨', '308': '大暴雨', '309': '特大暴雨',
'400': '小雪', '401': '中雪', '402': '大雪', '403': '暴雪', '404': '雨夹雪', '405': '阵雪',
'500': '薄雾', '501': '雾', '502': '霾', '503': '扬沙', '504': '浮尘',
'507': '沙尘暴', '508': '强沙尘暴'
};
// 获取地理位置
function getLocation() {
return new Promise((resolve, reject) => {
if (!navigator.geolocation) {
reject(new Error('Geolocation not supported'));
return;
}
navigator.geolocation.getCurrentPosition(
position => resolve(position),
error => reject(error),
{ enableHighAccuracy: true, timeout: 5000 }
);
});
}
// 根据经纬度获取城市信息
async function getCityByLocation(lat, lon) {
const url = `https://geoapi.qweather.com/v2/city/lookup?location=${lon},${lat}&key=${weatherConfig.key}`;
try {
const response = await fetch(url);
const data = await response.json();
if (data.code === '200' && data.location && data.location.length > 0) {
return data.location[0].id; // 返回城市ID
}
throw new Error('City not found');
} catch (error) {
console.error('获取城市信息失败:', error);
throw error;
}
}
// 获取天气数据
async function fetchWeather(locationId) {
const url = `https://devapi.qweather.com/v7/weather/now?location=${locationId}&key=${weatherConfig.key}`;
try {
const response = await fetch(url);
const data = await response.json();
if (data.code === '200') {
return data.now;
}
throw new Error(data.message || 'Weather data error');
} catch (error) {
console.error('获取天气数据时出错:', error);
throw error;
}
}
// 更新天气小组件
function updateWeatherWidget(weatherData) {
const widget = document.getElementById('weatherWidget');
const weatherCode = weatherData.icon;
const temp = weatherData.temp;
const icon = weatherIcons[weatherCode] || '🌍';
const desc = weatherDescriptions[weatherCode] || '未知';
widget.innerHTML = `
<span class="weather-icon">${icon}</span>
<span class="weather-temp">${temp}°${weatherConfig.unit.toUpperCase()}</span>
<span class="weather-desc">${desc}</span>
`;
}
// 使用默认城市显示天气
async function showDefaultWeather() {
try {
const weatherData = await fetchWeather(weatherConfig.defaultLocation);
updateWeatherWidget(weatherData);
} catch (error) {
console.error('使用默认城市获取天气失败:', error);
}
}
// 初始化天气小组件
async function initWeatherWidget() {
try {
// 尝试获取当前位置
const position = await getLocation();
const cityId = await getCityByLocation(position.coords.latitude, position.coords.longitude);
const weatherData = await fetchWeather(cityId);
updateWeatherWidget(weatherData);
// 保存城市ID到本地存储
localStorage.setItem('lastKnownCity', cityId);
} catch (error) {
console.log('自动定位失败,使用默认城市:', error);
// 尝试使用上次成功的城市
const lastKnownCity = localStorage.getItem('lastKnownCity');
if (lastKnownCity) {
try {
const weatherData = await fetchWeather(lastKnownCity);
updateWeatherWidget(weatherData);
return;
} catch (e) {
console.error('使用上次城市获取天气失败:', e);
}
}
// 最后使用默认城市
showDefaultWeather();
}
// 每小时更新一次天气
setInterval(async () => {
const lastKnownCity = localStorage.getItem('lastKnownCity') || weatherConfig.defaultLocation;
try {
const weatherData = await fetchWeather(lastKnownCity);
updateWeatherWidget(weatherData);
} catch (error) {
console.error('定时更新天气失败:', error);
}
}, 3600000);
}
// 页面加载时初始化天气小组件
document.addEventListener('DOMContentLoaded', initWeatherWidget);
OK,改导航栏,嵌入,收工
嵌入引用偷掉月亮大佬的:Hexo中Buttefly主题功能增强(九)- 偷掉月亮(moonshuo.cn)
喵喵喵~
评论加载中...