Upgrade to Pro — share decks privately, control downloads, hide ads and more …

dialog要素でつくるモーダルダイアログ

yomotsu
September 16, 2022

 dialog要素でつくるモーダルダイアログ

yomotsu

September 16, 2022
Tweet

More Decks by yomotsu

Other Decks in Programming

Transcript

  1. <!-- モーダル --> <dialog id="my-modal"> <p>簡易モーダル</p> </dialog> 
 <!-- 開くボタン

    --> <button type="button" onclick="document.querySelector('#my-modal').showModal();" > 開く </button>
  2. <!-- モーダル --> <dialog id="my-modal"> <p>簡易モーダル</p> </dialog> 
 <!-- 開くボタン

    --> <button type="button" onclick="document.querySelector('#my-modal').showModal();" > 開く </button>
  3. <!-- モーダル --> <dialog id="my-modal"> <p>簡易モーダル</p> </dialog> 
 <!-- 開くボタン

    --> <button type="button" onclick="document.querySelector('#my-modal').showModal();" > 開く </button>
  4. <!-- モーダル --> <dialog id="my-modal"> <p>簡易モーダル</p> <button type="button" onclick="document.querySelector( '#my-modal'

    ).close();" > 閉じる </button> </dialog> 
 <!-- 開くボタン --> <button type="button" onclick="document.querySelector('#my-modal').showModal();" > 開く </button>
  5. const $modal = document.querySelector( '#my-modal' ); $modal.removeEventListener( 'click', onDialogClick );

    function onDialogClick( event ) { const elRect = $modal.getBoundingClientRect(); const isInDialog = elRect.top <= event.clientY && event.clientY <= elRect.bottom && elRect.left <= event.clientX && event.clientX <= elRect.right; // もし、内側をクリックしていたら、なにもしない if ( isInDialog ) return; // それ以外(外側をクリック)なら閉じる $modal.close(); }
  6. const $modal = document.querySelector( '#my-modal' ); $modal.removeEventListener( 'click', onDialogClick );

    function onDialogClick( event ) { const elRect = $modal.getBoundingClientRect(); const isInDialog = elRect.top <= event.clientY && event.clientY <= elRect.bottom && elRect.left <= event.clientX && event.clientX <= elRect.right; // もし、内側をクリックしていたら、なにもしない if ( isInDialog ) return; // それ以外(外側をクリック)なら閉じる $modal.close(); }
  7. .myModal:modal { animation: fadeIn 1s 1; } .myModal:modal::backdrop { animation:

    fadeIn 1s 1; } NPEBMٖࣅΫϥε͸ 
 ϙϦϑΟϧͰ͖ͳ͍
  8. dialog.myModal { opacity: 0; transform: scale( .9 ); transition: opacity

    .5s, transform .5s; } dialog.myModal.-opening { opacity: 1; transform: scale( 1 ); }
  9. const showModal = ( id ) => { const $modal

    = document.getElementById( id ); $modal.showModal(); requestAnimationFrame( () => $modal.classList.add( '-opening' ) ); } ϑϨʔϜ଴͔ͬͯΒ 
 ΫϥεΛ෇༩͢Δ
  10. const closeModal = ( id ) => { const $modal

    = document.getElementById( id ); $modal.classList.remove( '-opening' ); $modal.addEventListener( 'transitionend', $modal.close, { once: true } ); } Ξχϝʔγϣϯ׬ྃΛ଴ͬͯ 
 DMPTF͢Δ
  11. const showModal = ( id ) => { const $modal

    = document.getElementById( id ); $modal.showModal(); noScroll.on(); // ϖʔδຊମͷεΫϩʔϧΛ཈ࢭ͢Δ $modal.addEventListener( 'cancel', onClose ); $modal.addEventListener( 'close', onClose ); } EJBMPHͷDMPTF͸ 
 DBODFM͔DMPTFΠϕϯτͰ ݕ஌Ͱ͖Δ
  12. const onClose = ( event ) => { noScroll.off(); //

    ページ本体のスクロール抑止解除 const $modal = event.target; $modal.removeEventListener( 'cancel', onClose ); $modal.removeEventListener( 'close', onClose ); }