Note: この記事は、3年以上前に書かれています。Webの進化は速い!情報の正確性は自己責任で判断してください。
前回つくったスクリプトをベースに、普通にブログで使えるようにちょこちょこカスタムしてみた。次から当サイトで使います。変更点は以下。
- 対象ブロックを class名 にて特定するようにした。
- 拡大画像が挿入される位置を選択できるようにした。
- 拡大画像をJavaScriptで生成するようにした。
つまり、記事一覧で複数表示されても動作し、拡大画像の挿入位置をCSSの都合で選べて、JS無効環境では単純なサムネールの画像リンクになる。
HTML
<div class="showcase">
<p>
<a href="m01.jpg" title="コメント1"><img src="s01.jpg" alt="" /></a>
<a href="m02.jpg" title="コメント2"><img src="s02.jpg" alt="" /></a>
<a href="m03.jpg" title="コメント3"><img src="s03.jpg" alt="" /></a>
<a href="m04.jpg" title="コメント4"><img src="s04.jpg" alt="" /></a>
<a href="m05.jpg" title="コメント5"><img src="s05.jpg" alt="" /></a>
</p>
</div>
HTML部分。特に何の変哲も無い、画像リンクが並ぶだけの構成。
JavaScript
var showcase = {
init: function(cname,pos){
var wrap = this.getElementsByClass(cname);
for(var i=0; i<wrap.length; i++){
this.setup(wrap[i],pos);
}
},
setup: function(wrap,pos){
var links = wrap.getElementsByTagName('a');
var bigWrap = document.createElement('p');
var bigImg = new Image();
var text = document.createTextNode(links[0].title);
if(pos == 'before'){
var thumb = wrap.getElementsByTagName('p')[0];
wrap.removeChild(thumb);
wrap.appendChild(bigWrap);
wrap.appendChild(thumb);
} else {
wrap.appendChild(bigWrap);
};
bigWrap.className = "bigImg";
bigImg.src = links[0].href;
bigWrap.appendChild(bigImg);
bigWrap.appendChild(text);
for(var i=0; i<links.length; i++) {
var thumb = new Image();
thumb.src = links[i].href;
links[i].onclick = function(){
showcase.showImg(this,bigImg,text);
return false;
};
}
},
showImg: function(elm,bigImg,text){
bigImg.src = elm.href;
text.nodeValue = elm.title;
},
getElementsByClass: function(searchClass) {
var classElements = new Array();
var els = document.getElementsByTagName('div');
var pattern = new RegExp('(^|\\s)'+searchClass+'(\\s|$)');
for (i = 0, j = 0; i < els.length; i++) {
if ( pattern.test(els[i].className) ) {
classElements[j] = els[i];
j++;
}
}
return classElements;
}
}
window.onload = function(){showcase.init('showcase','before')};
ちょっと長くなった。変更点は3つ。
init() の分割と、bigImgの生成/挿入処理の追加、あと getElementsByClass() メソッドの追加。順を追って軽く解説していきます。
まずinit()の分割。これは複数表示したときの変数のスコープの問題で、しょうがなかった。具体的には画像切替の段階で、複数のショーケースを設置していても、最後に生成された bigImg しか切り替わらない状態になっていた。これはJavaScriptにおいて、変数のスコープは宣言された関数の中に限定されるため。したがって init() の中でfor文を回すのではなく、init() にて showcase の数だけ setup() を実行するカタチになっている。いま思えば匿名関数で括っても良かったのかもだけど、結果的には、起動部と実行部が分離された今の状態のほうがよりスマート。
bigImgの生成/挿入に関しては、特に言うべきことはないかな。タグをひとつずつ生成して突っ込んで行ってるだけ。15~22行がbigImgの挿入場所を決める分岐処理。包括ブロックがもうちょい複雑なら InsertAdjacent を使ったほうが良いかもしれない。今はコレで十分。LightBoxっぽくするかどうかはCSSで決めれば良い。このままでもやろうと思えばできる。まあその場合はDocument直下に突っ込んだほうが設定はしやすいだろうけど。好きに料理してください。
getElementsByClass() は... まあ別に良いよね? 今回はパッケージ化の問題でshowcaseオブジェクトに含めてるけど、自前のが既にあるならソレ使っても問題ない。まあ捜索対象のノードとタグは、下手打てば負荷増になるから環境に合わせてチェックはしたほうが良いかもね、てくらいかな。
Note: スパム対策が面倒なので、コメント投稿を廃止しました。以前のコメントは残します。
ご意見・ご要望はtwitter@sigwygかはてブコメントにて。