Vanilla JSでLightboxっぽいものを自作する
- Web
- 2020/11/16
jQuery無しで動く画像ポップアップ機能が必要になったので自作した時のお話です
jQuery無しで画像ポップアップがしたい
僕は近年『脱 jQuery』をしています。つまるところ、jQuery依存のプラグインが一切使えないということでLightboxも例に漏れず使えません。Vanilla JSで動くポップアッププラグインもいくつか試してみたのですがうまく動かなかったりHTMLの大幅な書き直しが必要になったりとしっくりきません。自分が欲しいのは画像をクリックしたらモーダルで拡大表示するだけのシンプルなものだったので、自作することにしました。
HTMLのカスタムデータ属性にリンクを仕込む
簡単にポップアップ機能を実現するには、カスタムデータ属性を使うのが一番です。imgタグに大きな画像のパスをカスタムデータとして仕込んでおき、画像にクリックイベントが発火したらカスタムデータ属性を読み取りJSでDOMを生成し表示します。HTMLは以下のようになります
<img src='./thumbnail.jpg' data-orig='./original.jpg' class='popup'>
画像を表示するためのダミー要素を用意する
続いて画像をモーダル表示するためのダミー要素を用意します。今回は背景を暗くしたいので、画面全体を覆うdivの中に画像用のimgタグを設定しています。
<div class='orig-wrap'>
<img src='#' class='orig-img' >
</div>
.orig-wrap{
width:100%;
height:100vh;
background-color:rgba(50,50,50,.8);
display:none;
justify-content:center;
align-items:center;
position:fixed;
top:0;
left: 0;
opacity:0;
}
.orig-img{
width:max-content;
max-width:80%;
cursor:pointer;
}
.popup{
cursor: pointer;
}
これでダミー要素の完成です。ついでに画像周りにもCSSを当てておきます
サムネクリックでダミー要素に元画像表示
ここからやっとJSです
const thumb = document.querySelector('.popup'); //クラス名で元画像要素取得
thumb.addEventListener('click',function(){ //元画像クリック時の処理
const origWrap = document.querySelector('.orig-wrap');
const origImg = document.querySelector('.orig-img');
const origSource = thumb.dataset.orig; //カスタムデータの値を取得
origImg.setAttribute('src',origSource); //ダミー画像要素にカスタムデータのパスを入力
origWrap.style.display = 'flex'//displayプロパティをセット
origWrap.style.opacity = 1; //ダミー要素を不透明にする
});
解説
popupクラスを付与した画像(imgタグ)をクリックするとダミー要素のエレメントを取得し、クリックしたimgタグに仕込まれたカスタムデータの値を変数に格納します。
次に、予め取得したポップアップ表示用のimgタグのsrcプロパティにsetAttributeでカスタムデータの値をセットし、拡大表示用の画像が表示されるようになります。
最後にJSからダミー要素のCSSプロパティ(不透明度とdisplay)を変更し実際に画面に表示されます。
閉じる処理を追記
このままでは非表示にできないのでポップアップ表示された画像をクリックすると元に戻す処理を実装しましょう。
以下のようにeventListenerを追加します。
const thumb = document.querySelector('.popup'); //クラス名で元画像要素取得
thumb.addEventListener('click',function(){ //元画像クリック時の処理
const origWrap = document.querySelector('.orig-wrap');
const origImg = document.querySelector('.orig-img');
const origSource = thumb.dataset.orig; //カスタムデータの値を取得
origImg.setAttribute('src',origSource); //ダミー画像要素にカスタムデータのパスを入力
origWrap.style.display = 'flex'//displayプロパティをセット
origWrap.style.opacity = 1; //ダミー要素を不透明にする
origImg.addEventListener('click', function(){
origWrap.style.opacity = 0 //ダミー要素を透明にする
origWrap.style.display = 'none' //ダミー要素を非表示にする
})
});
DEMO
以下のリンクからデモが見れます
ダウンロード
サンプルファイルを置いておきます。個人での学習にご利用ください