jQuery を使って簡単に Lightbox のようなモーダルウィンドウを表示する方法のメモ。
サムネイル画像の HTML
<p class="thumbnail"> <a href="images/photo_Large.jpg"> <img src="images/thumbnail_1.jpg" height="100" width="200" /> </a> </p>
モーダルウィンドウの HTML。
<div id="bg_layer"> <!--半透明の領域--> <!--/#bg_layer--></div> <div id="over_layer"> <!--拡大画像と「閉じる」ボタンを表示する領域--> <img class="lightboxlike" src="#" alt="" /><!--拡大画像--> <p class="close_button"><img src="images/close-trans.png"/></p> <!--/#over_layer--></div>
CSS
<style> html, body { margin: 0; padding: 0; height: 100%; } #bg_layer { display: none; position: fixed; top: 0; left: 0; height: 100%; width: 100%; background: #000; opacity: 0.60; filter: alpha(opacity=60); z-index: 10; } #over_layer { display: none; position: fixed; top: 50%; left: 50%; z-index: 15; } /*---IE6 対策---*/ * html #bg_layer { position: absolute; } /*---IE6 対策---*/ * html #over_layer { position: absolute; } p.close_button { display: none; position: absolute; top: -10px; right: -10px; cursor: pointer; z-index: 20; } </style>
jQuery
var full_size_height = 400; //拡大画像の高さ var full_size_width = 800; //拡大画像の幅 $('p.thumbnail a').click(function() { if($('#over_layer').css('display') == 'none') { $('#bg_layer').show(); $('#over_layer').css({ marginTop: '-' + full_size_height/2 + 'px', marginLeft: '-' + full_size_width/2 + 'px' }); $('img.lightboxlike').attr('src', $(this).attr('href')); $('#over_layer, p.close_button').show(); } return false; }); //非表示にする(閉じる)処理 $('#bg_layer, p.close_button').click(function() { $('#over_layer,#bg_layer ').hide(); }); //IE6 対策 if($.browser.msie && $.browser.version<7) { $(window).scroll(function() { $('#bg_layer').get(0).style.setExpression('top', "$(document).scrollTop()+'px'"); $('#over_layer').get(0).style.setExpression('top',"($(document).scrollTop()+$(window).height()/2)+'px'"); }); } [/code] <h3>スクロールされた場合元の位置に戻す</h3> 場合によってはモーダルウィンドウを表示中にスクロールをして、モーダルウィンドウを開いた位置から移動してしまい、それが問題になる場合は、以下のようにして元の位置に戻せる。 <ul> <li>モーダルウィンドウを開いた際に、その時点でのスクロールの値を取得して、data() を使って「#overlayer」にその値を保持。</li> <li>閉じる際に、その値とその時点での値が異なれば、animate() で元の位置にスクロールする。</li> <li>animate() でスクロールさせることができる要素が html か body かを判定する。</li> </ul>$('p.thumbnail a').click(function() { //その時点でのスクロールの値を取得 $('#overlayer').data('scroll_top', $(window).scrollTop()); if($('#over_layer').css('display') == 'none') { $('#bg_layer').show(); $('#over_layer').css({ marginTop: '-' + full_size_height/2 + 'px', marginLeft: '-' + full_size_width/2 + 'px' }); $('img.lightboxlike').attr('src', $(this).attr('href')); $('#over_layer, p.close_button').show(); } return false; }); // スクロールさせることができる要素が html か body かを判定 var isHtmlScrollable = (function(){ var html = $('html'), top = html.scrollTop(); var elm = $('<div/>').height(10000).prependTo('body'); html.scrollTop(10000); var rs = !!html.scrollTop(); html.scrollTop(top); elm.remove(); return rs; })(); //非表示にする(閉じる)処理 $('#bg_layer, p.close_button').click(function() { //値が異なれば、animate() で元の位置に戻す if($(window).scrollTop() != $('#overlayer').data('scroll_top')){ $(isHtmlScrollable ? 'html' : 'body').animate({ scrollTop: $('#overlayer').data('scroll_top') }, 500); } $('#over_layer,#bg_layer ').hide(); });
以下は、ウィンドウのサイズによって表示する画像の大きさを変える場合。
var full_size_height = 600; //拡大画像の高さ
var full_size_width = 400; //拡大画像の幅
$('p.thumbnail a').click(function() {
if($('#over_layer').css('display') == 'none') {
$('#bg_layer').show();
var wh = $(window).height(); //現在のウィンドウの高さを取得
if(full_size_height - (-30) > wh && wh){ //+30 だと文字列になるので「- (-30)」とする
var fixedHeight = wh * 0.87;
var fixedWidth = full_size_width * (fixedHeight / full_size_height);
$('#over_layer').css({
marginTop: '-' + fixedHeight/2 + 'px',
marginLeft: '-' + fixedWidth/2 + 'px'
});
$('img.lightboxlike').attr({src: $(this).attr('href'), height:fixedHeight, width:fixedWidth});
}else{
$('#over_layer').css({
marginTop: '-' + full_size_height/2 + 'px',
marginLeft: '-' + full_size_width/2 + 'px'
});
//高さと幅が変更されている可能性があるので、元の値に戻す
$('img.lightboxlike').attr({src: $(this).attr('href'), height:full_size_height, width:full_size_width});
}
$('#over_layer, p.close_button').show();
}
return false;
});
//非表示にする(閉じる)処理
$('#bg_layer, p.close_button').click(function() {
$('#over_layer,#bg_layer ').hide();
});
//IE6 対策
if($.browser.msie && $.browser.version<7) {
$(window).scroll(function() {
$('#bg_layer').get(0).style.setExpression('top', "$(document).scrollTop()+'px'");
$('#over_layer').get(0).style.setExpression('top',"($(document).scrollTop()+$(window).height()/2)+'px'");
});
}
[/code]
また、関数にしたほうが使いやすい場合は以下のようにすることも可能。
function show_modal_window(this$, img_width, img_height, my_options) {
//$.extendでパラメータをマージ
var settings = $.extend({
zoom_h: 0.87, //高さの縮小倍率
zoom_w: 0.9, //幅の縮小倍率
extra_h: 30, //高さを比較する際のマージン(ピクセル)
extra_w: 10, //幅を比較する際のマージン(ピクセル)
duration: 700, //アニメーション表示の速さ(ミリ秒)
over_layer: '#over_layer', //画像を表示する領域
background_layer:'#bg_layer', //背景を表示する領域
img_element: 'img.lightboxlike', //表示する画像要素
close_element: 'p.close_button' //閉じるボタンの要素
}, my_options || {});
if($(settings.over_layer).css('display') == 'none') {
var image_width = img_width;
var image_height = img_height;
$(settings.background_layer).show();
var wh = $(window).height();
var ww = $(window).width();
//画像の高さがウィンドウの高さより大きい場合
if(image_height - (-settings.extra_h) > wh && image_width - (-settings.extra_w) <= ww){
var fixedHeight = wh * settings.zoom_h;
var fixedWidth = image_width * (fixedHeight / image_height);
$(settings.over_layer).css({
marginTop: '-' + fixedHeight/2 + 'px',
marginLeft: '-' + fixedWidth/2 + 'px'
});
$(settings.img_element).attr({src: this$.attr('href'), height:fixedHeight, width:fixedWidth});
//画像の幅がウィンドウの幅より大きい場合
}else if(image_width - (-settings.extra_w) > ww && image_height - (-settings.extra_h) <= wh){
fixedWidth = ww * settings.zoom_w;
fixedHeight = image_height * (fixedWidth / image_width);
$(settings.over_layer).css({
marginTop: '-' + fixedHeight/2 + 'px',
marginLeft: '-' + fixedWidth/2 + 'px'
});
$(settings.img_element).attr({src: this$.attr('href'), height:fixedHeight, width:fixedWidth});
//画像の高さと幅がウィンドウの高さと幅より大きい場合
}else if(image_width - (-settings.extra_w) > ww && image_height - (-settings.extra_h) > wh){
if((image_width - (-settings.extra_w)) - ww > (image_height - (-settings.extra_h)) -wh) {
fixedWidth = ww * settings.zoom_w;
fixedHeight = image_height * (fixedWidth / image_width);
$(settings.over_layer).css({
marginTop: '-' + fixedHeight/2 + 'px',
marginLeft: '-' + fixedWidth/2 + 'px'
});
$(settings.img_element).attr({src: this$.attr('href'), height:fixedHeight, width:fixedWidth});
}else{
fixedHeight = wh * settings.zoom_h;
fixedWidth = image_width * (fixedHeight / image_height);
$(settings.over_layer).css({
marginTop: '-' + fixedHeight/2 + 'px',
marginLeft: '-' + fixedWidth/2 + 'px'
});
$(settings.img_element).attr({src: this$.attr('href'), height:fixedHeight, width:fixedWidth});
}
}else{
$(settings.over_layer).css({
marginTop: '-' + image_height/2 + 'px',
marginLeft: '-' + image_width/2 + 'px'
});
$(settings.img_element).attr({src: this$.attr('href'), height:image_height, width:image_width});
}
$(settings.over_layer + ',' + settings.close_element).fadeIn(settings.duration);
}
}
attachment_links$.click(function() {
show_modal_window( $(this), 400, 600, {duration: 500 }) ;
return false;
});
if($.browser.msie && $.browser.version<7) { $(window).scroll(function() { $('#bg_layer').get(0).style.setExpression('top', "$(document).scrollTop()+'px'"); $('#over_layer').get(0).style.setExpression('top',"($(document).scrollTop()+$(window).height()/2)+'px'"); }); } $('#bg_layer, p.close_button, p.close_overLayer').click(function() { $('#over_layer,#bg_layer ').fadeOut(500); }); [/code]