使用srcset与sizes实现响应式img,避免高DPI设备加载过大图片
首先明确你之前修改代码失效的原因:srcset属性中宽度描述符(w)和像素密度描述符(x)互斥,同时添加1x标识后浏览器会忽略w描述符,将所有图片识别为1x等效资源,默认选择最小尺寸的740.jpg加载。
原生srcset + sizes的设计逻辑本身会将设备像素比(DPR)纳入选图计算规则,标准层面目前确实没有提供直接忽略DPR的配置项,以下是两种可落地的可行方案:
方案1:纯HTML模拟实现(兼容性佳,覆盖99%场景)
利用浏览器选图的计算公式:所需图像宽度 = sizes匹配到的长度值 × 当前设备DPR,我们可以把sizes的长度值按DPR等比缩小,让计算结果刚好匹配对应图片的宽度描述符,即可实现忽略DPR按视口选图的效果。主流设备DPR基本集中在1-3区间,覆盖这三个档位即可满足绝大多数用户需求:
<img src="740.jpg" title="..." alt="..." srcset=" 740.jpg 740w, 1280.jpg 1280w, 1600.jpg 1600w, 1920.jpg 1920w " sizes=" /* DPR=1设备 */ (resolution: 1dppx) and (max-width: 740px) 740px, (resolution: 1dppx) and (max-width: 980px) 1280px, (resolution: 1dppx) and (max-width: 1280px) 1600px, (resolution: 1dppx) 1920px, /* DPR=2设备 */ (resolution: 2dppx) and (max-width: 740px) 370px, (resolution: 2dppx) and (max-width: 980px) 640px, (resolution: 2dppx) and (max-width: 1280px) 800px, (resolution: 2dppx) 960px, /* DPR=3设备 */ (resolution: 3dppx) and (max-width: 740px) 247px, (resolution: 3dppx) and (max-width: 980px) 427px, (resolution: 3dppx) and (max-width: 1280px) 533px, (resolution: 3dppx) 640px, /* 其他DPR设备兜底 */ (max-width: 740px) 740px, (max-width: 980px) 1280px, (max-width: 1280px) 1600px, 1920px " >
方案2:JavaScript强制控制(100%符合需求,无兼容问题)
如果需要完全严格匹配你指定的断点规则,不接受任何例外,可以通过JS动态控制图片加载,完全绕过浏览器原生srcset的选图逻辑:
<img src="740.jpg" title="..." alt="..." class="responsive-img" data-src-740="740.jpg" data-src-980="1280.jpg" data-src-1280="1600.jpg" data-src-1920="1920.jpg" > <script> function updateResponsiveImg() { const viewportWidth = window.innerWidth; document.querySelectorAll('.responsive-img').forEach(img => { let targetSrc; if (viewportWidth <= 740) { targetSrc = img.dataset.src740; } else if (viewportWidth <= 980) { targetSrc = img.dataset.src980; } else if (viewportWidth <= 1280) { targetSrc = img.dataset.src1280; } else { targetSrc = img.dataset.src1920; } // 避免重复替换触发重加载 if (img.src !== targetSrc) img.src = targetSrc; }) } // 页面加载完成后执行 window.addEventListener('load', updateResponsiveImg); // 视口尺寸变化时执行 window.addEventListener('resize', updateResponsiveImg); </script>
内容的提问来源于stack exchange,提问作者Radon8472
相关产品推荐
相关产品推荐

