HTMLでModalを子ウィンドウのように使用したい(modelessのように)
現在の環境として
HTML、javascript、BootStrap5、Vue.js3を使用しています。
※サーバーサイドについてはここで触れません。
自分自身のHTMLと、子ウィンドウとは データのやりとりがあるため、
BootStrap5のようにHTML中にModalのHTMLを埋め込む感じで使用したいです。
イメージとして、Modalにロックをかけず、自由に移動できる感じのことが子ウィンドウです。
データのやりとり上も、HTML中に埋め込む必要があります。
※別ウィンドウを開いて、そこから情報取得するような方法はありましたが、それは避けたいです、
BootStrap5のリファレンスを見たところそのような機能がなさそうな感じですが。
もしくはBootStrap5以外の子ウィンドウの方法があれば。
曖昧な質問ですみませんが、どなたかご教授お願いします。
(追記)
教えて頂いた方法で試したところ、openを押すとModalは止まっていて、closeは押せるが、Modalをドラッグすると、カーソルに合わせてModalが動いてしまい、Modalのドロップができあない状況です。
(追記)
Vue.js3 + Bootstrap5で組んだ場合
javascript
1<div id="app"> 2 <div class="row"> 3 <div class="col-md-12"> 4 <div class="plane-modal-wrap"> 5 <button class="plane-modal-open">open</button> 6 </div> 7 </div> 8 </div> 9 10 <div class="plane-modal"> 11 <button class="plane-modal-close">close</button> 12 </div> 13</div> 14 15<script> 16const app = Vue.createApp({ 17 data() { 18 return { 19 20 } 21 }, 22 23 mounted: function () { 24 25 } 26}); 27 28app.mount("#app"); 29 30// 処理はVue外に書きました。クラス名の取得程度であればVue内でもいいかも 31// addEventListenerはVue外かな。 32const open = document.getElementsByClassName("plane-modal-open")[0]; 33const close = document.getElementsByClassName("plane-modal-close")[0]; 34const modal = document.getElementsByClassName("plane-modal")[0]; 35const modalWrap = document.getElementsByClassName("plane-modal-wrap")[0]; 36 37modalWrap.style.height = window.innerHeight + "px"; 38 39open.addEventListener("click", () => { 40 modal.style.display = "block"; 41}); 42 43close.addEventListener("click", () => { 44 modal.style.display = ""; 45}); 46 47let mX; 48let mY; 49let dX; 50let dY; 51 52modal.onmousedown = (e) => { 53 // クリック時のマウスカーソルX座標 54 mX = e.pageX; 55 // クリック時のマウスカーソルY座標 56 mY = e.pageY; 57 // クリック時の要素のX位置 58 dX = window.pageXOffset + modal.getBoundingClientRect().left 59 // クリック時の要素のY座標 60 dY = window.pageYOffset + modal.getBoundingClientRect().top 61 document.addEventListener("mousemove", onMouseMove); 62} 63 64const onMouseMove = (e) => { 65 if (e.pageY < 0 || e.pageY > window.innerHeight || e.pageX < 0 || e.pageX > window.innerWidth) { 66 document.removeEventListener("mousemove", onMouseMove); 67 }; 68 const modalWidth = modal.clientWidth; 69 const modalHeight = modal.clientHeight; 70 const shiftX = -(mX - e.pageX); 71 const shiftY = -(mY - e.pageY); 72 if (dX + shiftX < 0) { 73 modal.style.left = "0px"; 74 } else if (dX + shiftX + modalWidth > window.innerWidth) { 75 modal.style.left = window.innerWidth - modalWidth + "px"; 76 } else { 77 modal.style.left = dX + shiftX + "px"; 78 } 79 if (dY + shiftY < 0) { 80 modal.style.top = "0px"; 81 } else if (dY + shiftY + modalHeight > window.innerHeight) { 82 modal.style.top = window.innerHeight - modalHeight + "px"; 83 } else { 84 modal.style.top = dY + shiftY + "px"; 85 } 86} 87 88modal.onmouseup = () => { 89 document.removeEventListener("mousemove", onMouseMove); 90} 91</script>
css
1<!-- bodyはbootstrapで使用していると思うので消しました。 --> 2.plane-modal { 3 display: none; 4 width: 500px; 5 height: 400px; 6 border: solid 1px black; 7 position: absolute; 8 z-index: 1; 9 background-color: white; 10 top: calc(50% - 200px); 11 left: calc(50% - 250px); 12} 13 14.plane-modal-wrap { 15 width: 100%; 16 position: relative; 17 overflow: hidden; 18 top: 0; 19 left: 0; 20} 21 22.plane-modal-open { 23 z-index: 0; 24} 25 26.plane-modal-close { 27 float: right; 28}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2021/07/14 15:42 編集
2021/07/15 04:02
退会済みユーザー
2021/07/15 04:24
2021/07/15 04:50
退会済みユーザー
2021/07/15 05:11
2021/07/15 05:52 編集
退会済みユーザー
2021/07/15 06:08
退会済みユーザー
2021/07/15 06:34
退会済みユーザー
2021/07/15 06:51
退会済みユーザー
2021/07/16 02:18
2021/07/16 02:23
退会済みユーザー
2021/07/16 02:28 編集
2021/07/16 02:36
退会済みユーザー
2021/07/16 04:22 編集
退会済みユーザー
2021/07/16 04:26