画像が縦長か横長か調べて自動でクラス名をつけるJavaScript

うちでよく読んでもらっているページに「絶対はみ出さない画像!自動でサイズ調節するスタイルシート」というのがあるんですが、これに関連したことで質問を受けました。

「スマホで見ても、すべての画像が横幅いっぱいになって、はみ出さなくなったんですが、縦長の写真だけサイズを変えられないか」という内容です。

画像が横長なのか、縦長なのか、正方形なのかで分けて、それぞれクラス名をつければいいんですが、もうすでに大量のページがある場合は全ページを修正しなくてはいけないし、そうでないとしても毎回画像毎にクラス名を割り当てるのは大変です。

そこで、自動でクラス名を追加するJavaScriptを書いてみました。

画像のサイズを調べてクラス名を割り当てるJavaScript

今回、参考になったのは次のページです。これが非常に素晴らしい内容で、作業がとても簡単になりました。ありがとうございます。

[JavaScript] 画像のオリジナル サイズを取得する 最もシンプルな方法 – こじょらぼ

で、実際に作ったソースはこんなカンジです。HTMLのどこに追加しても動きますが、<head> 部分の終わりにある「</head> の直前」につけるのがいいと思います。

<script>
(function(){
	function image_class(){
		var img = new Image();
		var images = document.querySelectorAll('img');

		for(var i=0;i<images.length;i++){
			img.src = images[i].src;

			if(img.width < img.height){
				images[i].className += ' vertically_long';
				images[i].parentNode.className += ' vertically_long_outer';
			}else if(img.width > img.height){
				images[i].className += ' horizontally_long';
				images[i].parentNode.className += ' horizontally_long_outer';
			}else{
				images[i].className += ' square';
				images[i].parentNode.className += ' square_outer';
			}
		}
	}

	if(window.addEventListener){
		window.addEventListener('load', image_class, false);
	}else if(window.attachEvent){
		window.attachEvent('onload', image_class);
	}
})();
</script>

これでページ読み込み完了後
縦長の画像には vertically_long というクラス名が
横長の画像には horizontally_long というクラス名が
正方形には square というクラス名が追加されます。

さらに
vertically_long の親ノードには vertically_long_outer
horizontally_long の親ノードには horizontally_long_outer
square の親ノードには square_outer
というクラス名が追加されます。

このクラス名毎にスマホ専用スタイルシートを書けば、好きなように表示を変えられます。

ただ、お気づきかと思いますが同じ親ノードの中に、縦長と横長の両方の画像があった場合、両方のクラス名が親ノードに追加されるので、その部分は思ったように表示されないと思います。

サンプルページ

このスクリプトを適用していない場合と、適用した場合のサンプルページを用意しました。2つのページの違いはスクリプトをつけているか、いないかだけです。

スマホで見ても絶対にはみ出しませんが、スクリプトを適用したページだけ、縦長と正方形の表示が変わります。

スクリプトを適用していない場合
http://dwm.me/download/vertical_and_horizontal_ratio_js_sample_1.html
スクリプトを適用した場合
http://dwm.me/download/vertical_and_horizontal_ratio_js_sample_2.html

サンプルページのスタイルシートは次のようになっています。

<style type="text/css">

/* これで画像は絶対にはみ出さない */
img {
	max-width: 100%;
	height: auto;
}

/* 縦長の画像を真ん中に配置する */
.vertically_long_outer {
	text-align: center;
}

/* 縦長の画像のサイズを横幅120ピクセルに固定 */
/* 高さは自動で調整 */
.vertically_long {
	width: 120px;
	height: auto;
}

/* 正方形の画像を右寄せで配置 */
.square_outer {
	text-align: right;
}

/* 正方形画像の高さを200ピクセル、幅も200ピクセルに固定 */
.square {
	width: 200px;
	height: 200px;
}

</style>

真ん中合わせにしたいのに、左寄せになってしまう場合は下のように変更してください。

変更前

.vertically_long {
	width: 120px;
	height: auto;
}

変更後

.vertically_long {
	width: 120px;
	height: auto;
	/*2行追加*/
	margin-left: auto;
	margin-right: auto;
}

2015年1月9日追記:今年になってSeesaaブログでの表示で縦の長さが固定されてしまい、表示がおかしくなったというご指摘がありました。その場合は width と height に !important を追加してください。


height: auto !important;

今後更に変更される場合があるので、width と height 以外もすべて !important を追加してもいいかもしれません。

これを、ページの本文にだけ適用させたくて、サイドバーなどそれ以外の部分には影響を与えたくない場合があると思います。

例えばSeesaaブログなら各ページの本文は #content .text の中にあるので、それをスタイルシートに追加してください。(同じSeesaaブログでも構成の違うテンプレートがあるようです。詳しくはコメント欄を参照してください。)

具体的に言うとこんなカンジになります。

<style type="text/css">

#content .text img {
	max-width: 100%;
	height: auto;
}

#content .text .vertically_long_outer {
	text-align: center;
}

〜〜以下省略〜〜

“画像が縦長か横長か調べて自動でクラス名をつけるJavaScript” への15件の返信

  1. すみません。
    うまく反映できません。
    上部のスクリプトをデザイン-スマートフォン-コンテンツで自由形式に貼り付け追加しました。
    デザイン-スマートフォン-デザイン一覧から使用している[photo]というデザインを選び、をスタイルシートの一番下に追加してみました。
    間違ってますか?

    1. ぼぶさん。「ぼぶのラーメン紀行」と「くいどうらく日記」を見てみました。

      現状は「ぼぶのラーメン紀行」にはスクリプトのみ貼り付け中。追加したスタイルシートは元に戻して外してある。「くいどうらく日記」の方はスクリプトもスタイルシートも両方つけていない。ということであっているでしょうか。

      原因ですが「ぼぶのラーメン紀行」と「くいどうらく日記」では、テンプレートの構成が違うようです。

      上の本文中に書いてある、スタイルシートの #content .text というのは「くいどうらく日記」には、そのまま当てはまります。ですから「くいどうらく日記」に適用する場合は、そのままで行けると思います。

      ですが「ぼぶのラーメン紀行」のテンプレートは最近出来た新しいタイプのようで違う構成になっていました。

      「ぼぶのラーメン紀行」の場合は、前につける「#content .text」を「.article-body」に変更してください。(article-bodyの前にはドットが必要です)

      具体的には次の通りのスタイルシートで本文中にある、縦長の画像だけ横幅120ピクセルで中央配置になります。

      img {
      max-width: 100%;
      height: auto;
      }

      .article-body .vertically_long_outer {
      text-align: center;
      }

      .article-body .vertically_long {
      width: 120px;
      height: auto;
      }

      サイズは width: 120px; の数字を変えれば変更できます。

      text-align: center; を text-align: right; にすれば、右寄せに、text-align: left; にすれば左寄せになります。

      seesaaブログの デザイン> スマートフォン> デザイン一覧 でスマホのスタイルシートを編集できますが、右上に「 ページ : トップ | 記事 」という項目があります。

      Seesaaブログ編集画面

      写真があるのは「記事」だけなので、「記事」のスタイルシートの最後に追加してください。その場合は <style type=”text/css”> と </style> はいりません。

  2. お世話になります。
    ラーメン紀行・・・指示通りにやったつもりですが、スマートフォンでは縦長画像は100%幅表示のままです。
    くどうらく・・・PCの表示がおかしくなってしまいました。これまで使っていたデザインを初期値にもどしても、ほかのデザインを使ってもサムネイル画像もすべて100%表示になってしまいました。
    もう頭がこんがらかってきました。

  3. その後ゆっくりやってみたところ、ラーメン紀行の方は当初の目的は達成したと思います。
    大変ありがとうございました。

    ただ、くいどうらくの方はスマホの専用ページが、一覧は出ますが記事そのものが全く表示されなくなってしまいました。
    改良を施してはもどし、していたので原因がわかりません。
    デザインを新しいものに変えてもだめでした。

  4. 「くいどうらく日記」について

    理由はわかりませんがスマホ版はHTMLそのものがおかしくなっています。
    PC版は正常なので、配置したパーツに原因があるのかもしれません。

    デザイン> スマートフォン> コンテンツ の「記事」を一旦捨てて
    同じ場所に新しい「記事」を配置してみてください。

    それで直らなければシーサーのサポートに問い合わせてください。私にはわかりません。
    http://www.seesaa.co.jp/pages/enq/input.pl?enq=2

    写真のレイアウトについてですが「くいどうらく日記」に関しては直ったページを見ないことには回答できません。

    ##############################################################

    「ラーメン紀行」について

    写真レイアウトのスクリプトはうまく動いているようです。
    ただひとつ、スタイルシートで真ん中合わせの指定が効いていませんでした。

    理由はスマホ版テンプレートが予想していなかったHTMLに変更されていたからです。

    今のままで問題がなければ直す必要はありませんが、
    もし縦長写真を真ん中合わせにしたい場合は次のようにスタイルシートを変更してください。
    (120は自分の数字に直してください)

    変更前
    .vertically_long {
        width: 120px;
        height: auto;
    }

    変更後
    .vertically_long {
        width: 120px;
        height: auto;

        /*2行追加*/
        margin-left: auto;
        margin-right: auto;
    }

    これで縦長写真は真ん中合わせになりますが、左合わせが良ければ今のままで構いません。

  5. くいどうらく
    ご支持通りにやりましたが、変わりません。
    それよりデザインを変えるように設定してもデザインすら変わらないようになってしまいました。
    サポートにも聞いている最中です。

    ラーメン紀行
    こちらは今のままで満足です。
    本当にありがとうございました。

  6. くいどうらくの方ですが、コンテンツの「記事」を配置するところが間違っていました。
    正しい場所に移したら表示はされるようになりました。
    すみませんでした。
    しかしながら、横長の写真が相変わらずはみ出ます。。。

    ラーメン紀行もちょっとその後ゴタゴタしましたが、
    思い通りになっています。

    1. まず、くいどうらく日記に貼りつけたスタイルシートですが、先のコメントに書いた通り
      最初の <style type=”text/css”> と、最後の </style>つけないでください。

      それで、正しく表示されると思います。
      ただ、今お書きになっているスタイルシートのままですと
      次のように本文以外の画像表示がおかしくなります。

      これもこのページの本文に書いてある通り
      #content .text の追加で直ります。

      img {
      	max-width: 100%;
      	height: auto;
      }

      ではなく

      #content .text img {
      	max-width: 100%;
      	height: auto;
      }

      です。


      ただ、今後テンプレートを変更する可能性を考えると次のようにした方が無難です。
      このままコピペしてください。

      #content .text img, .article-body img {
      	max-width: 100%;
      	height: auto;
      }

      現在のテンプレートでは .article-body img は効いていませんが、
      他のテンプレートでは反対に .article-body img が効いて #content .text img が効かなくなる事が考えられます。

      効かない部分はあっても無害ですので、両方入れておけば後でわからなくならないと思います。

  7. ありがとうございました。
    テンプレートを変えてみました。
    うまく動作していると思います。
    今回はいろいろとご親切にありがとうございました。
    感謝します。

  8. すみません。
    スマホの方の表示がまたおかしくなっています。
    ラーメン紀行、くいどうらく、両方ともです。
    あれ以後、何もいじっていません。
    横ははみ出ないのですが、縦がびよーんと伸びています。
    原因と対処方はありますでしょうか。

    1. ぼぶさん、返事が遅くなりました。

      今、ぼぶさんのブログを見てみましたが、写真の横のサイズは縮小されているのに、縦のサイズは縮小されずに元のままになっています。その結果、縦に長くなって見えます。Seesaaブログのシステムか、お使いのテンプレートがバージョンアップされたのかもしれません。

      対応方法ですが、追加したスタイルシートの width と height に !important を追加します。具体的には以下の通り。

      [ぼぶのラーメン紀行]

      img {
      max-width: 100% !important;
      height: auto !important;
      }
      .article-body .vertically_long_outer {
      text-align: center;
      }
      .article-body .vertically_long {
      width: 240px !important;
      height: auto !important;
      }

      [くいどうらく日記]

      /* これで画像は絶対にはみ出さない */
      #content .text img, .article-body img {
      	max-width: 100% !important;
      	height: auto !important;
      }
      
      /* 縦長の画像を真ん中に配置する */
      .vertically_long_outer {
      	text-align: center;
      }
      
      /* 縦長の画像のサイズを横幅240ピクセルに固定 */
      /* 高さは自動で調整 */
      .vertically_long {
      	width: 240px !important;
      	height: auto !important;
      }
      
      .square_outer {
      	text-align: right;
      }
      
      /* 正方形画像の高さを200ピクセル、幅も200ピクセルに固定 */
      .square {
      	width: 200px !important;
      	height: 200px !important;
      }

      こうすれば直りますが、1点注意があります。
      くいどうらく日記のスタイルシートにある次の部分2ヵ所

      /* 正outer {

      }方形の画像を右寄せで配置 */
      .square_

      これは、ぼぶさんが貼りそこなって残っている部分です。この青文字部分があると誤作動しますので削除してください。

      上の内容をコピーして、丸ごと差し替えれば大丈夫ですが消さずに書き替える場合はこうします。

      /* 正outer {
       ⇓
      .square_outer {

      }方形の画像を右寄せで配置 */
      .square_

       ⇓
      }

  9. ありがとうございます!
    くいどうらくの方は治りましたが、ラーメン紀行の方は治りません。。。
    縦長の画像も枠いっぱいに表示されてしまいます。。。

    1. 両方のブログで縦長の写真は縮小されて余白があるように見えますが、具体的にどのページでしょう?
      また、ご覧になっているスマホはアンドロイドとiPhoneのどちらでしょうか?

  10. アンドロイドですが、今日見たら思う通りの表示になっていました。
    キャッシュの問題でしょうか。
    お騒がせしました、
    ありがとうございました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です