当前位置: 首页 > wzjs >正文

茌平做创建网站公司九游手游平台app

茌平做创建网站公司,九游手游平台app,谁做的怀来吧网站,现在做百度推广有用吗如何为博客首页实现基于位置的天气和动态背景图片 引言 我为我的博客主页添加了根据用户所在位置显示当地天气、日出日落时间,并加载一张与天气和时间段匹配的高质量背景图片,可以显著提升用户体验。想象晴天时展示阳光普照的田野,雨天时呈现…

如何为博客首页实现基于位置的天气和动态背景图片

在这里插入图片描述

引言

我为我的博客主页添加了根据用户所在位置显示当地天气、日出日落时间,并加载一张与天气和时间段匹配的高质量背景图片,可以显著提升用户体验。想象晴天时展示阳光普照的田野,雨天时呈现湿润的城市街景,这样的个性化设计既美观又贴心。

我的博客主页:http://inksnowhl.cn/

本文将详细介绍如何实现这一功能,重点放在核心实现逻辑上,而不局限于特定框架,让你可以轻松将其应用到自己的项目中。

技术栈

实现这一功能需要以下技术:

  • JavaScript:用于处理 API 请求和逻辑计算,适用于任何前端环境。
  • Open-Meteo API:免费天气 API,提供天气代码、日出和日落时间。
  • Pexels API:图片 API,用于获取与天气和时间段匹配的高质量背景图片。
  • ipapi.co:免费 IP 定位服务,用于获取用户经纬度。
  • LocalStorage:浏览器缓存机制,用于存储背景图片,减少 API 请求。

实现步骤

1. 获取用户位置

要根据用户位置获取天气,首先需要用户的经纬度。ipapi.co 提供了一个简单 API,通过 GET 请求 https://ipapi.co/json/ 获取位置信息:

async function getLocation() {try {const response = await fetch("https://ipapi.co/json/");const data = await response.json();return { latitude: data.latitude, longitude: data.longitude };} catch (error) {console.error("获取位置失败:", error);return { latitude: 39.9042, longitude: 116.4074 }; // 默认位置(如北京)}
}

说明:如果请求失败,代码会回退到默认位置(这里以北京为例),确保功能可用。

2. 获取天气数据

使用 Open-Meteo API 获取天气信息,包括天气代码、日出和日落时间。以下是核心实现:

async function getWeather(latitude, longitude) {const params = {latitude,longitude,daily: ["sunrise", "sunset"],current: "weather_code",timezone: "auto",};const url = "https://api.open-meteo.com/v1/forecast";const responses = await fetchWeatherApi(url, params);const response = responses[0];const current = response.current();const daily = response.daily();return {weatherCode: current.variables(0).value(),sunrise: new Date(Number(daily.variables(0).valuesInt64(0)) * 1000).toLocaleString(),sunset: new Date(Number(daily.variables(1).valuesInt64(0)) * 1000).toLocaleString(),};
}

说明

  • 使用 fetchWeatherApi(需引入 Open-Meteo SDK)发送请求。
  • timezone: "auto" 自动适配用户时区。对于咱们中国,可以设置为北京的时区,设置为 timezone:"Asia/Shanghai"
  • 返回的天气代码(weatherCode)用于确定天气类型,日出日落时间用于时间段计算。
    • 天气代码参考:https://open-meteo.com/en/docs 的最下面

3. 映射天气代码

Open-Meteo 的天气代码是数字(例如,0 表示晴天,61 表示雨)。需要将其映射为描述性文本和英文名称,用于显示和图片搜索:

const weatherMap = {0: { zh: "晴天", en: "sunny" },1: { zh: "多云", en: "cloudy" },61: { zh: "雨", en: "rain" },95: { zh: "雷暴", en: "thunderstorm" },// 更多映射...
};function getWeatherDescription(code) {return weatherMap[code] || { zh: "未知", en: "unknown" };
}

说明:这种映射便于将天气代码转换为中文描述(用于显示)和英文名称(用于图片搜索)。

4. 获取动态背景图片

使用 Pexels API 根据天气和时间段搜索图片(例如,sunny morning)。为了优化性能,添加了 LocalStorage 缓存,并检查 API 配额:

async function getBackgroundImage(weather, timeOfDay) {const query = `${weather}+${timeOfDay}`;const cacheKey = "bgImg";const cache = localStorage.getItem(cacheKey);if (cache) {const cacheData = JSON.parse(cache);if (Date.now() < cacheData.expires && cacheData.query === query) {return cacheData.url;}}const response = await fetch(`https://api.pexels.com/v1/search?query=${query}&per_page=1`,{ headers: { Authorization: "您的 API 密钥" } });// 检查配额const limit = response.headers.get("X-Ratelimit-Limit");const remaining = response.headers.get("X-Ratelimit-Remaining");const reset = new Date(Number(response.headers.get("X-Ratelimit-Reset")) * 1000);console.log(`总配额: ${limit}, 剩余: ${remaining}, 重置时间: ${reset}`);if (remaining === "0") {console.warn("Pexels API 配额已用尽,将于", reset, "重置");return "默认图片 URL"; // 提供备用图片}const data = await response.json();const url = data.photos[0]?.src.original || "默认图片 URL";localStorage.setItem(cacheKey, JSON.stringify({expires: Date.now() + 1000 * 60 * 60, // 缓存1小时url,query,}));return url;
}

配额检查说明

  • X-Ratelimit-Limit:每月总请求限额。
  • X-Ratelimit-Remaining:剩余请求数。
  • X-Ratelimit-Reset:配额重置的 UNIX 时间戳(秒)。
  • 如果 remaining 为 0,代码会记录警告并使用默认图片,确保功能不中断。

5. 计算时间段

根据日出日落时间,将一天分为早晨、中午、傍晚和晚上,用于选择合适的背景图片:

function getTimeOfDay(sunrise, sunset) {const now = Date.now();const sunriseTime = new Date(sunrise).getTime();const sunsetTime = new Date(sunset).getTime();const morningEnd = sunriseTime + 4 * 3600 * 1000; // 日出后4小时const eveningStart = sunsetTime - 1 * 3600 * 1000; // 日落前1小时if (now < sunriseTime) return { zh: "晚上", en: "night" };if (now < morningEnd) return { zh: "早晨", en: "morning" };if (now < eveningStart) return { zh: "中午", en: "noon" };return { zh: "傍晚", en: "evening" };
}

说明:时间段基于日出日落时间动态计算,确保图片与实际时间匹配。

6. 整合功能

以下是将上述逻辑整合的主函数:

async function initDynamicBackground() {const { latitude, longitude } = await getLocation();const weatherData = await getWeather(latitude, longitude);const weatherDesc = getWeatherDescription(weatherData.weatherCode);const timeOfDay = getTimeOfDay(weatherData.sunrise, weatherData.sunset);const bgUrl = await getBackgroundImage(weatherDesc.en, timeOfDay.en);// 应用背景图片(例如,设置到 DOM)document.body.style.backgroundImage = `url(${bgUrl})`;// 显示天气信息(例如,更新 DOM)document.getElementById("weather").textContent = weatherDesc.zh;document.getElementById("sunrise").textContent = weatherData.sunrise;document.getElementById("sunset").textContent = weatherData.sunset;
}

说明

  • 函数按顺序获取位置、天气、时间段和背景图片。
  • 结果用于更新页面背景和显示天气信息。
  • 代码使用原生 JavaScript 操作 DOM,适用于任何环境。

完整代码示例

以下是核心功能的完整实现:

const weatherMap = {0: { zh: "晴天", en: "sunny" },1: { zh: "多云", en: "cloudy" },61: { zh: "雨", en: "rain" },95: { zh: "雷暴", en: "thunderstorm" },
};async function getLocation() {try {const response = await fetch("https://ipapi.co/json/");const data = await response.json();return { latitude: data.latitude, longitude: data.longitude };} catch (error) {console.error("获取位置失败:", error);return { latitude: 39.9042, longitude: 116.4074 };}
}async function getWeather(latitude, longitude) {const params = {latitude,longitude,daily: ["sunrise", "sunset"],current: "weather_code",timezone: "auto",};const url = "https://api.open-meteo.com/v1/forecast";const responses = await fetchWeatherApi(url, params);const response = responses[0];const current = response.current();const daily = response.daily();return {weatherCode: current.variables(0).value(),sunrise: new Date(Number(daily.variables(0).valuesInt64(0)) * 1000).toLocaleString(),sunset: new Date(Number(daily.variables(1).valuesInt64(0)) * 1000).toLocaleString(),};
}function getWeatherDescription(code) {return weatherMap[code] || { zh: "未知", en: "unknown" };
}function getTimeOfDay(sunrise, sunset) {const now = Date.now();const sunriseTime = new Date(sunrise).getTime();const sunsetTime = new Date(sunset).getTime();const morningEnd = sunriseTime + 4 * 3600 * 1000;const eveningStart = sunsetTime - 1 * 3600 * 1000;if (now < sunriseTime) return { zh: "晚上", en: "night" };if (now < morningEnd) return { zh: "早晨", en: "morning" };if (now < eveningStart) return { zh: "中午", en: "noon" };return { zh: "傍晚", en: "evening" };
}async function getBackgroundImage(weather, timeOfDay) {const query = `${weather}+${timeOfDay}`;const cacheKey = "bgImg";const cache = localStorage.getItem(cacheKey);if (cache) {const cacheData = JSON.parse(cache);if (Date.now() < cacheData.expires && cacheData.query === query) {return cacheData.url;}}const response = await fetch(`https://api.pexels.com/v1/search?query=${query}&per_page=1`,{ headers: { Authorization: "您的 API 密钥" } });const limit = response.headers.get("X-Ratelimit-Limit");const remaining = response.headers.get("X-Ratelimit-Remaining");const reset = new Date(Number(response.headers.get("X-Ratelimit-Reset")) * 1000);console.log(`总配额: ${limit}, 剩余: ${remaining}, 重置时间: ${reset}`);if (remaining === "0") {console.warn("Pexels API 配额已用尽,将于", reset, "重置");return "默认图片 URL";}const data = await response.json();const url = data.photos[0]?.src.original || "默认图片 URL";localStorage.setItem(cacheKey, JSON.stringify({expires: Date.now() + 1000 * 60 * 60,url,query,}));return url;
}async function initDynamicBackground() {const { latitude, longitude } = await getLocation();const weatherData = await getWeather(latitude, longitude);const weatherDesc = getWeatherDescription(weatherData.weatherCode);const timeOfDay = getTimeOfDay(weatherData.sunrise, weatherData.sunset);const bgUrl = await getBackgroundImage(weatherDesc.en, timeOfDay.en);document.body.style.backgroundImage = `url(${bgUrl})`;document.getElementById("weather").textContent = weatherDesc.zh;document.getElementById("sunrise").textContent = weatherData.sunrise;document.getElementById("sunset").textContent = weatherData.sunset;
}// 执行初始化
initDynamicBackground();

注意事项

  1. Pexels API 配额

    • 每月配额通过 X-Ratelimit-Limit 查看(通常为 20,000 次)。
    • 剩余请求数通过 X-Ratelimit-Remaining 获取。
    • 重置时间通过 X-Ratelimit-Reset(UNIX 时间戳)确定。
    • 若配额用尽,建议使用默认图片或暂停请求直到重置。
  2. API 密钥安全:不要将 Pexels API 密钥硬编码在前端代码中。建议通过环境变量或后端代理加载。

  3. 缓存优化:背景图片缓存为1小时,避免频繁请求,同时保持内容新鲜,也能减少API请求次数,防止耗尽配额

  4. 错误处理

    • 位置获取失败时使用默认经纬度。
    • 图片请求失败或无结果时使用默认图片。
    • 检查 API 配额,防止超限。
  5. 框架无关:代码使用原生 JavaScript,可轻松适配 Vue、React 或其他框架。只需将数据绑定到框架的状态管理(如 Vue 的 ref 或 React 的 useState)。

结语

通过以上步骤,你可以为博客首页实现一个动态功能:根据用户位置显示天气、日出日落时间,并加载匹配的背景图片。核心逻辑使用纯 JavaScript 实现,灵活适用于各种项目。Pexels API 的配额检查确保了请求的可靠性,而缓存机制优化了性能。快试试吧,为你的博客增添一份个性化的魅力!


文章转载自:

http://qA11FgAi.pxwjp.cn
http://xFjlCxHL.pxwjp.cn
http://wLCpumP0.pxwjp.cn
http://5jFTS8P2.pxwjp.cn
http://4S3qRGzL.pxwjp.cn
http://nEnzt7fy.pxwjp.cn
http://FRflv96z.pxwjp.cn
http://ZHJIxT27.pxwjp.cn
http://FJrnNpQn.pxwjp.cn
http://LmpUSeMw.pxwjp.cn
http://LEdouU7u.pxwjp.cn
http://FR5rFYGl.pxwjp.cn
http://SHnacUt1.pxwjp.cn
http://E8k62y2x.pxwjp.cn
http://GrqGZCXv.pxwjp.cn
http://X2k1Acae.pxwjp.cn
http://BMpwgb6B.pxwjp.cn
http://v6aNqCQo.pxwjp.cn
http://SpJspVO6.pxwjp.cn
http://6zyqdhq8.pxwjp.cn
http://rufGiK7Z.pxwjp.cn
http://dWov9aKu.pxwjp.cn
http://HeeTGm7v.pxwjp.cn
http://a00MrqwQ.pxwjp.cn
http://HqARkQi1.pxwjp.cn
http://74OADK2b.pxwjp.cn
http://yK1ji5QK.pxwjp.cn
http://QradEju7.pxwjp.cn
http://fUwRT42B.pxwjp.cn
http://YUFwH2eP.pxwjp.cn
http://www.dtcms.com/wzjs/663801.html

相关文章:

  • 做设计的素材网站网站制作基本步骤
  • 湛江大型网站模板建设廊坊做网站哪家好
  • c 网站开发 readonly属性网站设计制作报价图片
  • 网站开发的8个步骤wordpress菜单选项
  • 用阿里云空降怎么建设网站蚌埠网站制作公司哪家好
  • 江苏广泽建设有限公司网站急招网络销售招聘
  • 参考消息官方网站外贸网站建设 深圳
  • 凡科网注册东莞企业网站seo
  • 网站开发前端框架客户关系管理的重要性
  • 购物网站中加减数目的怎么做装修网站排名
  • 石景山区公司网站建设最新新闻热点事件摘抄及评论
  • 免费一键生成个人网站怎么做二手房网站
  • 仓山福州网站建设wordpress更改发布的文章
  • 白云手机网站建设价格网站建设工作自策划实施以来
  • 深圳住房和建设局网站预约网站前台需求文档
  • 新手做网站网站设计维护内容
  • 建立网站后怎样收费游戏网站模板
  • 企业网站建设大概多少钱写字楼装修公司
  • 北京住房投资建设中心网站首做理财网站
  • 网页源码怎么做网站做网站可以找设计公司吗
  • 设计网站的软件简历代写
  • 重庆网站建设去迅法网中医网站建设素材
  • 安徽省建设干部培训学校网站仿淘宝商城网站开源系统
  • 彩票网站 模块不要验证码的广告网站
  • 国外手机html5网站删除西部数码网站管理助手
  • 网上去哪里找做网站的wordpress增强搜索
  • 网站开发和系统开发区别郑州建网站371
  • 网站建设的论文参考文献网站运营现状
  • 设计师接单网站怎样创建自己公司网站
  • 广西免费网站制作泰安seo公司