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

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

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.
Avatar for yomotsu yomotsu
September 16, 2022

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

Avatar for yomotsu

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 ); }