前提・実現したいこと
画像モーダルで、画像をdata-group でグループ化したいです。
発生している問題・エラーメッセージ
今のところ、開いた画像と同じ data-group に class="on" をつけるところまではできました。
onモーダルの prev, next ボタンを押すと、グループ化された on のついた画像を一つずつ移動(+1, -1)するようにしたいです。
ところが、現状では最初の一回のボタンの押下で +3, -3 されてしまう状態です。ボタンを何回も押せば本来のように +1, -1ずつ動きますが、安定して増減させたいです。
該当のソースコード
js
document.addEventListener('DOMContentLoaded', function () { class Modal { constructor() { //初期値(DOM) this.DOM = {}; this.DOM.html = document.querySelector('html'); this.DOM.thumbItems = document.querySelectorAll('.modal-imgs'); this.DOM.modal = document.querySelector('.modal-wrapper'); this.DOM.modalOverlay = document.querySelector('.modal-overlay'); this.DOM.modalItem = document.querySelector('.mid'); this.DOM.modalCaption = document.querySelector('.modal-aside'); this.DOM.modalClose = document.querySelector('.mp-close'); this.DOM.modalPrev = document.querySelector('.mp-prev'); this.DOM.modalNext = document.querySelector('.mp-next'); // スワイプ座標 this.startX; this.endX; // ターゲット要素 this.thumbTarget; // 何番めの要素か this.thumbCurrent; // 最初に実行する関数 this._init(); } _init() { this.DOM.thumbItems.forEach((thumbItem, index, array) => { thumbItem.addEventListener('click', this._appearModal.bind(this, thumbItem, index)); }); this._clickEvent(); // this._swipeEvent(); // this._mouseEvent(); } // クリックイベント _clickEvent() { this.DOM.modalClose.addEventListener('click', this._disappearModal.bind(this)); this.DOM.modalOverlay.addEventListener('click', this._disappearModal.bind(this)); this.DOM.modal.addEventListener('click', (e) => { if (e.target.querySelector('.modal-img')) { this._disappearModal.bind(this); } }); this.DOM.modalNext.addEventListener('click', this._next.bind(this)); this.DOM.modalPrev.addEventListener('click', this._prev.bind(this)); } // モーダル表示 _appearModal(thumbItem, index) { this.DOM.html.classList.add('is-fixed'); this.thumbCurrent = index; // 現在のindex this.DOM.modal.classList.add('spinner'); this.DOM.modal.classList.add('show'); this.DOM.modalOverlay.classList.add('show'); this.thumbTarget = thumbItem; //モーダル表示する要素 this._modalShow(this.thumbTarget); // モーダル表示 setTimeout(function () { document.querySelector('.modal-wrapper').classList.remove('spinner'); }, 200); } // モーダル非表示 _disappearModal() { this.DOM.html.classList.remove('is-fixed'); this.DOM.modal.classList.remove('show'); this.DOM.modalOverlay.classList.remove('show'); this.DOM.thumbItems.forEach(function (thumbItem) { thumbItem.classList.remove('on'); }); } // モーダルに表示する画像 _modalShow(self) { const imgElm = self; const targetModalItem = this.DOM.modalItem.childNodes[0]; targetModalItem.src = imgElm.getAttribute('data-src'); // フェードインのクラス targetModalItem.classList.remove('show'); setTimeout(function () { targetModalItem.classList.add('show'); }, 300); // グループ化 imgElm.classList.add('on'); let imageGroup = imgElm.getAttribute('data-group'); this.DOM.thumbItems.forEach(function (thumbItem) { if (thumbItem.getAttribute('data-group') === imageGroup) { thumbItem.classList.add('on'); } }); this._modalCaption(imgElm); } // モーダルに表示するキャプション _modalCaption(imgElm) { this.DOM.modalCaption.innerText = imgElm.dataset.caption } _next() { this.DOM.modal.classList.add('spinner'); const thumbItemsOn = document.querySelectorAll('.modal-imgs.on'); this.thumbCurrent = this._changeCount(1, this.thumbCurrent, thumbItemsOn.length); this.thumbTarget = thumbItemsOn[this.thumbCurrent]; this._modalShow(this.thumbTarget); // モーダル表示 setTimeout(function () { document.querySelector('.modal-wrapper').classList.remove('spinner'); }, 200); } _prev() { this.DOM.modal.classList.add('spinner'); const thumbItemsOn = document.querySelectorAll('.modal-imgs.on'); this.thumbCurrent = this._changeCount(-1, this.thumbCurrent, thumbItemsOn.length); this.thumbTarget = thumbItemsOn[this.thumbCurrent]; setTimeout(function () { document.querySelector('.modal-wrapper').classList.remove('spinner'); }, 200); this._modalShow(this.thumbTarget); // モーダル表示 } // 変更する番号を取得 _changeCount(num, index, len) { return (index + num + len) % len; } } // インスタンス化 const modal = new Modal(); });
html
<!-- gallery --> <div class="img-fit-01"> <div class="aspect-box spinner"> <img alt class="lazyload modal-imgs" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" style="width: 100%; height: 100%;" data-group="gallery-01" data-src="img/photo/04.png" data-caption="画像の詳細を書けます 01-01"> </div> <div class="aspect-box spinner"> <img alt class="lazyload modal-imgs" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" style="width: 100%; height: 100%;" data-group="gallery-01" data-src="img/photo/04.png" data-caption="画像の詳細を書けます 01-02"> </div> <div class="aspect-box spinner"> <img alt class="lazyload modal-imgs" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" style="width: 100%; height: 100%;" data-group="gallery-01" data-src="img/photo/04.png" data-caption="画像の詳細を書けます 01-03"> </div> <div class="aspect-box spinner"> <img alt class="lazyload modal-imgs" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" style="width: 100%; height: 100%;" data-group="gallery-01" data-src="img/photo/04.png" data-caption="画像の詳細を書けます 01-04"> </div> <div class="aspect-box spinner"> <img alt class="lazyload modal-imgs" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" style="width: 100%; height: 100%;" data-group="gallery-01" data-src="img/photo/04.png" data-caption="画像の詳細を書けます 01-05"> </div> <div class="aspect-box spinner"> <img alt class="lazyload modal-imgs" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" style="width: 100%; height: 100%;" data-group="gallery-01" data-src="img/photo/04.png" data-caption="画像の詳細を書けます 01-06"> </div> <aside>モーダルサンプル 02 / data-group でグループ化</aside> </div> <!-- image modal --> <div class="modal-wrapper spinner"> <div class="mid"><img alt src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="></div> <div class="mp-prev"></div> <div class="mp-next"></div> <div class="mp-close"></div> <aside class="modal-aside">xxx</aside> </div> <div class="modal-overlay"></div>
css
.modal-overlay { display: none; position: fixed; align-items: center; justify-content: center; flex-direction: column; top: 0; left: 0; cursor: pointer; z-index: -1; opacity: 0; background: rgba(255, 255, 255, 1); transition: all .25s 0s ease; } .modal-overlay.show { display: flex; width: 100%; height: 100%; z-index: 4; opacity: 1; } .modal-wrapper { display: flex; position: fixed; align-items: center; justify-content: center; flex-direction: column; transform: translate(-50%, -50%); top: 50%; left: 50%; z-index: -1; visibility: hidden; opacity: 0; transition: visibility .25s, opacity .25s; pointer-events: none; } .modal-wrapper.show { width: auto; z-index: 10; visibility: visible; opacity: 1; pointer-events: all; } .mid img { display: inline-block; position: relative; max-width: 80vw; max-height: 80vh; margin: 0; z-index: 5; opacity: 0; transition: .5s ease-out; -webkit-animation: show; animation: show; pointer-events: all; } .mid img.show { opacity: 1; -webkit-animation: show 1.3s ease-in-out; animation: show 1.3s ease-in-out; }
試したこと
js
_next() { this.DOM.modal.classList.add('spinner'); const thumbItemsOn = document.querySelectorAll('.modal-imgs.on'); this.thumbCurrent = this._changeCount(1, this.thumbCurrent, thumbItemsOn.length); this.thumbTarget = thumbItemsOn[this.thumbCurrent]; this._modalShow(this.thumbTarget); // モーダル表示 } _prev() { this.DOM.modal.classList.add('spinner'); const thumbItemsOn = document.querySelectorAll('.modal-imgs.on'); this.thumbCurrent = this._changeCount(-1, this.thumbCurrent, thumbItemsOn.length); this.thumbTarget = thumbItemsOn[this.thumbCurrent]; this._modalShow(this.thumbTarget); // モーダル表示 }
ここがうまく動いていないのだとおもいます。
試しに、
js
_next() { this.thumbCurrent = this._changeCount(1, this.thumbCurrent, this.DOM.thumbItems.length); this.thumbTarget = this.DOM.thumbItems[this.thumbCurrent]; this._modalShow(this.thumbTarget); // モーダル表示 } _prev() { this.thumbCurrent = this._changeCount(-1, this.thumbCurrent, this.DOM.thumbItems.length); this.thumbTarget = this.DOM.thumbItems[this.thumbCurrent]; this._modalShow(this.thumbTarget); // モーダル表示 }
としたところ、うまく +1, -1 されました。
また、コンソールに以下のようにすると、
js
console.log(thumbItemsOn); console.log(thumbItemsOn.length);
画像はきちんと取れていました。
js
this.thumbCurrent = this._changeCount(1, this.thumbCurrent, thumbItemsOn.length);
ここがうまく +1, -1 できていないのかと思うのですが、どう変更すればいいのか全くお手上げです。
どうかご助力をお願いできませんでしょうか。なにとぞよろしくお願いいたします。
補足情報(FW/ツールのバージョンなど)
Firefox 最新版
まだ回答がついていません
会員登録して回答してみよう