質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

解決済

画像モーダルをマウスドラッグに対応させたい

erp
erp

総合スコア45

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

1回答

-1評価

0クリップ

314閲覧

投稿2022/01/06 17:04

編集2022/01/06 22:41

前提・実現したいこと

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 最新版

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

yambejp

2022/01/07 04:57 編集

だらだら書きすぎです もっとシンプルな例で質問できないのでしょうか? そもそもモーダルは画面の真ん中に表示しませんか?

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。