画像が縦長か横長か調べて自動でクラス名をつける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;
}

〜〜以下省略〜〜