Красивые всплывающие диалоговые окна.

Вступление.

Нельзя представить полноценные динамические страницы без всплывающих окон — pop-up. Поэтому в этой статье мы рассмотрим несколько вариантов создания и появления pop-up на странице сайта. Не будем подробно останавливаться на том, что представляет из себя всплывающее окно. Со всей уверенность скажу, что вы неоднократно сталкивались с ними и знаете, что это такое.

Не будем ходить вокруг да около, а сразу приступим к делу — поставим задачу, что же мы хотим получить на выходе.

Итак, давайте создадим три всплывающих окна с эффектами анимации: fadeIn / fadeOut и slideInDown / slideOutUp, которые будет применяться как к подложке (overlay), так и к самому окну. Кроме этого, к одному из всплывающих окон, мы применим js-анимацию, чтобы оно было расположено точно по центру экрана, не зависимо от разрешения монитора и даже после ресайзинга страницы.

Также я уверен, что вам приходилось сталкиваться с ситуациями, когда на одной странице могли выводиться разные всплывающие окна, содержащие, соответственно, разную информацию. Такое часто встречается в лендингах, когда в одном pop-up содержится форма заказа, а в другом предлагают ввести данные для связи с вами. Давайте и мы с вами сделаем точно также.

Теперь настал черёд поговорить об управлении, которое мы сделаем для всплывающего окна.

  1. Открытие всплывающего окна. Один и тот же pop-up может открываться по клику на разные интерактивные элементы, расположенные в разных местах страницы.

  2. Закрытие всплывающего окна. Pop-up мы будем закрывать тремя способами:
    — во-первых, стандартным способом, кликом по крестику в правом верхнем углу всплывающего окна;
    — во-вторых, по клику на любое место экрана вне всплывающего окна, т. е., по оверлею, который перекрывает и затеняет контент страницы и, при этом, занимает всю площадь экрана, имея ширину и высоту равные 100%;
    — в-третьих, клавишей Esc.

Итак, вроде со всем определились и давайте теперь перейдём к созданию непосредственно всплывающего окна.

HTML-разметка всплывающего окна.

Мы не будем создавать сложную вёрстку на HTML. Создадим overlay, два всплывающих окна и по две кнопки для каждого pop-up, которые их будут открывать. Вёрстка будет практически одинаковая для всех вариантов анимации открытия и закрытия всплывающих окон.

Начнём с интерактивных элементов — кнопок, которые будут открывать наши всплывающие окна:

Обратите внимание на атрибут [data-modal], который прописан у каждой кнопки. В нём указывается id всплывающего окна, которое эта кнопка открывает.

Вы, наверное, заметили, что у некоторых элементов (<div class="overlay"> и <span class="closer">) присутствует атрибут [data-close]. С помощью этого атрибута можно определить все элементы на странице, которые могут закрыть всплывающие окна. В частности, <span class="closer"> — это крестик в правом верхнем углу соответствующего pop-up.

Таблица стилей для всплывающих окон.

Приведём здесь только стили, относящиеся к анимации на CSS3, всё-такие наша основная задача — прокачать скилл владения JavaScript.

Полный код таблицы стилей вы можете взять из архива. Отметим здесь только некоторые особенности.

И подложке, и всплывающему окну задано position: fixed;. Для чего это необходимо? Во-первых, их позиционирование будет осуществляться относительно границ экрана, а не документа. Во-вторых, при прокручивании колёсика мыши, позиционирование overlay и pop-up останется неизменным.

Продолжая разговор о позиционировании, остановимся подробнее на положении всплывающего окна. По вертикали задано смещение top: 180px;, т. е. расстояние от верхнего края экрана монитора составит 180px. Вы можете установить своё значение — это совершенно не принципиально.
По горизонтали нам необходимо всплывающее окно установить точно по центру. Это делается в два этапа:

  • 1

    Задаём pop-up отступ слева равным 50% — left: 50%;, при этом его левая граница будет совпадать с центром экрана по горизонтали.

  • 2

    Уменьшим отступ слева на половину ширины pop-up c помощью свойства ‘margin-left’ с отрицательным значением — margin-left: -288px;. Теперь центр по горизонтали у всплывающего окна совпадает с центром экрана.

Пишем JavaScript для управления всплывающими окнами с помощью CSS3.

И вот теперь мы добрались до самого главного — написания скрипта на чистом JavaScript, который будет управлять появлением и исчезновением всплывающих окон. Начнём, как обычно с ограничения области видимости и разместим скрипт в анонимной самозапускающейся функции.

Первым делом, что нам нужно сделать — это объявить несколько переменных, очень важных для нормального функционирования скрипта и присвоить им значения.

Мы получили коллекцию элементов mOpen. Обойдём каждый элемент в коллекции с помощью метода forEach. Этот метод совершает обход коллекции mOpen и назначает обработчик вызовом метода addEventListener для каждого элемента. После срабатывания обработчика, мы определяем, какое именно окно должно быть открыто и запускаем функцию modalShow, которая и откроет нужный нам pop-up.

Рассмотрим теперь по шагам работу функции modalShow.

  • 1

    Добавляем оверлею класс .fadeIn. Этот класс создаёт анимацию — плавное появление подложки в течение 0.4 сек. Предварительно (если есть) удаляем класс .fadeOut.

  • 2

    Определяем тип анимации появления всплывающего окна. Этот тип прописан в переменой typeAnimate. На этапе вёрстки, необходимо в самом низу страницы, перед тегом </body>, но выше кода подключения js-скрипта, который мы сейчас пишем, добавить одну из двух строк, которые определяют тип анимации появления всплывающего окна:

    Если typeAnimate == 'fade', добавляем объекту всплывающего окна modal класс .fadeIn, предварительно удалив (если есть) класс .fadeOut.
    Если typeAnimate == 'slide', то добавляем класс .slideInDown, а удаляем класс .slideOutUp.

  • 3

    Поднимаем флаг mStatus, присваивая ему значение true. Этот флаг сообщает, что всплывающее окно открыто.

Полный код функции modalShow:

Итак, в результате работы нашей функции мы видим оверлей во всей размер экрана, затеняющий основной контент, и по центру экрана (в горизонтальной плоскости) всплывающее окно с отступом от верхнего края равным 180px.

Теперь нам нужно написать функцию, которая закроет и подложку, и pop-up.

В самом начале скрипта мы создали коллекцию элементов mClose, клики по которым закроют всплывающее окно. Для этого необходимо повесить обработчик события на каждый элемент. Мы опять воспользуемся методами forEach и addEventListener. Если событие click наступило, то вызывается функция modalClose.

Ранее мы решили, что будем закрывать всплывающее окно не только по клику на элементы страницы, но и нажатием на клавишу Esc. Давайте тогда и на неё повесим обработчик события, используя всё тот же метод addEventListener.

Наконец настало время разобраться с работой функции modalClose. Сама по себе функция не сложная и напоминает функцию modalShow. Основное отличие между ними в том, что код функции modalClose находится внутри условия:

Разберём условие выполнения функции подробнее: код функции начнёт выполняться, если есть открытое всплывающее окно (вот зачем нам был нужен флаг mStatus) и нажата клавиша Esc (её код — 27).

Мы разобрались как открыть и закрыть всплывающее окно с помощью анимации основанной на CSS3. Настало время понять, как сделать аналогичную анимацию с помощью JavaScript.

Пишем JavaScript для управления всплывающими окнами с применением js-анимации.

У вас может возникнуть резонный вопрос, а зачем нам нужна js-анимация, если нужный нам эффект можно спокойно, без лишних затрат ресурсов, реализовать с помощью CSS3? Всё правильно, но иногда бывает необходимо динамически изменять исходные данные и CSS3 нам уже в такой ситуации не помощник.

Давайте реализуем следующую задачу: всплывающее окно должно появляться с эффектом slide и должно расположиться точно по центру экрана. Если пользователь изменит после этого размер окна браузера, всплывающее окно всё-равно останется по центру.

HTML-вёрстка и стили для всплывающего окна

Вёрстку и таблицу стилей мы возьмём из предыдущего примера, внеся в них минимальные изменения.
Добавим ещё один <div> в HTML-вёрстку:

и поместим в него наши всплывающие окна. К этому <div> и будем применять js-анимацию.
Уберём из всплывающих окон <span class="closer">, клик по которому закрывал их, добавив этот <span> новому элементу.

Добавим новые стили:

Готовим анимацию всплывающего окна.

За основу возьмём код из написанного ранее скрипта. Повторяющиеся участки кода мы не будем разбирать подробно, а всё внимание уделим обновлениям и добавлениям.

Начнём с того, что объявим несколько новых переменных и присвоим им значения:

После объявления переменных, необходимо вызвать функцию setTopOuter для начального позиционирования outer по вертикали. Именно к этому объекту будет применяться анимация на JavaScript путём изменения значения свойства top.
Рассмотрим подробнее начальное позиционирование. В исходном состоянии <div class="modal-outer"> должен быть выше верхней границы экрана, другими словами: нижняя граница <div> должна совпадать с верхней границей экрана. Для этого мы получим высоту <div> и используем её, как значение свойства top для отрицательного смещения по вертикали.

Положение элемента относительно границ экрана

Анимация появления всплывающего окна.

После клика по одной из кнопок, открывающих всплывающее окно, вызывается функция modalShow, запускающая анимацию, которая плавно опускает <div class="modal-outer"> к центру экрана.

Теперь давайте подробно, по шагам разберёмся, как будет работать наша анимация и какие входные данные нужны для её правильной работы.

  • 1

    Перед запуском анимации нужно объявить несколько переменных и назначить им значения:
    start, время начала анимации;
    startTop, начальное значение свойства top;
    finalTop, конечное значение свойства top;
    offset, смещение объекта outer за время анимации.

  • 2

    Внутри функции modalShow создадим именованную функцию fn, которая будет рекурсивно вызывать себя до тех пор, пока не закончится анимация. Внутри этой функции объявим и присвоим значения ещё паре переменных:
    now — время прошедшее с начала анимации.
    currTop — текущее значение свойства top изменяющееся в процессе анимации по линейному закону, что вызывает перемещение <div class="modal-outer"> по вертикали. Этот закон перемещения выражен формулой:

    где,
    startTop, значение свойства top при старте анимации;
    offset, расстояние на которое сместится <div class="modal-outer"> за время анимации (см. рисунок выше);
    now, время прошедшее с начала анимации;
    duration, время, в течение которого происходит анимация.

  • 3

    Полученное значение currTop сравниванием с finalTop и если оно больше, то присваиваем ему значение finalTop. Это необходимо для того, чтобы перемещаемый контейнер по окончанию анимации встал точно на рассчитанное ранее место.

  • 4

    Повторно сравним currTop с finalTop и, если, текущее значение не достигло окончательного, вызовем функцию fn через рекурсию.

Окончательный код функции modalShow, открывающей всплывающее окно:

Запомните, это очень важно.
При создании анимации на JavaScript вместо функции setInterval используйте функцию requestAnimationFrame. Эта функция позволяет синхронизировать анимацию со встроенными в браузер механизмами обновления страницы. Результатом будет более эффективное использование графического ускорителя, исключена повторная обработка одних и тех же участков страницы, меньше будет загрузка процессора и, самое главное, анимация будет более плавная, без рывков и дёрганий.

Анимация закрытия всплывающего окна.

Функция закрытия всплывающего окна практически повторяет функцию открытия. Основное отличие в том, что подложка закрывается после окончания анимации закрытия pop-up. Поэтому не будем рассматривать её подробно, ограничимся небольшими комментариями непосредственно в коде функции.

Позиционирование всплывающего окна при изменении размеров окна браузера

В начале статьи я обещал вам показать, как сохранить позиционирование открытого всплывающего окна при изменении размера окна браузера. Настало время поговорить и об этом. Т. к. по горизонтали pop-up центрируется с помощью CSS и это уже работает, то поговорим о центрировании по вертикали. Хочу обратить ваше внимание, что центрирование по вертикали должно происходить только открытого всплывающего окна, т. к. закрытое окно всегда находится за пределами верхней границы окна браузера.

Реализовано позиционирование будет в простенькой функции, состоящей всего из одной строки:

Вызываться данная функция будет по событию resize. Назначим обработчик события, как обычно, с помощью функции addEventListener.

и запишем этот код в самый конец функции modalShow — как говорилось выше, изменение позиционирования может быть только у открытого всплывающего окна.
Чтобы это условие выполнялось в полном объёме, необходимо после закрытия всплывающего окна, удалить этот обработчик. Для этого в конец функции modalClose необходимо добавить такую строчку:

Итак, мы полностью рассмотрели различные варианты открытия всплывающих окон — и с использованием анимации CSS3, и с применением js-анимации. Хочу добавить только, что по такому же принципу можно сделать появления pop-up из-за нижней или боковой границы окна браузера.

Комментарии

Всего: 4 комментария
Требования при посте комментариев:
  1. Комментарии должны содержать вопросы и дополнения по статье, ответы на вопросы других пользователей.
    Комментарии содержащие обсуждение политики, будут безжалостно удаляться.
  2. Для удобства чтения Вашего кода, не забываейте его форматировать. Вы его можете подсветить код с помощью тега <pre>:
    <pre class="lang:xhtml"> - HTML;
    <pre class="lang:css"> - CSS;
    <pre class="lang:javascript"> - JavaScript.
  3. Если что-то не понятно в статье, постарайтесь указать более конкретно, что именно не понятно.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *