Les fenêtres modales que nous méritons

Commençons


Dans différents critères et manifestes de qualité, il existe un élément tel que le défilement de la page de blocage lorsqu'une fenêtre modale est ouverte. Une fenêtre modale implique une interaction uniquement avec elle.

Beaucoup poseront la question: «Pourquoi ne pas utiliser des solutions toutes faites?». Le problème est que cette fonctionnalité n'est pas du tout implémentée ou est mal exécutée. Vous pouvez utiliser la solution la plus simple et la pire:

.body { overflow: hidden;} 

Ici, nous obtenons une légère contraction de la page. Code Il convient de noter: le problème se produit uniquement là où le défilement a lieu sur la page, par exemple, dans Safari, il n'y a pas un tel problème.

Problème d'animation (Gif)


Certaines solutions dans les espaces ouverts de npm proposent de remplacer un défilement par un retrait ou un bloc qui ressemble à un défilement (une simple barre grise), beaucoup de magie, mais ils ne résolvent pas le problème.

Nous allons modifier un peu le code initial et tout fonctionne:

 .body { position:fixed; overflow-y: scroll; } 

Maintenant, un autre problème est apparu: la page saute. Code La solution via js est simple: lors de l'ouverture de la page, nous prenons la valeur de défilement de la page et définissons cette valeur sur la propriété supérieure de la balise de code <body>.

 function getBodyScrollTop() { return self.pageYOffset || (document.documentElement && document.documentElement.ScrollTop) || (document.body && document.body.scrollTop); } openModalButton.addEventListener('click', e => { e.preventDefault() body.dataset.scrollY = getBodyScrollTop() //    body.style.top = `-${body.dataset.scrollY}px` modal.classList.add('modal--open') body.classList.add('body-lock') }) closeModalButton.addEventListener('click', e => { e.preventDefault() modal.classList.remove('modal--open') body.classList.remove('body-lock') window.scrollTo(0, body.dataset.scrollY) //  ,   }) 

Parfois, sur le site, il peut y avoir une page qui a peu de contenu et pas de défilement, mais lorsque vous ouvrez une fenêtre modale, notre code l'ajoute. Modifions un peu le défilement. Solution prête .

 function existVerticalScroll() { return document.body.offsetHeight > window.innerHeight } openModalButton.addEventListener('click', e => { e.preventDefault() body.dataset.scrollY = getBodyScrollTop() modal.classList.add('modal--open') if(existVerticalScroll()) { //   body.classList.add('body-lock') body.style.top = `-${body.dataset.scrollY}px` } }) closeModalButton.addEventListener('click', e => { e.preventDefault() modal.classList.remove('modal--open') if(existVerticalScroll()) { //   body.classList.remove('body-lock') window.scrollTo(0,body.dataset.scrollY) } }) 

La disponibilité


Si vous n'y pensez pas, il y aura un mouvement possible en utilisant un onglet en dehors de la fenêtre modale. Sur gif, appuyez simplement sur Tab plusieurs fois.

Problème d'animation (Gif)


Sur Internet, il n'y a pas de solution simple à ce problème et l'écriture de votre béquille n'est pas très rationnelle lorsqu'il existe une bibliothèque focus-trap.js . Ici, l'auteur a révélé plus en détail le sujet des bibliothèques et leurs problèmes .

 //     const modalFocusTrap = createFocusTrap(".modal"); //      openModalButton.addEventListener('click', e => { e.preventDefault() body.dataset.scrollY = getBodyScrollTop() modal.classList.add('modal--open') modalFocusTrap.activate(); //  .   if(existVerticalScroll()) { body.classList.add('body-lock') body.style.top = `-${body.dataset.scrollY}px` } }) closeModalButton.addEventListener('click', e => { e.preventDefault() modal.classList.remove('modal--open') modalFocusTrap.deactivate(); //  .   if(existVerticalScroll()) { body.classList.remove('body-lock') window.scrollTo(0,body.dataset.scrollY) } }) 

Résumé


Même s'il y a plusieurs fenêtres modales sur la page, vous pouvez encapsuler tout le code dans une fonction et passer le nom de classe de la fenêtre modale.

 function initModal(className) { // ,        } initModal('modalName1') initModal('modalName2') 

Le problème à première vue est simple, mais il y a tellement de moments non évidents. Je pense que cet article vous aidera à faire de meilleures fenêtres modales. Code prêt

Matériaux utiles


Source: https://habr.com/ru/post/fr483114/


All Articles