【追記】この記事をポストした後にもう少しよい方法が見つかったので次の記事を参照してください。
jQuery/JavaScriptによる画像リサイズ その2
JavaScriptとjQueryを使って、だいたいのブラウザで動作する画像をリサイズする方法をいろいろ試していた。
Firefoxだと画像の幅が取得できないということはないけど、リサイズが効く前に画像が表示され画像が一瞬大きく表示されてしまう。
若干気持ち悪さは残るが、今のところ表示時に”display: none”で対応するのがよさそう。
一瞬画像が大きく表示されてしまうのは避けたいということと、ブラウザ毎の条件分岐はあまりしたくないというところを条件に作ってみた。
確認ブラウザ
手元にあった次の環境で動作を確認している。
■Mac
Firefox 17.0.1
Chrome 23.0.1271.95
Safari 6.0.2
■Windows
IE7, IE8, IE9 (IE7, 8は開発ツールで確認)
Firefox 17.0.1
Chrome 23.0.1271.95 m
Safari 5.1.7
コード
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<script src="jquery-1.8.3.min.js"></script>
<script>
function resize(obj, size){
  var ratio = obj.width / obj.height;
  if ( obj.width < size && obj.height < size ) {
    return;
  }
  if ( obj.width > obj.height ) {
    obj.width  = size;
    obj.height = size / ratio;
  } else {
    obj.width  = size * ratio;
    obj.height = size;
  }
}
$(function(){
  $('.resize').each(function(){
    this.src = this.src + '?' + new Date().getTime();
  }).load(function(){
    var maxSize = 200;
    $(this).css('display', 'inline');
    resize(this, maxSize);
  })
});
</script>
<style>
.resize {
  display: none;
}
</style>
<title>jQueryによる画像リサイズ</title>
</head>
<body>
<img class="resize" src="images/sample.jpg">
<img class="resize" src="images/sample2.jpg">
<img class="resize" src="images/sample3.jpg">
<img class="resize" src="images/sample4.jpg">
</body>
</html>
解説
画像の縦横の最大サイズを200pxで設定している。最大サイズに満たない画像はそのまま表示している。
表示時に画像は非表示
一瞬画像が大きくなることを防ぐため、画像には”resize”というclassを指定し、styleで”display: none”にあらかじめ設定している。
IEのキャッシュ対策
画像がonload時にリサイズをするようにしているけど、IEの場合はキャッシュした画像にはonloadが実行されない。。。
ということで、キャッシュ対策として時間をパラメータに与えて対策。
IMG要素のonloadイベントがIE系でうまくいかないときの対処 | Blog | Keyframe Worldwide
this.src = this.src + '?' + new Date().getTime();
IEではdisplay: noneでwidth, heightが取得できない
実際のリサイズ前に”display: inline”に戻しているのは、IEでは”display: none”の状態では画像がロード済みでも、width, heightが0の値を返すからだ。
ここは結構ハマってしまった。
リサイズ前にdisplayを戻してしまっては一瞬画像が大きく表示されそうだが、私の目には実際の動作でそうはならなかったのでOKとしている。
$(this).css('display', 'inline');
resize(this, maxSize);
IEだと display:none にした画像の高さと幅が取れない | Azrael
画像のリサイズ
画像のリサイズ自体にはjQueryは使っていない。要素のwidth, heightを取得できることを前提にしている。
指定した画像サイズより縦も横も小さい場合はリサイズしない。
まとめ
IEはやっぱりハマりどころが多い。
サーバサイド側で画像サイズを考慮したり、サムネイル作ったりした方が良さそうな気もするけど、そこまではできないとか、サーバサイドに手を入れられないとか、手っ取り早くクライアント側で画像を特定の画像サイズで表示してほしいときにはちょうどよい方法なのではないだろうか。
あと、”display: none”を使用せずに、あまりブラウザ毎に条件分岐せずにうまくJavaScriptをリサイズできる方法があったら教えてください。
