JavaScriptで<img>の元の大きさを取得する (naturalWidth/naturalHeight)
HTMLImageElement(<img>) のwidth/heightは、実際の表示サイズに引っ張られて値が変化する。(明示的に指定してても引っ張られる!)- 元の大きさを取得したければ
naturalWidth/naturalHeightを見る。
経緯と結論から
レスポンシブ対応してるサイト作ってて、レイアウトから画像がはみ出さないよう <img> に max-width:100% とか設定してたら、縮小されてる時に img.width に依存するJavaScriptがうまく動かなかった。
確認してみたところ、どうも HTMLImageElement の width/height には原寸ではなく実際の表示サイズがセットされてる模様。しかも、明示的に指定してても、必ず実際の表示サイズがセットされてるっぽい。
元の大きさを取得したければ、以下のように naturalWidth/naturalHeight を見る。
var img = document.getElementById('id-of-img');
console.log(img.naturalWidth);
console.log(img.naturalHeight);実験1: 普通に取得
↓の多幸感に溢れた画像は、原寸が 256 × 256 px。

この <img> タグの大きさを、以下のようにJavaScriptで取得する。
<img src="img.gif" alt="" id="img1" />var img = document.getElementById('img1');
console.log(img.width); // -> 256
console.log(img.height); // -> 256
console.log(img.naturalWidth); // -> 256
console.log(img.naturalHeight); // -> 256
console.log(img.style.width); // -> (カラ文字)
console.log(img.style.height); // -> (カラ文字)img の width/height および naturalWidth/naturalHeightは、もちろん 256。
style は設定していないので、img.style の width/height はカラ文字となり、取得できなかった。
実験2: 間接的に縮小して取得
↓の画像は、さっきと同じ画像。ただし <img> の外側のボックスをスタイルシートで 128 × 128px にしたうえで、<img> に style で max-width:100% を指定しているので、小さく表示されてる。

<img> に style で width/height を直接指定せず、遠回しに表示上のサイズを変えてるのがミソ。この <img> タグの大きさを、先程と同様にJavaScriptで取得する。
<div style="width:128px; height:128px;">
<img src="img.gif" alt="" id="img2" style="max-width:100%;" />
</div>var img = document.getElementById('img2');
console.log(img.width); // -> 128
console.log(img.height); // -> 128
console.log(img.naturalWidth); // -> 256
console.log(img.naturalHeight); // -> 256
console.log(img.style.width); // -> (カラ文字)
console.log(img.style.height); // -> (カラ文字)img の width/height が 128 となることに注目! 実際の表示サイズが反映されてる。
naturalWidth/naturalHeight なら元の大きさ 256 を取得できる。
実験3: 間接的に縮小&明示的に指定して取得
じゃあ <img> の width/height をHTML上で明示的に指定してたらどうなるの? というわけで、先程の条件に追記して実験。
<img>の外側のボックスをスタイルシートで 128 × 128px にする。<img>にstyleでmax-width:100%を指定する。<img>のwidth/heightに 200 を指定する。

ハチャメチャ。max-width のせいで縦長になっちゃってる。そしてこの <img> タグの大きさを、先程と同様にJavaScriptで取得すると……。
<div style="width:128px; height:128px;">
<img src="img.gif" alt="" id="img3" style="max-width:100%;" width="200" height="200" />
</div>var img = document.getElementById('img3');
console.log(img.width); // -> 128
console.log(img.height); // -> 200
console.log(img.naturalWidth); // -> 256
console.log(img.naturalHeight); // -> 256
console.log(img.style.width); // -> (カラ文字)
console.log(img.style.height); // -> (カラ文字)
console.log(img.getAttribute('width')); // -> "200"
console.log(img.getAttribute('height')); // -> "200"*明示的に指定したにも関わらず、img の width が 128 になってる。*ということは、HTMLImageElement の width/height には、本当に実際の表示サイズがセットされてるらしい。
一応、HTML上で明示的に設定した width/height も getAttribute() で取得できたけど、HTMLの <img> とJavaScriptの HTMLImageElement は同一視しないほうがよさそうだ。
キリウ君が読まないノート