リンクが張られた画像をLightbox形式で表示するようなJavaScriptを書いていた。vw
とvh
単位でa
要素を引き伸ばして適当に前面に表示し、img
要素をなんとなく拡大してから天地左右中央配置する。予めクラス指定が必要だったり、スタイルの追加が必要だったりしない、ドロップインで動作するものだ。
Demo: Lightbox with Clean Markup
デモでそれぞれの画像をクリック(タッチ)すると、描画領域全体に画像が表示される。a
要素をオーバーレイの背景に変え、img
要素をうまく収まるように調整することになる。
if (this.href !== image.src) {
image._src = image.src;
image.src = this.href;
}
リンク先と画像のURLが違う場合は、画像がサムネイルでリンク先がフルサイズの画像とみなし、一時的に画像のリンク先を書き換えてフルサイズ画像が表示されるようにもなっている。サムネイルのURLは一時的に_src
プロパティーに保存しておき、閉じると元に戻るようにもした。
if (image._src) {
image.src = image._src;
delete image._src;
}
data-*
属性を使ってやりたいところだが、スクリプトの規模に比べて大仰なポリフィルが必要になるので、オレオレプロパティーに保存している。setAttribute()
やgetAttribute()
をdata-*
属性に使ったら負けだ。
this.style.backgroundColor = '#333';
this.style.cursor = 'zoom-out';
this.style.height = '100vh';
this.style.left = '0';
this.style.position = 'fixed';
this.style.top = '0';
this.style.width = '100vw';
this.style.zIndex = '1';
コンテキストに依存するので、left
とtop
プロパティーは0
にする必要があるだろう。a
要素はデフォルトでdisplay: inline
のため、position: fixed
を指定するとblock
に変わる、と仕様に規定がある。そのためわざわざthis.style.display = 'block'
を指定しなくてもwidth
プロパティー等はきちんと反映されるようになる。描画領域に合わせるのは100vw
と100vh
で簡単な時代だ。
image.style.bottom = '0';
image.style.height = 'auto';
image.style.left = '0';
image.style.margin = 'auto';
image.style.maxHeight = '96%';
image.style.maxWidth = '96%';
image.style.position = 'absolute';
image.style.right = '0';
image.style.top = '0';
image.style.width = 'auto';
画像の天地左右中央配置はFirefoxの画像表示スタイルシートに幅制限を加えたものにした。FirefoxでCSSではなくJavaScriptでheight
とwidth
属性を書き換えてリサイズしているのは何か意味があるんだろうか。最大幅を100%
にしていないのは単に好みだ。
デモではPlaceIMGの画像でリンク先もそれの場合のみに有効になるようにしている。実際にはURLの判定を[src^="/img/"]
やウェブサイトのドメイン、またはその両方で判定するようにすると良いだろう。
様々な事情があってHTMLファイルはいじることが難しいけれど、それらから固定で参照されているJavaScriptファイルだけは追記することが可能、というようなケースで必要になって考えていた。このように画像のURLなどから類推し、既存のHTML構造を利用してスタイルを当てていくのがコストが低い。
デモのページにも書いておいたが、実装依存はともかくz-index
プロパティーがコンテキストに依存するという問題がある。ライブラリー化するのは難しそうだ。とは言うもののストレートな実装なので汎用化しなくても良さそうではある。