如何获取通过srcset加载的图片的naturalWidth值?
问题:使用srcset时无法获取图片真实自然尺寸,naturalWidth返回容器宽度
我正在开发一个用srcset的lightbox脚本,希望浏览器根据屏幕尺寸选择合适大小的图片。JS部分会在请求时切换图片,尝试获取新图片的自然尺寸。因为浏览器会从srcset里选图,我用img.addEventListener("load", ...)等图片加载完后查看naturalWidth,但这个值不是JPEG原图的像素尺寸,而是容器宽度。哪里错了?
相关代码
HTML
<button type=button id=button1>Reload</button> <div id=div1> <figure id=fig1> <img id=img1 src="https://picsum.photos/300/150" srcset="https://picsum.photos/600/300 600w, https://picsum.photos/400/200 400w, https://picsum.photos/200/100 200w" sizes="90vw"> <figcaption id=figcap1>original caption</figcaption> </figure> </div>
JavaScript
const img1 = document.getElementById("img1"); const figcap1 = document.getElementById("figcap1"); const button1 = document.getElementById("button1"); function reload () { function onLoad (e) { const target = e.currentTarget; console.log(`loaded width=${target.width} naturalWidth=${target.naturalWidth}`); figcap1.innerHTML = `loaded width=${target.width} naturalWidth=${target.naturalWidth}`; target.maxWidth = target.naturalWidth; } console.log("reloaded"); img1.addEventListener('load', onLoad, { once: true }); img1.src = "https://picsum.photos/300/150?random=2"; } button1.addEventListener('click', reload); button1.click();
问题原因与解决方法
核心问题
你直接修改img.src的操作会绕过srcset的选择逻辑,浏览器只会加载你指定的300/150尺寸图片,而这张图的显示尺寸被容器(90vw)限制,导致naturalWidth看起来和容器宽度一致——实际上是因为你加载的就是小图,它的真实自然宽度就是300px,和容器宽度刚好匹配而已。
解决步骤
- 更新srcset而非直接修改src:要让浏览器重新执行srcset选择逻辑,需要更新
img.srcset属性,替换其中的图片URL(保持宽度描述符不变),而不是直接改src。 - 触发图片重新加载:更新srcset后,浏览器不会自动重新选择,需要手动触发——可以调用
img.load()方法。
修改后的JavaScript代码示例:
const img1 = document.getElementById("img1"); const figcap1 = document.getElementById("figcap1"); const button1 = document.getElementById("button1"); function reload () { function onLoad (e) { const target = e.currentTarget; console.log(`loaded width=${target.width} naturalWidth=${target.naturalWidth}`); figcap1.innerHTML = `loaded width=${target.width} naturalWidth=${target.naturalWidth}`; target.style.maxWidth = `${target.naturalWidth}px`; // 修正:通过style设置max-width } console.log("reloaded"); img1.addEventListener('load', onLoad, { once: true }); // 更新srcset,替换所有图片URL为带随机参数的版本 img1.srcset = `https://picsum.photos/600/300?random=2 600w, https://picsum.photos/400/200?random=2 400w, https://picsum.photos/200/100?random=2 200w`; // 触发重新加载 img1.load(); } button1.addEventListener('click', reload); button1.click();
额外说明
naturalWidth本身就是图片的真实像素宽度,问题出在你没有让浏览器通过srcset选择合适的图片,而是强制加载了固定尺寸的小图。- 原代码里的
target.maxWidth = target.naturalWidth是错误写法,应该通过style.maxWidth来设置CSS样式。
内容的提问来源于stack exchange,提问作者Chris Dennis
相关产品推荐
相关产品推荐

