====== Modal Dialog ====== ===== 要求 ===== * 素早く簡単に Modal Dialiaog が実装できるよう、コンポーネント化したい。 ===== Code ===== import { ref, reactive } from 'https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.2/vue.esm-browser.js'; const ModalContainer = { template: ` .modal { display: none; } .modal-backdrop { z-index: 0; background: rgba(0, 0, 0, 0.4); } /* vueのtransitionを使わないなら不要 */ .fade-enter-active, .fade-leave-active { transition: opacity .15s; } .fade-enter, .fade-leave-to { opacity: 0; }
`, props: { enableBackdrop: { type: Boolean, default: true }, title: { type: String, default: '' }, size: { type: String, default: 'modal-sm' } }, setup(props, context) { const visible = ref(false) const display_mode = reactive({display: 'none'}) let scrollbarWidth = 0; let orgBodyPaddingRight = 0; // let orgBodyPosition = 'relative'; function show() { scrollbarWidth = window.innerWidth - document.body.clientWidth; orgBodyPaddingRight = document.body.style.paddingRight; // orgBodyPosition = document.body.style.position; // document.body.style.position = 'fixed'; if (scrollbarWidth ) { document.body.style.paddingRight = `${scrollbarWidth }px`; } // document.body.style.position = 'fix'; document.body.style.height = '100vh'; document.body.style.overflowY = 'hidden'; visible.value = true; display_mode.display = 'block'; } function hide(event) { if (event && event.target.classList.contains('modal-backdrop') && !props.enableBackdrop) return; if (scrollbarWidth ) { document.body.style.paddingRight = orgBodyPaddingRight; } // document.body.style.position = orgBodyPosition; document.body.style.height = 'auto'; document.body.style.overflowY = 'auto'; visible.value = false; display_mode.display = 'none'; } return { visible, display_mode, show, hide } } }; export default ModalContainer;
===== Props ===== * size: サイズ * title: タイトル * enableBackdrop: バックドロップの有効化 ===== Slots ===== * header スロット * body スロット * footer スロット ===== Events ===== * None ===== Demo =====
===== Bootstrap バージョンよる記述の違い調査 ===== ==== BS5 の実装 ==== ==== BS4 の実装 ==== ==== BS3 の実装 ==== ◆ BS3 .modal-open .modal { overflow-x: hidden; overflow-y: auto; } .fade.in { opacity: 1; } .modal-backdrop.in { filter: alpha(opacity=50); opacity: .5; } .modal-backdrop.fade { filter: alpha(opacity=0); opacity: 0; } .modal { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1040; display: none; overflow: hidden; -webkit-overflow-scrolling: touch; outline: 0; } .modal-backdrop { position: absolute; top: 0; right: 0; left: 0; background-color: #000; } .fade { opacity: 0; -webkit-transition: opacity .15s linear; -o-transition: opacity .15s linear; transition: opacity .15s linear; } * div のネストや指定が必要な CSS クラスもほぼ同様 手動でモーダルを表示するには、いろいろとやることがある * div.modal.fade を div.modal.fade.in に変更 * div.modal-backdrop の z-index を削除 * これでも裏のページがスクロールしてしまうので、以下の対策を。。。 https://coliss.com/articles/build-websites/operation/javascript/prevent-page-scrolling-when-a-modal-is-open.html