reviews

ImageLightbox.js:カスタマイズしやすい軽量ライトボックス

imagelightbox-js

//osvaldas.info/image-lightbox-responsive-touch-friendly

 

軽くてシンプルでカスタマイズしやすいレスポンシブでタッチフレンドリーなライトボックス

ほとんどタイトルで言い切ってしまったのだけども、Image LightboxはデフォルトではCSSは何も指定されていないというシンプルなライトボックス系のjQueryプラグイン。エフェクト開始、画像読み込み、読み込み終了、エフェクト終了、等々コールバックが充実しているので、ウェブデザインや用途に合わせてとてもカスタマイズしやすい作りになっている。ライトボックスが珍しかった時代はともかく、ユーザーがウェブ体験に慣れている現在、余計なUIがない方が扱いやすいのではないかと思う。

簡単な設定

使い方は簡単でまずはjsを読み込みます。

<script src="jquery.js"></script>
<script src="imagelightbox.js"></script>
<script>
    jQuery( function($){
        $( 'a' ).imageLightbox();
    });
</script>

次にcssに以下を設定

#imagelightbox{
    position: fixed; z-index: 9999;
    -ms-touch-action: none; touch-action: none;
}

以上です。

が、しかし…

Image Lightboxはie8に対応していないという、ブラウザ島国事情にとってあまりに厳しい条件。なんとかして使いたいと思ったので、以下ではie8対応にする方法を考えることにします。(作者のValutisさんはリトアニアの方のようだけども、レガシーブラウザは死滅しているみたい…めちゃめちゃうらやましい。)

 

ImageLightbox.jsをIE8対応に変更する

やってみたら主な(すべてではない)障害は二つあった。

parseIntで整数値が返ってこない

一つはparseIntの対象となる要素(デフォルトだとimg#imagelightbox)のcssでleftの値がエラーを起こすことで、cssに値を与えれば良いのだが、それだけでは中央揃えも出来ない有様なのでcssハックで中央揃えすることに。

img#imagelightbox { position:fixed; z-index:9999; -ms-touch-action:none; touch-action:none; } /* minimal css */
img#imagelightbox { left:09; right:09; top:09; bottom:09; margin:auto9; } /* IE8 hack */

load functionが発火しない

これで本体に手を付けずに済んだ…と思ったのもつかの間、いったん機嫌良く表示された画像を閉じ、再度リンクを押して表示しようとすると画像が読み込まれないという。これはあれだ。たいへん残念なIEらしい、画像がキャッシュされてしまうとload functionが発火しないという致命的なバグ。139行下のload function手前のjQueryでsrcを付与している処理、これをfunctionから切り離して後述するように変更。

元のコード

image = $( '<img ' + options.selector + ' />' )
.attr( 'src', target.attr( 'href' ) )
.load( function()
{
image.appendTo( 'body' );
setImage();
/////////// 略 ///////////
})
.error( function()
{if( options.onLoadEnd !== false ) options.onLoadEnd();
})

これを次のように変更してやります。

image = $( '<img ' + options.selector + ' />' ).appendTo( 'body' );
image.load( function()
{
setImage();
/////////// 略 ///////////
})
.error( function()
{if( options.onLoadEnd !== false ) options.onLoadEnd();
});
image.attr( 'src', target.attr( 'href' ) );

改変したコードはここにあげときます。(コードを改変したくなければ、ie8の場合のみリンク末尾にjsでタイムスタンプを付ける、という手法でも回避できるのではないかと思います。未検証ですが。)

Your Comment

コードの記述は<pre>または<code>タグで括って下さい。自動的にエスケープされます。

 

右の文字を入力して下さい captcha

2 comments

  1. yamamoto

    May 22, 2015

    はじめまして。

    Image Lightboxをサイトに使用してカスタマイズしようとして、つまずいてます。。
    captionの位置が固定なんですよね…。これを写真の真下あるいは真上に移動させたいのですが、どうにもこうにも…
    わかる人にはすぐわかるのでしょうがどうも知識不足で困っています…

    返信する
    • Mizuho Ogino

      May 22, 2015

      CSSだけでは実現できません。

      まず、imagelightbox.jsの60行目くらいにあるオプションのcaptionHeight周辺にでも、idとポジションの項目を追加して下さい。

      captionid: 'imagelightboxcaption',
      captionHeight: 0,
      captionPosi: 'bottom', // 'bottom','top','image-bottom','image-top'

      次に107行目当たりのimageへのcss指定を丸ごと以下の様に変更します。

       

      var caption = $( '#' + options.captionid );
      if( caption.length ){
      if ( !options.captionHeight ) {
      options.captionHeight = caption.outerHeight();
      }
      if ( options.captionPosi == 'image-bottom' ) {
      caption.css({
      'width':  imageWidth + 'px',
      'top': ( $( window ).height() - options.captionHeight - imageHeight ) / 2 + imageHeight + 'px'
      });
      } else if ( options.captionPosi == 'image-top' ) {
      caption.css({
      'width':  imageWidth + 'px',
      'top': ( $( window ).height() - options.captionHeight - imageHeight ) / 2 + 'px'
      });
      }
      }
      
      image.css(
      {
      'width': imageWidth + 'px',
      'height': imageHeight + 'px',
      'top': ( $( window ).height() + ( ( options.captionPosi == 'top' || options.captionPosi == 'image-top' )? options.captionHeight: options.captionHeight * (-1) ) - imageHeight ) / 2 + 'px',
      'left': ( $( window ).width() - imageWidth ) / 2 + 'px'
      });

      これで準備は完了。あとはinstanceに captionPosi:’image-bottom’, captioned:’my-caption-id’ みたいな感じで自由に設定して下さい。captionPosiはデフォルトがbottomです。ウィンドウの最上部に指定する場合はtop、画像のすぐ上と下に配置する場合はimage-topとimage-bottomを指定します。
      cssはimagelightboxの仕様に習って、js側では最低限しか指定していませんので注意して下さい。captionにする要素にはposition:fixedとleft:0, right:0は必要だと思います。あとできればmargin-right:auto, margin-left:autoやborder-box を与えておいて下さい。ただし、ie8で動くかどうかはしりません。あしからず。