このページの本文へ

jQueryによるLightbox風モーダルウィンドウの作り方

2009年11月26日 13時00分更新

西畑一馬/to-R

  • この記事をはてなブックマークに追加
本文印刷

jQueryでモーダルウィンドウを作成する

 HTMLとCSSでモーダルウィンドウを表現する方法が分かったら、jQueryを使って、サムネイル画像がクリックされたらモーダルウィンドウを生成し、拡大画像を表示するスクリプトを作りましょう。

サムネイルがクリックされるとモーダルウィンドウが生成される
サムネイルがクリックされるとモーダルウィンドウが生成される

 HTMLは先ほどのサンプル01からglayLayerとoverLayerを取り除いたものです。サムネイル画像を包むa要素のhref属性にはモーダルウィンドウで表示したい拡大画像のパスを記述し、class属性に「modal」を設定します。

サンプル02(HTML部分)


<h1>jQueryを利用したモーダルウィンドウの作成</h1>
<ul>
    <li><a href="images/photo1.jpg" class="modal"><img src="images/photo1_thum.jpg" alt="シャンデリア" /></a></li>
    <li><a href="images/photo2.jpg" class="modal"><img src="images/photo2_thum.jpg" alt="バラ" /></a></li>
    <li><a href="images/photo3.jpg" class="modal"><img src="images/photo3_thum.jpg" alt="海" /></a></li>
    <li><a href="images/photo4.jpg" class="modal"><img src="images/photo4_thum.jpg" alt="門" /></a></li>
    <li><a href="images/photo5.jpg" class="modal"><img src="images/photo5_thum.jpg" alt="海" /></a></li>
    <li><a href="images/photo6.jpg" class="modal"><img src="images/photo6_thum.jpg" alt="あじさい" /></a></li>  <li><a href="images/photo7.jpg" class="modal"><img src="images/photo7_thum.jpg" alt="空" /></a></li>
    <li><a href="images/photo8.jpg" class="modal"><img src="images/photo8_thum.jpg" alt="建物" /></a></li>
</ul>


 CSSもサンプル01と同じですが、#glayLayerと#overLayerは初期状態では非表示になるようにdisplay:none;を追加しています。また、スターハック(関連記事)を利用してIE6の場合のみ、positionプロパティをabsoluteに変更しています。詳しくは後述しますが、IE6はposition:fixedに対応していないため、今回はjQueryで擬似的にposition:fixedを実現する方法を取ります。

サンプル02(CSS部分)


#glayLayer{
    display:none;
    position:fixed;
    (中略)
}
#overLayer{
    display:none;
    position:fixed;
    (中略)
}
* html #glayLayer{
    position:absolute;
}
* html #overLayer{
    position: absolute;
}


 スクリプト部分は次のようになります。

サンプル02(スクリプト部分)


$(function(){
    $("body").append("<div id='glayLayer'></div><div id='overLayer'></div>")
    
    $("#glayLayer").click(function(){
        $(this).hide()
        $("#overLayer").hide()
    })
    
    $("a.modal").click(function(){
        $("#glayLayer").show()
        $("#overLayer").show().html("<img src='"+$(this).attr("href")+"' />")
        return false;
    })
    
    if($.browser.msie && $.browser.version<7){
        $(window).scroll(function(){
            $("#glayLayer").css('top',$(document).scrollTop())
            $("#overLayer").css('top',($(document).scrollTop()+$(window).height()/2) +"px")
        })
    }
    
})


 スクリプトの2行目では、append()を使って(関連記事)、body要素の一番後ろに<div id='glayLayer'> </div> と <div id='overLayer'> </div>を追加します。


$("body").append("<div id='glayLayer'></div><div id='overLayer'></div>")


 続いて4行目では、#glayLayerにclick()イベントを設定し、モーダルウィンドウが開いている状態のときにウィンドウを閉じて元の状態に戻す処理を記述しています。#glayLayerがクリックされると、半透明レイヤー(galyLayer)と子ウィンドウ(overLayer)をhide()で非表示にします。


$("#glayLayer").click(function(){
    $(this).hide()
    $("#overLayer").hide()
})


 9行目では、class属性が「modal」のa要素に対してclick()イベントを設定しています。a要素がクリックされると#glayLayerと#overLayerをshow()で表示状態に変更し、html()を使って#overLayerにimg要素を挿入します(関連記事)。img要素のsrc属性にはa要素のhref属性から取り出した値を設定します。これで、サムネイルをクリックすると拡大画像を表示する処理が実現できました。


$("a.modal").click(function(){
    $("#glayLayer").show()
    $("#overLayer").show().html("<img src='"+$(this).attr("href")+"' />")
    return false;
})


 最後のブロック(15行目以降)は、IE6対策です。if文を使ってブラウザーがIE6の場合のみ処理を分岐させ(関連記事)、擬似的にposition:fixedを実現する処理を記述します。position:fixedはスクロールしても位置が変わらない絶対配置ですので、スクリプトで疑似的に実現するには、(1)Webページの中のどの位置を表示しているか、(2)ブラウザーがどのサイズで開かれているか――をスクロールが発生するたびに調べます。

sample4.jpg
スクロールイベントが発生した時点でのブラウザーの高さとページトップからの位置を調べる

 $(window).scroll(function(){...})は、ブラウザー上でのスクロール処理(スクロールイベント)を感知し、{...}内に記述された命令を実行する構文です。ページトップからの表示位置は $(document).scrollTop() で、ブラウザーの表示領域の高さは $(window).height()で取得できます。

 半透明レイヤー(#glayLayer)はCSSハックでIE6にのみposition:aboslute(絶対配置)を設定していましたので、スクロールイベントが発生するたびにページトップからの表示位置を取得してtopプロパティに設定すれば、position:fixedの場合と同様の結果が得られます。

 子ウィンドウ(#overLayer)も同様に、ページトップからの表示位置にブラウザーの表示領域の高さの半分を足すことにより、position:fixedのときのtop:50%と同じ位置に子ウィンドウを表示できます。


if($.browser.msie && $.browser.version<7){
    $(window).scroll(function(){
        $("#glayLayer").css('top',$(document).scrollTop())
        $("#overLayer").css('top',($(document).scrollTop()+$(window).height()/2) +"px")
    })
}


 以上で、サムネイル画像をクリックすると拡大画像を表示するモーダルウィンドウが完成しました。


【JavaScriptワンポイントレッスン 】

IE限定の「setExpression」を使う

 サンプル02ではIE6向けの処理として、$(window).scroll(function(){...}) で擬似的にposition:fixedを実現しました。ただ、スクロールイベントを使う方法はスクロール後に座標を移動させているため、どうしてもチラツキが発生してしまいます。

 そこで、IE独自の「setExpression」という命令を使って問題を回避する方法を紹介しましょう。setExpressionはIE5~IE7のみで利用できるJavaScriptの命令で、ブラウザーがWebページを描画するタイミングで指定したJavaScriptを実行します。

 たとえば以下のように記述すると、$(document).scrollTop()+'px' の結果を#glayLayerのtopプロパティに設定できます。get(0)はjQueryで取得した要素にJavaScriptで記述した処理を適用する命令です。


$("#glayLayer").get(0).style.setExpression("top","$(document).scrollTop()+'px'")


 サンプル02のIE6対策の部分を次のように変更することにより、setExpressionを使ったposition:fixedを実現できます。

サンプル03(スクリプト部分)


if($.browser.msie && $.browser.version<7){
    $(window).scroll(function(){
        $("#glayLayer").get(0).style.setExpression("top","$(document).scrollTop()+'px'")
        $("#overLayer").get(0).style.setExpression("top","($(document).scrollTop()+$(window).height()/2)+'px'")
    })
}


 残念ながらチラツキが完全になくなるわけではありませんが、スクロールイベントを使った方法に比べて格段にスムーズに表示されるようになります。

Web Professionalトップページバナー

この記事の編集者は以下の記事をオススメしています

ASCII.jp会員サービス 週刊Web Professional登録

Webディレクター江口明日香が行く