As janelas modais que merecemos

Vamos começar


Em critérios e manifestações de qualidade diferentes, existe um item como o bloqueio da rolagem da página quando uma janela modal é aberta. Uma janela modal implica interação apenas com ela.

Muitos farão a pergunta: "Por que não usar soluções prontas?". O problema é que essa funcionalidade não é implementada ou é muito mal executada. Você pode usar a solução mais simples e pior:

.body { overflow: hidden;} 

Aqui temos uma ligeira contração da página. Código Vale a pena notar: o problema ocorre apenas onde a rolagem ocorre na página, por exemplo, no Safari não existe esse problema.

Problema de Animação (Gif)


Algumas soluções nos espaços abertos npm oferecem a substituição do rolo por um recuo ou bloco denominado rolo (uma simples barra cinza), muita mágica, mas eles não corrigem o problema.

Ajustaremos um pouco o código inicial e tudo funcionará:

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

Agora, outro problema apareceu: a página sobe. Código A solução através de js é simples: ao abrir a página, pegamos o valor em que a página é rolada e configuramos esse valor para a propriedade top da tag 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) //  ,   }) 

Às vezes, no site, pode haver uma página com pouco conteúdo e sem rolagem, mas quando você abre uma janela modal, nosso código a adiciona. Vamos modificar um pouco o pergaminho. Solução pronta .

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

Disponibilidade


Se você não pensar, haverá um possível movimento usando uma guia fora da janela modal. No gif, basta pressionar Tab algumas vezes.

Problema de Animação (Gif)


Na Internet, não há uma solução simples para esse problema, e escrever sua bicicleta de muleta não é muito racional quando existe uma biblioteca focus-trap.js . Aqui, o autor revelou com mais detalhes o tópico das bibliotecas e seus problemas .

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

Sumário


Mesmo se houver várias janelas modais na página, você pode agrupar todo o código em uma função e passar o nome da classe da janela modal.

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

O problema à primeira vista é simples, mas há tantos momentos não óbvios. Acho que este artigo o ajudará a criar melhores janelas modais. Código pronto

Materiais úteis


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


All Articles