前提・実現したいこと
vanilla jsで画像モーダルを作っています。スワイプ時のようにマウスドラッグでもモーダルをめくれるようにしたいです。
発生している問題・エラーメッセージ
エラーはなし
該当のソースコード
js
document.addEventListener('DOMContentLoaded', function () { /* modal ---------------------------------------------------- */ const html = document.querySelector('html'); const modalWrapper = document.getElementsByClassName('modal-wrapper')[0]; const images = document.querySelectorAll('.modal-imgs'); const modalImgWrp = document.getElementsByClassName('modal-img')[0]; const modalImage = document.querySelector('.modal-img img'); const modalAside = document.getElementsByClassName('modal-aside')[0]; const modalPrev = document.getElementsByClassName('mp-prev')[0]; const modalNext = document.getElementsByClassName('mp-next')[0]; const modalClose = document.getElementsByClassName('mp-close')[0]; if (modalWrapper != null) { let listItems = document.querySelectorAll('.modal-imgs'), listItem = Array.prototype.slice.call(listItems, 0); listItem.forEach(function ($listItem, i) { let imageSrc = $listItem.getAttribute('data-src'), imageCaption = $listItem.getAttribute('data-caption'); $listItem.dataset.num = (i + 1); $listItem.addEventListener('click', function () { document.body.style.overflowY = 'hidden', html.classList.add('is-fixed'); let imageGroup = this.getAttribute('data-group'); images.forEach(function (img) { if (img.getAttribute('data-group') === imageGroup) { img.classList.add('on'); } }); modalImage.dataset.num = this.getAttribute('data-num'); let thisNum = parseInt(modalImage.getAttribute('data-num')); if (!document.querySelector('[data-num="' + (thisNum - 1) + '"].on')) { modalPrev.style.visibility = 'hidden'; } else { modalPrev.style.visibility = 'visible'; } if (!document.querySelector('[data-num="' + (thisNum + 1) + '"].on')) { modalNext.style.visibility = 'hidden'; } else { modalNext.style.visibility = 'visible'; } modalWrapper.classList.add('show'); modalWrapper.classList.add('spinner'); modalImage.classList.add('show'); modalImage.src = imageSrc; modalAside.textContent = imageCaption; setTimeout(function () { modalWrapper.classList.remove('spinner'); }, 200); }); }); modalPrev.addEventListener('click', function () { prev(); }); modalNext.addEventListener('click', function () { next(); }); modalImage.swipe('left', function () { next(); }, 10); modalImage.swipe('right', function () { prev(); }, 10); modalImage.drag('left', function () { next(); }, 100); modalImage.drag('right', function () { prev(); }, 100); }; function prev() { document.body.style.overflowY = 'hidden', html.classList.add('is-fixed'); modalWrapper.classList.add('spinner'); modalImage.classList.add('off'); modalImage.classList.remove('show'); modalPrev.style.visibility = 'hidden'; modalNext.style.visibility = 'hidden'; setTimeout(function () { modalImage.classList.remove('off'); modalImage.classList.add('show'); let prevNum = parseInt(modalImage.getAttribute('data-num')); modalNext.style.visibility = 'visible'; if (!document.querySelector('[data-num="' + (prevNum - 2) + '"].on')) { modalPrev.style.visibility = 'hidden'; modalNext.style.visibility = 'visible'; } else { modalPrev.style.visibility = 'visible'; modalNext.style.visibility = 'visible'; } let prevImg = document.querySelector('[data-num="' + (prevNum - 1) + '"].on'), prevSrc = prevImg.getAttribute('data-src'), prevCaption = prevImg.getAttribute('data-caption'); modalImage.src = prevSrc; modalAside.textContent = prevCaption; modalImage.dataset.num = prevNum - 1; setTimeout(function () { modalWrapper.classList.remove('spinner'); }, 200); }, 300); } function next() { document.body.style.overflowY = 'hidden', html.classList.add('is-fixed'); modalWrapper.classList.add('spinner'); modalImage.classList.add('off'); modalImage.classList.remove('show'); modalPrev.style.visibility = 'hidden'; modalNext.style.visibility = 'hidden'; setTimeout(function () { modalImage.classList.remove('off'); modalImage.classList.add('show'); let nextNum = parseInt(modalImage.getAttribute('data-num')); modalPrev.style.visibility = 'visible'; if (!document.querySelector('[data-num="' + (nextNum + 2) + '"].on')) { modalNext.style.visibility = 'hidden'; modalPrev.style.visibility = 'visible'; } else { modalNext.style.visibility = 'visible'; modalPrev.style.visibility = 'visible'; } let nextImg = document.querySelector('[data-num="' + (nextNum + 1) + '"].on'), nextSrc = nextImg.getAttribute('data-src'), nextCaption = nextImg.getAttribute('data-caption'); modalImage.src = nextSrc; modalAside.textContent = nextCaption; modalImage.dataset.num = nextNum + 1; setTimeout(function () { modalWrapper.classList.remove('spinner'); }, 200); }, 300); } /* modal ------------------------------------------------ end */ }); if (!HTMLElement.prototype.swipe) { Object.defineProperty(HTMLElement.prototype, "swipe", { configurable: true, enumerable: false, writable: true, value: function (direction, callback, sensitivity) { const self = this; const sens = Object.prototype.toString.call(sensitivity) !== '[object Number]' || sensitivity <= 0 ? 5 : sensitivity; switch (direction) { case 'left': self.addEventListener('touchstart', function (event) { self.removeEventListener("touchstart", null, false); let position = event.changedTouches[0].pageX; self.addEventListener('touchend', function (event) { self.removeEventListener("touchend", null, false); if (event.changedTouches[0].pageX < position - screen.width / sens) { callback(self); } position = 0; }); }, false); break; case 'right': self.addEventListener('touchstart', function (event) { self.removeEventListener("touchstart", null, false); let position = event.changedTouches[0].pageX; self.addEventListener('touchend', function (event) { self.removeEventListener("touchend", null, false); if (event.changedTouches[0].pageX > position + screen.width / sens) { callback(self); } position = screen.width; }); }, false); break; } } }); } // これが動かない if (!HTMLElement.prototype.drag) { Object.defineProperty(HTMLElement.prototype, "drag", { configurable: true, enumerable: false, writable: true, value: function (direction, callback, sensitivity) { const self = this; const sens = Object.prototype.toString.call(sensitivity) !== '[object Number]' || sensitivity <= 0 ? 5 : sensitivity; switch (direction) { case 'left': self.addEventListener('mousedown', function (event) { self.removeEventListener("mousedown", null, false); let position = event.pageX; self.addEventListener('mouseup', function (event) { self.removeEventListener("mouseup", null, false); if (event.pageX < position - screen.width / sens) { callback(self); } position = 0; }); }, false); break; case 'right': self.addEventListener('mousedown', function (event) { self.removeEventListener("mousedown", null, false); let position = event.pageX; self.addEventListener('mouseup', function (event) { self.removeEventListener("mouseup", null, false); if (event.pageX > position + screen.width / sens) { callback(self); } position = screen.width; }); }, false); break; } } }); }
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-02"> </div> <aside>モーダルサンプル 02 / data-group でグループ化</aside> </div> <!-- image modal --> <div class="modal-wrapper spinner"> <div class="modal-img"> <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>
css
.modal-wrapper { opacity: 0; } .modal-wrapper.show { opacity: 1; } .modal-img img { opacity: 0; } .modal-img img.show { opacity: 1; }
試したこと
ドラッグで時々動くんですが、安定して動かすにはどうすればいいいか分かりません。
どうかご助力いただけないでしょうか。
補足情報(FW/ツールのバージョンなど)
Firefox 最新版
だらだら書きすぎです
もっとシンプルな例で質問できないのでしょうか?
そもそもモーダルは画面の真ん中に表示しませんか?
まだ回答がついていません
会員登録して回答してみよう