モーダルイメージギャラリー(Lightbox)を自作する方法
自作するにあたり以下のサイトを参考にしています。
今回は写真ギャラリーの「Lightbox」をを自作する方法を紹介します。
Contents
サイト参考版
まず、一番シンプルに参考にしてきたサイトのコードそのまま利用した場合のバージョンになります。
サンプル
HTMLコード
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Slideshow / Carousel demo(1)</title>
<style type="text/css">
.row > .column {
padding: 0 8px;
}
.row:after {
content: "";
display: table;
clear: both;
}
/* Create four equal columns that floats next to eachother */
.column {
float: left;
width: 25%;
}
/* The Modal (background) */
.modal {
display: none;
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: black;
}
/* Modal Content */
.modal-content {
position: relative;
background-color: #fefefe;
margin: auto;
padding: 0;
width: 90%;
max-width: 1200px;
}
/* The Close Button */
.close {
color: white;
position: absolute;
top: 10px;
right: 25px;
font-size: 35px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #999;
text-decoration: none;
cursor: pointer;
}
/* Hide the slides by default */
.mySlides {
display: none;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -50px;
color: white;
font-weight: bold;
font-size: 20px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
-webkit-user-select: none;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a black background color with a little bit see-through */
.prev:hover,
.next:hover {
background-color: rgba(0, 0, 0, 0.8);
}
/* Number text (1/3 etc) */
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
/* Caption text */
.caption-container {
text-align: center;
background-color: black;
padding: 2px 16px;
color: white;
}
img.demo {
opacity: 0.6;
}
.active,
.demo:hover {
opacity: 1 !important;
}
img.hover-shadow {
transition: 0.3s;
}
.hover-shadow:hover {
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
</style>
</head>
<body>
<div style="width:80%">
<!-- Images used to open the lightbox -->
<div class="row" >
<div class="column" style="padding:0px">
<img src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC06344.jpg" onclick="openModal();currentSlide(1)" class="hover-shadow" style="width:100%">
</div>
<div class="column" style="padding:0px">
<img src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC07591.jpg" onclick="openModal();currentSlide(2)" class="hover-shadow" style="width:100%">
</div>
<div class="column" style="padding:0px">
<img src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC07708.jpg" onclick="openModal();currentSlide(3)" class="hover-shadow" style="width:100%">
</div>
<div class="column" style="padding:0px">
<img src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC06513.jpg" onclick="openModal();currentSlide(4)" class="hover-shadow" style="width:100%">
</div>
</div>
<!-- The Modal/Lightbox -->
<div id="myModal" class="modal" >
<span class="close cursor" onclick="closeModal()">×</span>
<div class="modal-content" style="width:45%;background-color:inherit !important;">
<div class="mySlides">
<div class="numbertext">1 / 4</div>
<img src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC06344.jpg" style="width:100%">
</div>
<div class="mySlides">
<div class="numbertext">2 / 4</div>
<img src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC07591.jpg" style="width:100%">
</div>
<div class="mySlides">
<div class="numbertext">3 / 4</div>
<img src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC07708.jpg" style="width:100%">
</div>
<div class="mySlides">
<div class="numbertext">4 / 4</div>
<img src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC06513.jpg" style="width:100%">
</div>
<!-- Next/previous controls -->
<a class="prev" onclick="plusSlides(-1)" >❮</a>
<a class="next" onclick="plusSlides(1)" >❯</a>
<!-- Caption text -->
<div class="caption-container">
<p id="caption"></p>
</div>
<!-- Thumbnail image controls -->
<div class="column">
<img class="demo" src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC06344.jpg" onclick="currentSlide(1)" alt="レッサーパンダ" style="width:100%">
</div>
<div class="column">
<img class="demo" src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC07591.jpg" onclick="currentSlide(2)" alt="カピバラ" style="width:100%">
</div>
<div class="column">
<img class="demo" src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC07708.jpg" onclick="currentSlide(3)" alt="ペンギン" style="width:100%">
</div>
<div class="column">
<img class="demo" src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC06513.jpg" onclick="currentSlide(4)" alt="ネコ" style="width:100%">
</div>
</div>
</div>
</div>
<script type="text/javascript">
// Open the Modal
function openModal() {
document.getElementById("myModal").style.display = "block";
}
// Close the Modal
function closeModal() {
document.getElementById("myModal").style.display = "none";
}
var slideIndex = 1;
showSlides(slideIndex);
// Next/previous controls
function plusSlides(n) {
showSlides(slideIndex += n);
}
// Thumbnail image controls
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
var captionText = document.getElementById("caption");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " active";
captionText.innerHTML = dots[slideIndex-1].alt;
}
</script>
</body>
</html>
デモ
実装方法
スタイルシート定義
<style type="text/css">
.row > .column {
padding: 0 8px;
}
.row:after {
content: "";
display: table;
clear: both;
}
/* Create four equal columns that floats next to eachother */
.column {
float: left;
width: 25%;
}
/* The Modal (background) */
.modal {
display: none;
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: black;
}
/* Modal Content */
.modal-content {
position: relative;
background-color: #fefefe;
margin: auto;
padding: 0;
width: 90%;
max-width: 1200px;
}
/* The Close Button */
.close {
color: white;
position: absolute;
top: 10px;
right: 25px;
font-size: 35px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #999;
text-decoration: none;
cursor: pointer;
}
/* Hide the slides by default */
.mySlides {
display: none;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -50px;
color: white;
font-weight: bold;
font-size: 20px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
-webkit-user-select: none;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a black background color with a little bit see-through */
.prev:hover,
.next:hover {
background-color: rgba(0, 0, 0, 0.8);
}
/* Number text (1/3 etc) */
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
/* Caption text */
.caption-container {
text-align: center;
background-color: black;
padding: 2px 16px;
color: white;
}
img.demo {
opacity: 0.6;
}
.active,
.demo:hover {
opacity: 1 !important;
}
img.hover-shadow {
transition: 0.3s;
}
.hover-shadow:hover {
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
</style>
HTMLマークアップ
まず、画像を設置します。
<div class="row" >
<div class="column" style="padding:0px">
<img src="(画像URI)" onclick="openModal();currentSlide(1)" class="hover-shadow" style="width:100%" />
</div>
...
</div>
イメージタグ(<img>)を設置し、クリックイベントに『openModal()』と『currentSlide()』を設定します。currentSlide()の引数には、後で設置するスライドの番号を設定してください。
次にモーダル領域を生成します。
<div id="myModal" class="modal" >
<span class="close cursor" onclick="closeModal()">×</span><!-- 閉じるボタン -->
<div class="modal-content" style="height:45%;background-color:inherit !important;">
...
</div>
</div>
まず、DIV領域を設定し、class『modal』を指定します。
次に、モーダルの内容としてDIV領域を生成し、class『modal-content』を設定します。
また、合わせて、閉じるボタンとして、SPANに、class『close』を指定し、クリックイベントに『closeModal()』指定してください。閉じる記号としては『✖』(×:)を指定してあります。
<div id="myModal" class="modal" >
<span class="close cursor" onclick="closeModal()">×</span><!-- 閉じるボタン -->
<div class="modal-content" style="height:45%;background-color:inherit !important;">
<div class="mySlides">
<div class="numbertext">1 / 4</div>
<img src="(画像URI)" style="width:100%">
</div>
...
</div>
</div>
スライド領域として、DIVにclass『mySlides』を指定します。その配下に、モーダル表示時に表示する画像をイメージタグ(<img>)を設定します。
次に、『次へ』ボタンと『前へ』ボタンを設置します。
<div id="myModal" class="modal" >
<span class="close cursor" onclick="closeModal()">×</span><!-- 閉じるボタン -->
<div class="modal-content" style="height:45%;background-color:inherit !important;">
<div class="mySlides">
<div class="numbertext">1 / 4</div>
<img src="(画像URI)" style="width:100%">
</div>
...
<!-- Next/previous controls -->
<a class="prev" onclick="plusSlides(-1)" >❮</a>
<a class="next" onclick="plusSlides(1)" >❯</a>
</div>
</div>
アンカータグ(<a>)に、class『prev』を指定し、クリックイベントとして『plusSlides(-1)』を設定すると、『前へ』ボタンになります。
アンカータグ(<a>)に、class『next』を指定し、クリックイベントとして『plusSlides(1)』を設置すると、『次へ』ボタンいなります。
<div id="myModal" class="modal" >
<span class="close cursor" onclick="closeModal()">×</span><!-- 閉じるボタン -->
<div class="modal-content" style="height:45%;background-color:inherit !important;">
<div class="mySlides">
<div class="numbertext">1 / 4</div>
<img src="(画像URI)" style="width:100%">
</div>
...
<!-- Next/previous controls -->
<a class="prev" onclick="plusSlides(-1)" >❮</a>
<a class="next" onclick="plusSlides(1)" >❯</a>
<!-- Caption text -->
<div class="caption-container">
<p id="caption"></p>
</div>
</div>
</div>
さらに、キャプション領域を設定します。
DIV領域に、class『caption-container』を設定し、配下に、ID『caption』の領域を生成しておきます。
<div id="myModal" class="modal" >
<span class="close cursor" onclick="closeModal()">×</span><!-- 閉じるボタン -->
<div class="modal-content" style="height:45%;background-color:inherit !important;">
<div class="mySlides">
<div class="numbertext">1 / 4</div>
<img src="(画像URI)" style="width:100%">
</div>
...
<!-- Next/previous controls -->
<a class="prev" onclick="plusSlides(-1)" >❮</a>
<a class="next" onclick="plusSlides(1)" >❯</a>
<!-- Caption text -->
<div class="caption-container">
<p id="caption"></p>
</div>
<!-- Thumbnail image controls -->
<div class="column">
<img class="demo" src="(画像URI)" onclick="currentSlide(1)" alt="(キャプション)" style="width:100%">
</div>
...
</div>
</div>
最後に、サムネイル領域を生成します。DIV領域を設定し、class『column』を指定します。その配下に、サムネイル用の画像をイメージタグ(<img>)で設定します。classには『demo』を指定してください。また、alt属性に文字列を設定すると、その文字列がキャプションになります。
Javascriptコード追加
<script type="text/javascript">
// Open the Modal
function openModal() {
document.getElementById("myModal").style.display = "block";
}
// Close the Modal
function closeModal() {
document.getElementById("myModal").style.display = "none";
}
var slideIndex = 1;
showSlides(slideIndex);
// Next/previous controls
function plusSlides(n) {
showSlides(slideIndex += n);
}
// Thumbnail image controls
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
var captionText = document.getElementById("caption");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " active";
captionText.innerHTML = dots[slideIndex-1].alt;
}
</script>
最後に、Javascriptコードを追加すれば、完了です。
モーダルギャラリー領域およびサムネイルを自動生成するようにしてみた
モーダル領域を毎回HTMLでマークアップするのも面倒ですし、サムネイル数や写真数などは変わる可能性がるので、これらを動的に生成するようにしてみます。
HTMLコード
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Slideshow / Carousel demo(2)</title>
<style type="text/css">
.row > .column {
padding: 0 8px;
}
.row:after {
content: "";
display: table;
clear: both;
}
/* Create four equal columns that floats next to eachother */
.column {
float: left;
width: 25%;
}
/* The Modal (background) */
.modal {
display: none;
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: black;
}
/* Modal Content */
.modal-content {
position: relative;
background-color: #fefefe;
margin: auto;
padding: 0;
width: 90%;
max-width: 1200px;
}
/* The Close Button */
.close {
color: white;
position: absolute;
top: 10px;
right: 25px;
font-size: 35px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #999;
text-decoration: none;
cursor: pointer;
}
/* Hide the slides by default */
.mySlides {
display: none;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -50px;
color: white;
font-weight: bold;
font-size: 20px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
-webkit-user-select: none;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a black background color with a little bit see-through */
.prev:hover,
.next:hover {
background-color: rgba(0, 0, 0, 0.8);
}
/* Number text (1/3 etc) */
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
/* Caption text */
.caption-container {
text-align: center;
background-color: black;
padding: 2px 16px;
color: white;
}
img.demo {
opacity: 0.6;
}
.active,
.demo:hover {
opacity: 1 !important;
}
img.hover-shadow {
transition: 0.3s;
}
.hover-shadow:hover {
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
</style>
</head>
<body>
<div style="width:80%">
<!-- Images used to open the lightbox -->
<div class="row" >
<div class="column" style="padding:0px">
<img src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC06344.jpg" class="hover-shadow" style="width:100%" alt="レッサーパンダ">
</div>
<div class="column" style="padding:0px">
<img src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC07591.jpg" class="hover-shadow" style="width:100%" alt="カピバラ">
</div>
<div class="column" style="padding:0px">
<img src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC07708.jpg" class="hover-shadow" style="width:100%" alt="ペンギン">
</div>
<div class="column" style="padding:0px">
<img src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC06513.jpg" class="hover-shadow" style="width:100%" alt="ネコ">
</div>
</div>
</div>
<script type="text/javascript">
var myModal = document.createElement("div");
myModal.className = "modal";
myModal.id = "myModal";
var btnClose = document.createElement("span");
btnClose.className = "close cursor";
btnClose.innerHTML = "×"
btnClose.addEventListener( 'click', function() {
closeModal();
}, false
);
var modalContent = document.createElement("div");
modalContent.className = "modal-content";
modalContent.style.width = "45%";
modalContent.style.backgroundColor = "inherit"
var slides = document.querySelectorAll(".column img");
if ( slides != undefined ) {
var nCount = slides.length;
for ( var i=0; i < nCount; i++ ) {
var imgObj = slides[i];
/* イベント設定 */
setSlideClickEvent(imgObj,i+1);
var mySlide = document.createElement("div");
mySlide.className = "mySlides";
var numberText = document.createElement("div");
numberText.className = "numbertext";
numberText.innerHTML = String(i+1) + " / " + String(nCount);
var lightboxSlide = document.createElement("img");
lightboxSlide.src = imgObj.src;
lightboxSlide.style.width = "100%";
mySlide.appendChild(numberText);
mySlide.appendChild(lightboxSlide);
modalContent.appendChild(mySlide);
}
if ( nCount > 1 ) {
var btnPrev = document.createElement("a");
btnPrev.className = "prev";
btnPrev.innerHTML = "❮";
btnPrev.addEventListener( 'click', function() {
plusSlides(-1);
}, false
);
var btnNext = document.createElement("a");
btnNext.className = "next";
btnNext.innerHTML = "❯";
btnNext.addEventListener( 'click', function() {
plusSlides(1);
}, false
);
modalContent.appendChild(btnPrev);
modalContent.appendChild(btnNext);
}
var captionArea = document.createElement("div");
captionArea.className = "caption-container";
var captionText = document.createElement("p");
captionText.id = "caption";
captionArea.appendChild(captionText);
modalContent.appendChild(captionArea);
for ( var i=0; i < nCount; i++ ) {
var imgObj = slides[i];
/* サムネイル作成 */
var thumbArea = document.createElement("div");
thumbArea.className = "column";
thumbArea.style.width = String((100 / nCount)) + '%';
var thumbnail = document.createElement("img");
thumbnail.src = imgObj.src;
thumbnail.className = "demo";
thumbnail.style.width = "100%";
thumbnail.alt = imgObj.alt;
thumbArea.appendChild(thumbnail);
modalContent.appendChild(thumbArea);
/* サムネイルクリック時のイベントを設定 */
setThumbClickEvent(thumbnail,i+1);
}
}
myModal.appendChild(btnClose);
myModal.appendChild(modalContent);
document.body.appendChild(myModal);
// Open the Modal
function openModal() {
document.getElementById("myModal").style.display = "block";
}
// Close the Modal
function closeModal() {
document.getElementById("myModal").style.display = "none";
}
var slideIndex = 1;
showSlides(slideIndex);
// Next/previous controls
function plusSlides(n) {
showSlides(slideIndex += n);
}
// Thumbnail image controls
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
var captionText = document.getElementById("caption");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " active";
captionText.innerHTML = dots[slideIndex-1].alt;
}
function setSlideClickEvent(slide,idx) {
if ( slide == undefined ) return;
/* ボタンクリック時のイベント設定 */
slide.addEventListener( 'click', function() {
openModal();
currentSlide(idx);
}, false );
}
function setThumbClickEvent(thumb,idx) {
if ( thumb == undefined ) return;
/* ボタンクリック時のイベント設定 */
thumb.addEventListener( 'click', function() {
currentSlide(idx);
}, false );
}
</script>
</body>
</html>
デモ
実装方法
基本的には、すべてJavascript側で対応するので、HTMLでは、画像を設定するだけです。
ただ、キャプションをサムネイルで設定するのではなく、画像のalt属性に設定してください。
<div class="row" >
<div class="column" style="padding:0px">
<img src="(画像URI1)" class="hover-shadow" style="width:100%" alt="(キャプション1)">
</div>
<div class="column" style="padding:0px">
<img src="(画像URI2)" class="hover-shadow" style="width:100%" alt="(キャプション2)">
</div>
<div class="column" style="padding:0px">
<img src="(画像URI3)" class="hover-shadow" style="width:100%" alt="(キャプション3)">
</div>
<div class="column" style="padding:0px">
<img src="(画像URI4)" class="hover-shadow" style="width:100%" alt="(キャプション4)">
</div>
</div>
あとは、Javascriptを実行するだけです。
モーダルイメージギャラリー(Lightbox)をライブラリ化してみた
サンプル
HTMLコード
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Slideshow / Carousel demo(3)</title>
<link rel="stylesheet" href="https://www.single-life.tokyo/demo/MyLightbox.css">
</head>
<body>
<div style="width:80%">
<div class="row" >
<div class="column" style="padding:0px">
<img src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC06344.jpg" style="width:100%" alt="レッサーパンダ">
</div>
<div class="column" style="padding:0px">
<img src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC07591.jpg" style="width:100%" alt="カピバラ">
</div>
<div class="column" style="padding:0px">
<img src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC07708.jpg" style="width:100%" alt="ペンギン">
</div>
<div class="column" style="padding:0px">
<img src="https://www.single-life.tokyo/wp-content/uploads/2021/07/DSC06513.jpg" style="width:100%" alt="ネコ">
</div>
</div>
</div>
<script type="text/javascript" src="https://www.single-life.tokyo/demo/MyLightbox.js"></script>
<script type="text/javascript">
/* thumbVisible:falseにするとサムネイルが非表示 */
var lightbox = new MyLightbox(".column img",{ thumbVisible:false } );
</script>
</body>
</html>
CSSファイル(MyLightbox.css)
.row > .column {
padding: 0 8px;
}
.row:after {
content: "";
display: table;
clear: both;
}
/* Create four equal columns that floats next to eachother */
.column {
float: left;
width: 25%;
}
/* The Modal (background) */
.modal {
display: none;
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: black;
}
/* Modal Content */
.modal-content {
position: relative;
background-color: #fefefe;
margin: auto;
padding: 0;
width: 90%;
max-width: 1200px;
}
/* The Close Button */
.close {
color: white;
position: absolute;
top: 10px;
right: 25px;
font-size: 35px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #999;
text-decoration: none;
cursor: pointer;
}
/* Hide the slides by default */
.mySlides {
display: none;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -50px;
color: white;
font-weight: bold;
font-size: 20px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
-webkit-user-select: none;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a black background color with a little bit see-through */
.prev:hover,
.next:hover {
background-color: rgba(0, 0, 0, 0.8);
}
/* Number text (1/3 etc) */
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
/* Caption text */
.caption-container {
text-align: center;
background-color: black;
padding: 2px 16px;
color: white;
}
img.demo {
opacity: 0.6;
}
.active,
.demo:hover {
opacity: 1 !important;
}
img.hover-shadow {
transition: 0.3s;
}
.hover-shadow:hover {
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
cursor:pointer;
}
JSファイル(MyLightbox.js)
class MyLightbox {
constructor(selector,options) {
/* オプション取得 */
this.selector = selector;
this.slideIndex = options.slideIndex || 1;
this.slideWidth = options.slideWidth || '45%';
this.slideNoCapWidth = options.slideNoCapWidth || '60%';
this.prevClass = options.prevClass || 'prev';
this.nextClass = options.nextClass || 'next';
this.modalClass = options.modalClass || 'modal';
this.modalId = options.modalId || 'myModal';
this.numbertextClass = options.numbertextClass || 'numbertext';
this.captionClass = options.captionClass || "caption-container";
this.captionId = options.captionId || "caption";
this.thumbClass = options.thumbClass || 'demo';
this.columnClass = options.columnClass || 'column';
this.slideClass = options.slideClass || 'mySlides';
if ( options.thumbVisible == undefined ) this.thumbVisible = true;
else this.thumbVisible = options.thumbVisible;
/* 初期化処理実行 */
this.init();
}
/* Lightbox領域生成 */
init() {
var myModal = document.createElement("div");
myModal.className = this.modalClass;
myModal.id = this.modalId;
var btnClose = document.createElement("span");
btnClose.className = "close cursor";
btnClose.innerHTML = "×"
btnClose.addEventListener( 'click', function() {
this.closeModal();
}.bind(this), false
);
var modalContent = document.createElement("div");
modalContent.className = "modal-content";
if ( this.thumbVisible ) {
modalContent.style.width = this.slideWidth;
} else {
modalContent.style.width = this.slideNoCapWidth;
}
modalContent.style.backgroundColor = "inherit"
var slides = document.querySelectorAll(this.selector);
if ( slides != undefined ) {
var nCount = slides.length;
for ( var i=0; i < nCount; i++ ) {
var imgObj = slides[i];
imgObj.className = 'hover-shadow';
/* イベント設定 */
this.setSlideClickEvent(imgObj,i+1);
var mySlide = document.createElement("div");
mySlide.className = this.slideClass;
var numberText = document.createElement("div");
numberText.className = "numbertext";
numberText.innerHTML = String(i+1) + " / " + String(nCount);
var lightboxSlide = document.createElement("img");
lightboxSlide.src = imgObj.src;
lightboxSlide.style.width = "100%";
mySlide.appendChild(numberText);
mySlide.appendChild(lightboxSlide);
modalContent.appendChild(mySlide);
}
if ( nCount > 1 ) {
var btnPrev = document.createElement("a");
btnPrev.className = this.prevClass;
btnPrev.innerHTML = "❮";
btnPrev.addEventListener( 'click', function() {
this.plusSlides(-1);
}.bind(this), false
);
var btnNext = document.createElement("a");
btnNext.className = this.nextClass;
btnNext.innerHTML = "❯";
btnNext.addEventListener( 'click', function() {
this.plusSlides(1);
}.bind(this), false
);
modalContent.appendChild(btnPrev);
modalContent.appendChild(btnNext);
}
var captionArea = document.createElement("div");
captionArea.className = this.captionClass;
var captionText = document.createElement("p");
captionText.id = this.captionId;
captionArea.appendChild(captionText);
modalContent.appendChild(captionArea);
for ( var i=0; i < nCount; i++ ) {
var imgObj = slides[i];
/* サムネイル作成 */
var thumbArea = document.createElement("div");
thumbArea.className = this.columnClass;
thumbArea.style.width = String((100 / nCount)) + '%';
if ( this.thumbVisible == false ) thumbArea.style.display ='none';
var thumbnail = document.createElement("img");
thumbnail.src = imgObj.src;
thumbnail.className = this.thumbClass;
thumbnail.style.width = "100%";
thumbnail.alt = imgObj.alt;
thumbArea.appendChild(thumbnail);
modalContent.appendChild(thumbArea);
/* サムネイルクリック時のイベントを設定 */
this.setThumbClickEvent(thumbnail,i+1);
}
}
myModal.appendChild(btnClose);
myModal.appendChild(modalContent);
document.body.appendChild(myModal);
this.showSlides(this.slideIndex);
}
// Open the Modal
openModal() {
document.getElementById(this.modalId).style.display = "block";
}
// Close the Modal
closeModal() {
document.getElementById(this.modalId).style.display = "none";
}
// Next/previous controls
plusSlides(n) {
this.showSlides(this.slideIndex += n);
}
// Thumbnail image controls
currentSlide(n) {
this.showSlides(this.slideIndex = n);
}
showSlides(n) {
var i;
var slides = document.getElementsByClassName(this.slideClass);
var dots = document.getElementsByClassName(this.thumbClass);
var captionText = document.getElementById(this.captionId);
if (n > slides.length) {this.slideIndex = 1}
if (n < 1) {this.slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[this.slideIndex-1].style.display = "block";
dots[this.slideIndex-1].className += " active";
captionText.innerHTML = dots[this.slideIndex-1].alt;
}
setSlideClickEvent(slide,idx) {
if ( slide == undefined ) return;
/* ボタンクリック時のイベント設定 */
slide.addEventListener( 'click', function() {
this.openModal();
this.currentSlide(idx);
}.bind(this), false );
}
setThumbClickEvent(thumb,idx) {
if ( thumb == undefined ) return;
/* ボタンクリック時のイベント設定 */
thumb.addEventListener( 'click', function() {
this.currentSlide(idx);
}.bind(this), false );
}
}
デモ
実装方法
MyLightbox初期化
<script type="text/javascript">
/* thumbVisible:falseにするとサムネイルが非表示 */
var lightbox = new MyLightbox(".column img",{ thumbVisible:false } );
</script>
MyLightboxクラスというのを作成しました。
初期化パラメータの第1パラメータに、ギャラリーを設定したい画像のセレクタを指定してください。第2パラメータには、オプションを指定してください。
以上、ご参考まで