使用.on('error')遇重复请求:移动端图片加载失败处理求助
问题排查与解决方案
Let's break down your issues and fix them step by step:
一、为什么会出现重复请求
你设置的隐藏.check-img元素会在DOM加载时立刻发起一次移动端图片的请求。同时在移动设备上,<source media="(max-width:768px)">元素也会尝试加载目标图片(哪怕初始为空,后续赋值时也可能触发二次请求)。这种双重触发就是你看到不存在的图片被重复请求的原因。
二、当前jQuery代码不生效的原因
最可能的情况是error事件绑定的时机太晚——图片已经加载失败后,脚本才执行绑定,导致事件监听器根本没被触发。另外,仅仅修改srcset并不会强制<picture>元素重新评估资源,所以就算你正确赋值了默认图,它也不会显示出来。
三、修复方案
步骤1:调整HTML结构
保留.check-img但移除它的src属性,避免不必要的初始请求,改用自定义数据属性存储移动端图片地址:
<picture> <!-- 移动端图片(srcset将动态设置) --> <source srcset="" media="(max-width:768px)"> <!-- 仅用于存储数据的虚拟图片 --> <img style="display: none" data-mobile-src="mobile image src here" data-defaultimg="default src here" class="check-img" alt=""> <!-- 桌面端图片 --> <img src="desktop-img-src" alt="" class="img-fluid"> </picture>
步骤2:更新jQuery代码
我们用虚拟Image对象测试移动端图片的可用性(不会产生额外DOM请求),正确绑定事件,并在更新source后强制<picture>元素刷新资源:
$(document).ready(function() { $("picture").each(function() { const $picture = $(this); const $mobileSource = $picture.find("source[media='(max-width:768px)']"); const $checkImg = $picture.find(".check-img"); const mobileImgUrl = $checkImg.data("mobile-src"); const defaultImgUrl = $checkImg.data("defaultimg"); // 创建虚拟图片测试可用性(不会渲染到DOM中) const testImage = new Image(); testImage.src = mobileImgUrl; // 加载失败时:切换为默认图 testImage.onerror = function() { $mobileSource.attr("srcset", defaultImgUrl); // 强制picture元素重新评估资源 const $desktopImg = $picture.find(".img-fluid"); $desktopImg.attr("src", $desktopImg.attr("src")); }; // 加载成功时:使用原移动端图片 testImage.onload = function() { $mobileSource.attr("srcset", mobileImgUrl); }; // 清理:移除隐藏的check-img,因为已经不需要它了 $checkImg.remove(); }); });
核心改进点:
- 消除重复请求:仅通过虚拟
Image对象发起一次请求测试移动端图片的可用性。 - 及时绑定事件:在
$(document).ready()中执行代码,确保在图片完成加载前就开始测试。 - 强制picture刷新:重置桌面端图片的
src属性,触发<picture>元素重新检查资源,确保移动端在需要时立刻显示默认图。
内容的提问来源于stack exchange,提问作者Ganesh Kumar G
相关产品推荐
相关产品推荐

