<div class="overlay"></div>
<div class="modal-window"></div>
<div class="image-viewer">
<div class="main-image">
</div>
<ul class="nav">
</ul>
</div>
img {
height: auto;
width: 100%;
}
.image-viewer {
background: #dfdfdf;
margin: 0 auto;
width: 40%;
@media screen and (max-width: 768px) {
width: 100%;
}
}
.main-image {
background: #777;
padding-bottom: 56.25%;
margin-bottom: 10px;
overflow: hidden;
position: relative;
> img {
//opacity: 0;
position: absolute;
top: 0;
left: 0;
transition: 0.5s;
//visibility: hidden;
/*
&.active {
opacity: 1;
visibility: visible;
z-index: 100;
}
*/
}
}
.nav {
font-size: 0;
list-style: none;
margin: 0;
padding: 0;
&-item {
background: #ccc;
display: inline-block;
overflow: hidden;
position: relative;
padding-bottom: 14.0625%;
width: 25%;
/*
@media screen and (max-width: 768px) {
padding-bottom: 28.125%;
width: 50%;
}
*/
> img {
position: absolute;
top: 0;
left: 0;
}
}
}
.overlay {
background: #000;
height: 100%;
opacity: 0;
position: fixed;
top: 0;
left: 0;
transition: 0.5s;
-webkit-visibility: hidden;
visibility: hidden;
width: 100%;
z-index: 1000;
&.active {
opacity: 0.6;
visibility: visible;
}
}
.modal-window {
opacity: 0;
position: fixed;
top: 50%;
left: 50%;
transition: 0.5s;
transform: translate(-50%, -50%);
visibility: hidden;
z-index: 2000;
&.active {
opacity: 1;
visibility: visible;
}
}
View Compiled
(() => {
//画像に関するクラス
class Asset {
constructor() {
this.urls = [
"#",
"#",
"#",
"#"
];
this._images = [];
}
get images() {
return this._images;
}
//初期化するメソッド
init() {
this.createImage();
}
//画像を生成するメソッド
createImage() {
for (let i = 0; i < this.urls.length; i++) {
const image = new Image();
image.src = this.urls[i];
this._images[i] = image;
}
}
}
//ナビゲーションに関するクラス
class Nav {
constructor() {
this.elem = document.querySelector(".nav");
this.navItems = null;
}
//ナビゲーションをクリックできる状態にするメソッド
setupListener(mainImage) {
this.navItems.forEach((navItem, index) =>
navItem.addEventListener("click", e => {
e.preventDefault();
//クリックされたナビの画像
const target = e.target;
//複製
const clone = target.cloneNode(true);
//表示されている画像を削除
mainImage.removeImage();
//複製した画像を挿入
mainImage.addImage(clone);
})
);
}
//ナビゲーションにサムネイルを挿入するメソッド
insertThumbnail(images) {
//.navに画像を挿入(画像が親要素を持たなければouterHTMLはエラーを発生する)
images.forEach(image => this.elem.appendChild(image));
//画像を.nav-itemで包む
for (let i = 0; i < images.length; i++) {
images[i].outerHTML = `<li class="nav-item">${images[i].outerHTML}</li>`;
}
this.navItems = document.querySelectorAll(".nav-item");
//this.navItems.forEach(navItem => this.elem.appendChild(navItem));
}
}
//メイン画像に関するクラス
class MainImage {
constructor() {
this.elem = document.querySelector(".main-image");
}
//初期化するメソッド
init(nav) {
//先頭のサムネイル画像を複製
const clone = nav.navItems[0].firstChild.cloneNode(true);
//複製したサムネイル画像を表示
this.addImage(clone);
}
//メイン画像をクリックできる状態にするメソッド
setupListener(modalWindow, overlay) {
this.elem.addEventListener("click", e => {
e.preventDefault();
const target = e.target;
//console.log(target);
//メイン画像を複製
const clone = target.cloneNode(true);
//それまで挿入されていたモーダルウィンドウの画像を削除
modalWindow.removeImage();
//複製したメイン画像をモーダルウィンドウに挿入
modalWindow.addImage(clone);
//オーバーレイを表示
overlay.show();
});
}
//.main-imageにメイン画像を挿入するメソッド
addImage(image) {
this.elem.appendChild(image);
//image.classList.add("active");
}
//.main-imageからメイン画像を削除するメソッド
removeImage() {
this.elem.removeChild(this.elem.firstChild);
//this.elem.firstChild.classList.remove("active");
}
}
//モーダルウィンドウに関するクラス
class ModalWindow {
constructor() {
this.elem = document.querySelector(".modal-window");
}
//モーダルウィンドウを表示するメソッド
show() {
this.elem.classList.add("active");
}
//モーダルウィンドウを非表示にするメソッド
hide() {
this.elem.classList.remove("active");
}
//.modal-windowに画像を挿入するメソッド
addImage(image) {
this.elem.appendChild(image);
this.elem.classList.add("active");
}
//.modal-windowから画像を削除するメソッド
removeImage() {
//モーダルウィンドウ内に画像があれば(初回は無いためそのまま書くとエラーが発生する)
if (this.elem.firstChild) {
this.elem.removeChild(this.elem.firstChild);
this.elem.classList.remove("active");
}
}
}
//オーバーレイに関するクラス
class Overlay {
constructor() {
this.elem = document.querySelector(".overlay");
}
//オーバーレイをクリックできる状態にするメソッド
setupListener(modalWindow) {
this.elem.addEventListener("click", e => {
e.preventDefault();
//オーバーレイを非表示
this.hide();
//モーダルウィンドウを非表示
modalWindow.hide();
//モーダルウィンドウ内の画像を削除
modalWindow.removeImage(modalWindow.elem.firstChild);
});
}
//オーバーレイを表示するメソッド
show() {
this.elem.classList.add("active");
}
//オーバーレイを非表示にするメソッド
hide() {
this.elem.classList.remove("active");
}
}
//インスタンス化
const asset = new Asset();
const nav = new Nav();
const mainImage = new MainImage();
const modalWindow = new ModalWindow();
const overlay = new Overlay();
//全体を初期化する関数
function init() {
asset.init();
nav.insertThumbnail(asset.images);
mainImage.init(nav);
setupListeners();
}
//画像ビューアを操作できる状態にする関数
function setupListeners() {
nav.setupListener(mainImage);
mainImage.setupListener(modalWindow, overlay);
overlay.setupListener(modalWindow);
}
//起動
init();
})();
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.