You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在picture标签中实现source加载失败时显示默认图片?

解决picture标签所有source加载失败时img默认图不显示的问题

问题原因

浏览器处理<picture>标签时,会优先匹配符合当前媒体查询的<source>资源并尝试加载。如果所有匹配的<source>都加载失败,浏览器不会自动回退加载<img>的默认src,只会显示alt文本,这是浏览器的默认行为逻辑。

修复方法

方法1:监听<source>的错误事件,手动触发<img>加载

给每个<source>添加onerror事件,统计失败的资源数量,当所有<source>都加载失败时,强制让<img>重新加载自身的src。

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<picture>
  <source media="(min-width:650px)" srcset="invalid.jpg" onerror="handleSourceError(this)">
  <source media="(min-width:465px)" srcset="invalid.jpg" onerror="handleSourceError(this)">
  <img id="fallbackImg" src="https://images.pexels.com/photos/9754/mountains-clouds-forest-fog.jpg" alt="test">
</picture>

<script>
let failedCount = 0;
const totalSources = document.querySelectorAll('picture source').length;
const fallbackImg = document.getElementById('fallbackImg');

function handleSourceError() {
  failedCount++;
  if (failedCount === totalSources) {
    // 重新赋值src触发浏览器加载默认图
    fallbackImg.src = fallbackImg.src;
  }
}
</script>
</body>
</html>

方法2:用CSS背景图做兜底

放弃<picture>标签,改用<div>配合CSS媒体查询设置背景图,利用CSS背景图的叠加特性,将兜底图作为备选:

<div class="responsive-img" role="img" aria-label="test"></div>

<style>
.responsive-img {
  width: 100%;
  height: 300px; /* 设置固定高度或用padding-top维持比例 */
  background: url('https://images.pexels.com/photos/9754/mountains-clouds-forest-fog.jpg') center/cover no-repeat;
}

@media (min-width: 465px) {
  .responsive-img {
    background: url('invalid.jpg') center/cover no-repeat, 
                url('https://images.pexels.com/photos/9754/mountains-clouds-forest-fog.jpg') center/cover no-repeat;
  }
}

@media (min-width: 650px) {
  .responsive-img {
    background: url('invalid.jpg') center/cover no-repeat, 
                url('https://images.pexels.com/photos/9754/mountains-clouds-forest-fog.jpg') center/cover no-repeat;
  }
}
</style>

当高优先级的背景图加载失败时,低优先级的兜底图会自动显示。

方法3:JS动态加载图片

通过JavaScript检测屏幕尺寸,主动加载对应图片,加载失败时直接切换到兜底图:

<img id="responsiveImg" src="https://images.pexels.com/photos/9754/mountains-clouds-forest-fog.jpg" alt="test">

<script>
const fallbackSrc = 'https://images.pexels.com/photos/9754/mountains-clouds-forest-fog.jpg';

function loadTargetImg() {
  let targetSrc = fallbackSrc;
  if (window.innerWidth >= 650) {
    targetSrc = 'invalid.jpg';
  } else if (window.innerWidth >= 465) {
    targetSrc = 'invalid.jpg';
  }

  const tempImg = new Image();
  tempImg.src = targetSrc;
  tempImg.onload = () => {
    document.getElementById('responsiveImg').src = targetSrc;
  };
  tempImg.onerror = () => {
    document.getElementById('responsiveImg').src = fallbackSrc;
  };
}

// 初始化加载
loadTargetImg();
// 窗口 resize 时重新加载
window.addEventListener('resize', loadTargetImg);
</script>

内容的提问来源于stack exchange,提问作者Alex Varela

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 17:30:59