如何在原生JavaScript中加载外部SVG图标替换OpenWeather默认图标
原生JS加载外部SVG图标有两种常用的轻量化方案,都可以完全替代臃肿的switch写法:
方案1:单独SVG文件按需加载
适合图标数量不多的场景,每个天气状况对应一个独立SVG文件,无需额外合并操作。
- 先将所有SVG图标按统一规则命名,存入同一个目录(比如
/assets/weather-icons/),命名规则为:将天气描述的空格替换为短横线、全小写,例如clear sky对应clear-sky.svg,few clouds对应few-clouds.svg。 - 编写加载函数,内置缓存避免重复请求:
// 全局缓存已加载的SVG内容 const weatherIconCache = new Map(); // SVG文件存放的基础路径,根据你的项目结构修改 const ICON_BASE_PATH = '/assets/weather-icons/'; async function getWeatherIcon(condition) { // 转换为标准文件名 const fileName = condition.replaceAll(' ', '-').toLowerCase() + '.svg'; // 命中缓存直接返回 if (weatherIconCache.has(fileName)) { return weatherIconCache.get(fileName); } try { const response = await fetch(ICON_BASE_PATH + fileName); if (!response.ok) throw new Error('请求失败'); const svgContent = await response.text(); // 存入缓存后续复用 weatherIconCache.set(fileName, svgContent); return svgContent; } catch (err) { console.error(`加载${condition}图标失败:`, err); // 加载失败返回兜底默认图标 return '<svg viewBox="0 0 24 24">/* 你的默认图标代码 */</svg>'; } }
- 业务逻辑中调用:
const dailyCondition = value.weather[0].description; // 因为是异步函数,需要用await接收结果 const dailyConditionIcon = await getWeatherIcon(dailyCondition); // 直接插入DOM即可:element.innerHTML = dailyConditionIcon
方案2:SVG精灵图一次性加载
适合图标数量较多的场景,所有图标合并为一个精灵图文件,仅发起一次请求,切换图标无延迟。
- 先合并所有SVG为精灵图文件
weather-sprite.svg,每个图标用symbol标签包裹,ID和天气描述的转换结果对应:
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <symbol id="clear-sky" viewBox="0 0 24 24"> <!-- 晴天天图标的path代码 --> </symbol> <symbol id="few-clouds" viewBox="0 0 24 24"> <!-- 少云图标的path代码 --> </symbol> <!-- 其余所有天气图标按同样格式添加 --> </svg>
- 页面初始化时预加载精灵图:
window.addEventListener('DOMContentLoaded', async () => { try { const res = await fetch('/assets/weather-icons/weather-sprite.svg'); const spriteContent = await res.text(); const container = document.createElement('div'); container.style.display = 'none'; container.innerHTML = spriteContent; document.body.appendChild(container); } catch (err) { console.error('天气图标精灵图加载失败:', err); } });
- 业务逻辑中直接引用,无需异步处理:
const dailyCondition = value.weather[0].description; const iconId = dailyCondition.replaceAll(' ', '-').toLowerCase(); const dailyConditionIcon = `<svg class="weather-icon" viewBox="0 0 24 24"><use href="#${iconId}"></use></svg>`;
注意事项
- 使用精灵图时需要确保所有SVG内部的ID、类名不重复,避免样式冲突
- 部署时需要确保服务器配置了正确的SVG MIME类型(
image/svg+xml),否则浏览器会无法正常解析
内容的提问来源于stack exchange,提问作者Mike Hermary
相关产品推荐
相关产品推荐

