JavaScript : 画像ビューワ : Ver.1.00 (getElementsByClassName)
2013.09.26
jQueryプラグインの Lightbox を導入すれば手っ取り早いのですが、自分のサイトに合わせてカスタマイズしようとすると結構敷居が高いのも事実で・・・
もっと簡単に画像ビューワ(拡大表示)が出来ないものかとネットを漁ってみたのですが、どれもイマイチしっくりこないので自分でコードを書いてみました。
参考にさせて頂いたサイト ・・・ A Cool CSS Effect - Dashboard (英語)
上記のサイトのコードは、1ヶ所のリンク、もしくは1枚のサムネイル画像に対して1枚の拡大画像(1:1)となっており、複数の画像を表示する画像ギャラリー形式のページでそのまま使うにはコードが冗長的になってしまいます。また、各ブラウザに依存したCSSのアルファ効果(opacity等)も使われているので、汎用性についても制限があります。(後述)
なので、このコードを元にしてゴニョゴニョと・・・
画像送りやズーム表示する際のアニメーション効果、プログレスバーなど凝ったギミックはありませんが、その分軽くて jQuery も必要としないので導入やメンテ、改造も簡単だと思います。
基本的にサイトの単独ページ向けに作ったのですが、単純なコードなので一工夫すれば WordPress などのCMSにも組み込みやすいと思います。(流石にある程度のスキルは必要ですが…)
表示可能な画像形式はブラウザに依存しますが、逆にブラウザが対応している画像であれば全て表示可能です。
ただし、このバージョン(Ver.1.0)では画像の保存先(呼び出し先)にJPEG画像とPNG画像が混在している場合など、表示可能な画像形式はどれか1つの形式に限られます。
しかし、それもPHPなどのSSIでサムネイル画像部分のHTMLを生成し、JavaScriptに渡すパラメータをサムネイルの画像形式に合わせて変化させれば解決できます。
今回はPHPのコードまで説明すると長くなるので、通常の HTML + CSS + JavaScript に絞って紹介したいと思います。
処理の流れ
大まかな処理の流れは以下のようになります。
- サムネイル画像をdivでマークアップ。
- サムネイル画像(div要素)の onclick で block 化実行。同時にパラメータ(画像番号)をJavaScriptに投げる
- 受け取った画像番号を元にオリジナルサイズの画像を呼び出し
- 非表示のdiv要素(id="imglay")に呼び出した画像をアタッチ
- 非表示のdiv要素を表示
サムネイル画像をdivでマークアップする作業を手打ちで行うか…?、それともPHPを使って自動化するか…?
画像枚数が少なければ手打ちでも良いのですが、10枚以上の画像を処理するとなるとPHPで自動化した方が現実的かもしれません。
imgv_100_sample.html : CODE
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Lightbox風 画像ビューワ : Ver.1.00 </title> <style> .img_thm{ display: inline; margin: 5px; } #imglay { text-align: center; display: none; position: absolute; width: 100%; z-index:100; background-image: url(img/img_bak64.png); //背景透過PNG画像指定 background-repeat: repeat; background-position: center top; padding-top: 30px; padding-bottom: 30px; overflow: auto; left: 0px; top: 0px; } #imglay p { color: #FFFFFF; text-align: center; width: 100%; } #imglay img { /*opacity: 1.0; /* Safari, Opera */ //今回は未使用 /*-moz-opacity:1.0; /* FireFox */ /*filter: alpha(opacity=100); /* IE */ border: 20px solid #FFFFFF; overflow: auto; } #imglay #img_close { //CLOSEボタン領域 width: 100%; } #imglay #img_close a { text-decoration: none; width: 120px; padding-top: 15px; padding-bottom: 15px; margin-right: auto; margin-left: auto; display: block; } #imglay #img_close img { border: none; } </style> </head> <body> <div class="img_thm" onclick="return Simg('01');"> <img src="img/sample/s01.jpg" width="200" height="150" alt="Flashlight"> </div> <div class="img_thm" onclick="return Simg('03');"> <img src="img/sample/s03.jpg" width="200" height="150" alt="Flashlight"> </div> <div class="img_thm" onclick="return Simg('07');"> <img src="img/sample/s07.jpg" width="200" height="150" alt="Flashlight"> </div> <div id="imglay"> <p>UltraFire C1</p> <div onclick="return Limg()"><img id="img_view" src=""></div> <div id="img_close"> <a href="javascript:void(0)" onclick="return Limg()"> <img src="img/close.png" alt="CLOSE"></a> </div> </div> <script;> function Simg(n){ document.getElementById('imglay').style.display='block'; /*var img_dir = 'http://hoge/img/img_file';*/ var img_dir = 'img/sample/'; //画像ファイルのパス var img_num = n; //連番画像の番号:画像ファイル名 var img_ext = '.jpg'; //拡張子:JPEG画像 document.getElementById('img_view').src = img_dir + img_num + img_ext; } function Limg(){ document.getElementById('imglay').style.display='none'; } </script> </body> </html>
解説・注意点
コードを書く際にアレだった点など・・・(´・ω・`)
非表示の div要素(CSS)
#imglay { ~ display: none; position: absolute; width: 100%; z-index:100; background-image: url(img/img_bak64.png); //背景透過PNG画像指定 ~ }
拡大画像の表示エリアに関するCSSですが、 display: none; とする事で通常は非表示となります。
position: absolute; は表示エリアサイズ・座標の絶対表示、z-index:100; で重ね順を指定しています。
画像以外の背景部分を半透明にしたいので透過PNG画像を使っていますが、これはCSSのアルファ値プロパティを設定すると関連するdiv要素直下に含まれる全ての要素が半透明になってしまうのを回避する為です。
画像部分を別のdivで括っても親要素に対してネスト(子要素)されている場合は半透明の呪縛からは逃れられず、かといって全く別のdiv要素で拡大画像部分を配置するのもアレなので一番お手軽と思われる方法で済ませています。
半透明処理(opacity)
#imglay img {
/*opacity: 1.0; /* Safari, Opera */ //今回は未使用
/*-moz-opacity:1.0; /* FireFox */
/*filter: alpha(opacity=100); /* IE */
border: 20px solid #FFFFFF;
overflow: auto;
}
背景だけでなく、前景(拡大画像)まで半透明になってしまうので今回は未使用。前述の方法で表示エリアの背景を半透明としています。
onclick 指定
<div class="img_thm" onclick="return Simg('01');"> <img src="img/sample/s01.jpg" width="200" height="150" alt="Flashlight"> </div>
画像サムネイルのHTMLですが、onclick を使っているので<a>タグを使う必要は有りません。( onclick ならば、img要素だけでなくdiv要素の全域に対して有効)
しかし、このコードでは <a>タグを使っていないので、マウスカーソルが変化せずクリッカブルな要素か否かユーザーに伝わり難いという欠点があります。
<a>タグを使った場合に【 a href="javascript:void(0)" 】と、記述が長くなるのがアレなので短く記述するようにしていますが、どちらにするかはお好みで・・・(蛇足ですがマウスカーソルも CSS の cursor: で制御できます)
メインのJavaScriptに投げる部分は Simg( ) になりますが、パラメータ(引数)はサムネイル画像に対応したオリジナル画像の画像番号としています。このパラメータに拡張子や他の属性も含めれば拡大画像表示に必要な他の属性もコントロール可能となります。
JavaScriptだけでなくPHPも使って処理する場合も考え、便宜上ファイル名を連番としていますが、規則性の無いファイル名を扱う場合でも要領は同じです。
サムネイル画像は実体ファイルが必要となり常時表示する事になるので alt属性はきちんと設定した方が良いと思います。
非表示の div要素(HTML)
<div id="imglay"> //拡大画像表示エリア <p>UltraFire C1</p> //画像キャプション <div onclick="return Limg()"><img id="img_view" src=""></div> //src部分は空 <div id="img_close"> <a href="javascript:void(0)" onclick="return Limg()"> //拡大画像非表示(ボタン画像使用) <img src="img/close.png" alt="CLOSE"></a> </div> </div>
<div id="imglay"> が拡大画像の表示エリアとなります。
ただしこの部分は通常非表示となっており、サムネイル画像をクリックした時にのみ src 部分にオリジナル画像をセットし表示される仕組みです。
<p>タグの画像キャプションは固定となっていますが、この部分を画像に応じて可変にする場合や短い説明文(テキスト)を表示する場合などはPHPやデータベースと連動させた方が現実的かもしれません。
今回は <div id="imglay"> が表示されている場合にエリアのどこをクリックしてもビューワが閉じる仕様ですが、操作が判り易いように【閉じるボタン】などを配置した方が良いと思います。単に閉じる為のリンクを文字で記述しても良いのですが表示画面が単調になりがちなのでボタンを画像化してみました。
JavaScript 処理
<script> function Simg(n){ document.getElementById('imglay').style.display='block'; /*var img_dir = 'http://hoge/img/img_file';*/ var img_dir = 'img/sample/'; //画像ファイルのパス var img_num = n; //連番画像の番号:画像ファイル名 var img_ext = '.jpg'; //拡張子:JPEG画像 document.getElementById('img_view').src = img_dir + img_num + img_ext; } function Limg(){ document.getElementById('imglay').style.display='none'; } </script>
JavaScriptのメイン部分です。
function Simg(n) にサムネイルがクリックされた場合の処理を記述しています。
document.getElementById('imglay').style.display='block';
上記にて非表示にしていたエリア(div要素)を表示し、パラメータ(n)を元にしてオリジナル画像を呼び出しています。実際にレンタルサーバーのWEBページ内で使う場合はファイルのパス名をサイト構造に応じて書き換えて下さい。(うまく画像が呼び出せない場合は http://hoge/~ など絶対パスで指定)
function Limg() は画像ビューワを閉じる処理です。(非表示はCSSで設定)
今回はdiv要素全体を指定していますが、特定の要素のみを対象にする場合は、document.getElementById('***') でピンポイント指定する必要があります。
jQuery + 本家Lightbox を使えばお洒落な画像ビューワを実現出来ますが、どうせ一時の流行ですから・・・と、負け惜しみを言ってみる…(´・ω・`)