F.Ko-Jiの「一秒後は未来」

jQueryのみでLightboxっぽいものを実現する方法

梅酒.inのトップページにある「梅酒がウリな飲食店」というコーナーにある画像をクリックすると、Lightboxっぽく情報を表示するようにしています。

umeshu-in-lightbox.gif

↑ こんな感じ。

Lightbox効果を実現するライブラリは検索すれば色々と見つかると思いますが、ここではライブラリはjQueryのみとして、どのようにLightboxを実現したかを説明します。

処理のおおまかな流れは以下の通りです。

  1. select要素を隠す (IE対策)
  2. ページ全体に半透明の黒いレイヤーを表示する
  3. 表示領域の中央に目的のコンテンツを表示する

1. select要素を隠す

IE6ではselect要素にz-indexが定義されていないため、レイヤーのz-indexをどれだけ大きくしても、IE6ではselect要素がレイヤーの下に隠れることはありません。そのため、ページ上にあるselect要素を隠す必要があります。

jQueryでは、

$('select').hide();

この一行だけでOKです。

2. ページ全体に半透明の黒いレイヤーを表示する

まず、レイヤー用のdiv要素を準備します。ここではidをoverlayとしてCSSを次のように記述しています。

#overlay {
    position: absolute;
    top: 0;
    left: 0;
    background: #000;
    z-index: 9999;
    filter: alpha(opacity=0);
    -moz-opacity: 0;
    opacity: 0;
    display: none;
}

透過を0、背景色を黒、配置を(0, 0)にして、display: noneで隠しておきます。レイヤーの高さと幅はブラウザにあわせて変更したいので、ここでは定義していません。div#overlay要素自体は邪魔にならないように</body>の直前あたりに置いておきます。

次に、Lightboxを実行させたい要素に onclick で実行する関数を指定しておきます。

実行する関数の内容はおおまかに次のようになります。

  • レイヤーの高さと幅を決定
  • jQueryのfadeToメソッドでレイヤーをアニメーション表示
var height = $('body:first').height();
var width = document.documentElement.clientWidth;
$('#overlay').height(height).width(width).show().fadeTo(500, 0.8, function() {
    // ここにレイヤー表示後の処理を記述
}

レイヤーの高さは bodyタグの height を取得してセットしています。幅ははブラウザの表示領域幅のサイズを取得しています。bodyタグの幅が元々100%であれば、bodyタグの幅を取得して構いません。

これでブラウザをどれだけスクロールしても、画面全体に半透明の黒いレイヤーが表示されている状態になります。

3. 表示領域の中央に目的のコンテンツを表示する

最後に目的のコンテンツを表示領域の中央に表示させます。そのためには、ブラウザがスクロールしている場合も考慮して、表示位置を決定する必要があります。

まず、目的のコンテンツを表示させるためのdivタグを div#layer_info として、CSSは次のように記述しておきます。

#layer_info {
    display: none;
    z-index: 10000;
    position: absolute;
    background: #fff;
    width: 780px;
    height: 460px;
}

ポイントは以下の3項目です。

  • z-indexが先ほどのレイヤーより大きいこと
  • positionがabsoluteであること
  • display: noneで隠しておくこと

次に #layer_info を表示させる位置を計算します。ブラウザのスクロール位置の取得について、IEとFirefoxは同じだったのですが、Safariでは違っていたので、Safariかどうかで処理を分けています。

if (navigator.userAgent.match(/AppleWebKit\/\d.+Safari\/\d.+/)) {
    var scrollTop = document.body.scrollTop;
} else {
    var scrollTop = document.documentElement.scrollTop;
}
var top = (document.documentElement.clientHeight - $('#layer_info').height()) / 2
        + scrollTop;
var left = ($('html').width() - $('#layer_info').width()) / 2;
$('#layer_info').css('top', top).css('left', left).show();

ここでは横スクロールは無いものとしています。このような処理を、半透明レイヤーの表示後のコールバック関数の処理として記述すれば、レイヤーのアニメーション後に目的のコンテンツを中央に表示するということができます。

Lightboxを閉じる場合は、fadeTo()で透過を0に戻して、各レイヤーを非表示にして、select要素を表示させます。透過を0に戻すのは、次回実行時に前回の透過状態からアニメーションが始まってしまわないようにするためです。

というわけで、梅酒を飲んだら 梅酒.in をよろしくお願いします。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

著者について

fkoji

F.Ko-Ji

Webエンジニアやってます。最近は ドットインストール の開発がお仕事です。その傍ら、個人で Meity電車遅延なう梅酒.in#グラドル自画撮り部 の部室といったネットサービスを開発・運営してます。梅酒と草野球とリアル脱出ゲームが好きです。

» 詳しいプロフィールや運営サービスの一覧など