前提・実現したいこと
vanilla jsで画像モーダルを作っています。スワイプ時のようにマウスドラッグでもモーダルをめくれるようにしたいです。
発生している問題・エラーメッセージ
エラーはなし
該当のソースコード
js
1document.addEventListener('DOMContentLoaded', function () { 2 /* modal ---------------------------------------------------- */ 3 const html = document.querySelector('html'); 4 const modalWrapper = document.getElementsByClassName('modal-wrapper')[0]; 5 const images = document.querySelectorAll('.modal-imgs'); 6 const modalImgWrp = document.getElementsByClassName('modal-img')[0]; 7 const modalImage = document.querySelector('.modal-img img'); 8 const modalAside = document.getElementsByClassName('modal-aside')[0]; 9 const modalPrev = document.getElementsByClassName('mp-prev')[0]; 10 const modalNext = document.getElementsByClassName('mp-next')[0]; 11 const modalClose = document.getElementsByClassName('mp-close')[0]; 12 if (modalWrapper != null) { 13 let listItems = document.querySelectorAll('.modal-imgs'), 14 listItem = Array.prototype.slice.call(listItems, 0); 15 listItem.forEach(function ($listItem, i) { 16 let imageSrc = $listItem.getAttribute('data-src'), 17 imageCaption = $listItem.getAttribute('data-caption'); 18 $listItem.dataset.num = (i + 1); 19 $listItem.addEventListener('click', function () { 20 document.body.style.overflowY = 'hidden', html.classList.add('is-fixed'); 21 let imageGroup = this.getAttribute('data-group'); 22 images.forEach(function (img) { 23 if (img.getAttribute('data-group') === imageGroup) { 24 img.classList.add('on'); 25 } 26 }); 27 modalImage.dataset.num = this.getAttribute('data-num'); 28 let thisNum = parseInt(modalImage.getAttribute('data-num')); 29 if (!document.querySelector('[data-num="' + (thisNum - 1) + '"].on')) { 30 modalPrev.style.visibility = 'hidden'; 31 } else { 32 modalPrev.style.visibility = 'visible'; 33 } 34 if (!document.querySelector('[data-num="' + (thisNum + 1) + '"].on')) { 35 modalNext.style.visibility = 'hidden'; 36 } else { 37 modalNext.style.visibility = 'visible'; 38 } 39 modalWrapper.classList.add('show'); 40 modalWrapper.classList.add('spinner'); 41 modalImage.classList.add('show'); 42 modalImage.src = imageSrc; 43 modalAside.textContent = imageCaption; 44 setTimeout(function () { 45 modalWrapper.classList.remove('spinner'); 46 }, 200); 47 }); 48 }); 49 modalPrev.addEventListener('click', function () { 50 prev(); 51 }); 52 modalNext.addEventListener('click', function () { 53 next(); 54 }); 55 modalImage.swipe('left', function () { 56 next(); 57 }, 10); 58 modalImage.swipe('right', function () { 59 prev(); 60 }, 10); 61 modalImage.drag('left', function () { 62 next(); 63 }, 100); 64 modalImage.drag('right', function () { 65 prev(); 66 }, 100); 67 }; 68 69 function prev() { 70 document.body.style.overflowY = 'hidden', html.classList.add('is-fixed'); 71 modalWrapper.classList.add('spinner'); 72 modalImage.classList.add('off'); 73 modalImage.classList.remove('show'); 74 modalPrev.style.visibility = 'hidden'; 75 modalNext.style.visibility = 'hidden'; 76 setTimeout(function () { 77 modalImage.classList.remove('off'); 78 modalImage.classList.add('show'); 79 let prevNum = parseInt(modalImage.getAttribute('data-num')); 80 modalNext.style.visibility = 'visible'; 81 if (!document.querySelector('[data-num="' + (prevNum - 2) + '"].on')) { 82 modalPrev.style.visibility = 'hidden'; 83 modalNext.style.visibility = 'visible'; 84 } else { 85 modalPrev.style.visibility = 'visible'; 86 modalNext.style.visibility = 'visible'; 87 } 88 let prevImg = document.querySelector('[data-num="' + (prevNum - 1) + '"].on'), 89 prevSrc = prevImg.getAttribute('data-src'), 90 prevCaption = prevImg.getAttribute('data-caption'); 91 modalImage.src = prevSrc; 92 modalAside.textContent = prevCaption; 93 modalImage.dataset.num = prevNum - 1; 94 setTimeout(function () { 95 modalWrapper.classList.remove('spinner'); 96 }, 200); 97 }, 300); 98 } 99 100 function next() { 101 document.body.style.overflowY = 'hidden', html.classList.add('is-fixed'); 102 modalWrapper.classList.add('spinner'); 103 modalImage.classList.add('off'); 104 modalImage.classList.remove('show'); 105 modalPrev.style.visibility = 'hidden'; 106 modalNext.style.visibility = 'hidden'; 107 setTimeout(function () { 108 modalImage.classList.remove('off'); 109 modalImage.classList.add('show'); 110 let nextNum = parseInt(modalImage.getAttribute('data-num')); 111 modalPrev.style.visibility = 'visible'; 112 if (!document.querySelector('[data-num="' + (nextNum + 2) + '"].on')) { 113 modalNext.style.visibility = 'hidden'; 114 modalPrev.style.visibility = 'visible'; 115 } else { 116 modalNext.style.visibility = 'visible'; 117 modalPrev.style.visibility = 'visible'; 118 } 119 let nextImg = document.querySelector('[data-num="' + (nextNum + 1) + '"].on'), 120 nextSrc = nextImg.getAttribute('data-src'), 121 nextCaption = nextImg.getAttribute('data-caption'); 122 modalImage.src = nextSrc; 123 modalAside.textContent = nextCaption; 124 modalImage.dataset.num = nextNum + 1; 125 setTimeout(function () { 126 modalWrapper.classList.remove('spinner'); 127 }, 200); 128 }, 300); 129 } 130 /* modal ------------------------------------------------ end */ 131}); 132 133if (!HTMLElement.prototype.swipe) { 134 Object.defineProperty(HTMLElement.prototype, "swipe", { 135 configurable: true, 136 enumerable: false, 137 writable: true, 138 value: function (direction, callback, sensitivity) { 139 const self = this; 140 const sens = Object.prototype.toString.call(sensitivity) !== '[object Number]' || sensitivity <= 0 ? 5 : sensitivity; 141 switch (direction) { 142 case 'left': 143 self.addEventListener('touchstart', function (event) { 144 self.removeEventListener("touchstart", null, false); 145 let position = event.changedTouches[0].pageX; 146 self.addEventListener('touchend', function (event) { 147 self.removeEventListener("touchend", null, false); 148 if (event.changedTouches[0].pageX < position - screen.width / sens) { 149 callback(self); 150 } 151 position = 0; 152 }); 153 }, false); 154 break; 155 case 'right': 156 self.addEventListener('touchstart', function (event) { 157 self.removeEventListener("touchstart", null, false); 158 let position = event.changedTouches[0].pageX; 159 self.addEventListener('touchend', function (event) { 160 self.removeEventListener("touchend", null, false); 161 if (event.changedTouches[0].pageX > position + screen.width / sens) { 162 callback(self); 163 } 164 position = screen.width; 165 }); 166 }, false); 167 break; 168 } 169 } 170 }); 171} 172 173// これが動かない 174if (!HTMLElement.prototype.drag) { 175 Object.defineProperty(HTMLElement.prototype, "drag", { 176 configurable: true, 177 enumerable: false, 178 writable: true, 179 value: function (direction, callback, sensitivity) { 180 const self = this; 181 const sens = Object.prototype.toString.call(sensitivity) !== '[object Number]' || sensitivity <= 0 ? 5 : sensitivity; 182 switch (direction) { 183 case 'left': 184 self.addEventListener('mousedown', function (event) { 185 self.removeEventListener("mousedown", null, false); 186 let position = event.pageX; 187 self.addEventListener('mouseup', function (event) { 188 self.removeEventListener("mouseup", null, false); 189 if (event.pageX < position - screen.width / sens) { 190 callback(self); 191 } 192 position = 0; 193 }); 194 }, false); 195 break; 196 case 'right': 197 self.addEventListener('mousedown', function (event) { 198 self.removeEventListener("mousedown", null, false); 199 let position = event.pageX; 200 self.addEventListener('mouseup', function (event) { 201 self.removeEventListener("mouseup", null, false); 202 if (event.pageX > position + screen.width / sens) { 203 callback(self); 204 } 205 position = screen.width; 206 }); 207 }, false); 208 break; 209 } 210 } 211 }); 212} 213
html
1<!-- gallery --> 2<div class="img-fit-01"> 3 <div class="aspect-box spinner"> 4 <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"> 5 </div> 6 <aside>モーダルサンプル 02 / data-group でグループ化</aside> 7</div> 8 9<!-- image modal --> 10<div class="modal-wrapper spinner"> 11 <div class="modal-img"> 12 <div class="mid"><img alt src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="></div> 13 <div class="mp-prev"></div> 14 <div class="mp-next"></div> 15 <div class="mp-close"></div> 16 <aside class="modal-aside">xxx</aside> 17 </div> 18</div>
css
1.modal-wrapper { 2 opacity: 0; 3} 4 5.modal-wrapper.show { 6 opacity: 1; 7} 8 9.modal-img img { 10 opacity: 0; 11} 12 13.modal-img img.show { 14 opacity: 1; 15}
試したこと
ドラッグで時々動くんですが、安定して動かすにはどうすればいいいか分かりません。
どうかご助力いただけないでしょうか。
補足情報(FW/ツールのバージョンなど)
Firefox 最新版
だらだら書きすぎです
もっとシンプルな例で質問できないのでしょうか?
そもそもモーダルは画面の真ん中に表示しませんか?
回答1件
あなたの回答
tips
プレビュー