JavaScriptで<img>の元の大きさを取得する (naturalWidth/naturalHeight)
HTMLImageElement
(<img>
) のwidth
/height
は、実際の表示サイズに引っ張られて値が変化する。(明示的に指定してても引っ張られる!)- 元の大きさを取得したければ
naturalWidth
/naturalHeight
を見る。
経緯と結論から
レスポンシブ対応してるサイト作ってて、レイアウトから画像がはみ出さないよう <img>
に max-width:100%
とか設定してたら、縮小されてる時に img.width
に依存するJavaScriptがうまく動かなかった。
確認してみたところ、どうも HTMLImageElement
の width
/height
には原寸ではなく実際の表示サイズがセットされてる模様。しかも、明示的に指定してても、必ず実際の表示サイズがセットされてるっぽい。
元の大きさを取得したければ、以下のように naturalWidth
/naturalHeight
を見る。
実験1: 普通に取得
↓の多幸感に溢れた画像は、原寸が 256 × 256 px。
この <img>
タグの大きさを、以下のようにJavaScriptで取得する。
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で取得する。
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で取得すると……。
*明示的に指定したにも関わらず、img
の width
が 128 になってる。*ということは、HTMLImageElement
の width
/height
には、本当に実際の表示サイズがセットされてるらしい。
一応、HTML上で明示的に設定した width
/height
も getAttribute()
で取得できたけど、HTMLの <img>
とJavaScriptの HTMLImageElement
は同一視しないほうがよさそうだ。