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

如何获取通过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,和容器宽度刚好匹配而已。

解决步骤

  1. 更新srcset而非直接修改src:要让浏览器重新执行srcset选择逻辑,需要更新img.srcset属性,替换其中的图片URL(保持宽度描述符不变),而不是直接改src。
  2. 触发图片重新加载:更新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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 07:45:29