ы howto use modal window in web
× К оглавлению На главную Об авторе

Дата и время публикации:

Назначение и применение


1. Назначение

Вид визуальной формы, блокирующий и/или останавливающей работу приложения до тех пор, пока пользователь не закончит c ней работу. При этом такой метод визуализации интерфейса пользователя называют модальным, а вид графического интерфейса – модальное или диалоговое окно.

Диалоговые окна относятся к специальным элементам графического интерфейса, который является "конечной точкой" реализации человеко-машинного интерфейса (ЧМИ) (англ. Human-machine interface, HMI) и обеспечивающего интерактивное взаимодействие оператора(пользователя) с программно-аппаратной средой (вычислительной системой).

Таким образом, использование диалогового окна в модальном режиме позволяет информировать пользователя о важных событиях в "жизни" приложения и/или системы в целом с временным или полным остановом, в т.ч. для ввода пользователем необходимых данных.

Простым примером, такого взаимодействия будет вывод окна сообщения (англ. message box, англ. alert box), которое выводит одну или несколько строк текста и требует от пользователя подтвердить, что он был им прочитано.

2. Реализация

2.1 Суть использования технологий WEB

В документах WEB реализация, вернее её имитация, вывода окна диалога с текстовым сообщением и кнопкой "Закрыть" производится с использованием языка гипертекстовой разметки (англ. HyperText Markup Language), стилей каскадных таблиц CSS и мультипарадигменного языка программирования JavaScript.

2.2 стилей каскадных таблиц CSS

Несмотря на грозные названия перечисленных технологии информационной среды, с помощью которых реализуется данный интерактивный интерфейс, сама реализация достаточна проста, и заключается в отрисовки элемента DIV "поверх" всех остальных элементов документа DOM, которая случится после нажатия кнопки "".

2.2 Использование CSS

Создадим отдельный файл <style/modal.css> в корневой директории сайта класса .modal, как показано в листинге 2.2.1

Листинг 2.2.1

/* Задник модального окна */
.modal {
    display: none;    /* не отображать по умолчанию */
    padding-top: 5%; /*  и установить ориентацию ящика */ 
    left:   0;       /*  при этом */
    top:    0;
    bottom: 0;
    right:  0;
    position: fixed;  /* фиксируем положение */
    z-index: 1000;    /* поверх всех */
    width:   100%;    /* Раскрыть в ширину */
    height:  100%;    /* Раскрыть по высоте  */
    overflow: auto;    /* разрешить прокрутку по необходимости */
    background-color: rgb(0,0,0); /* Фон полностью белый Fallback color */
    background-color: rgba(0,0,0,0.9); /* с оттенками черного */
/*  свойство transform */
    transform: scale(1.1); /* параметры трансформации элемента */
    -ms-transform: scale(1.1); /* по ширине, т.к. значение больше единицы,    */
    -moz-transform: scale(1.1); /* поэтому элемент будет увеличен */
    -o-transform: scale(1.1);
    -webkit-transform: scale(1.1);
/* свойство transition */
    -o-transition: visibility 0s ease 0.25s, opacity 0.25s 0s, transform 0.25s;
    -moz-transition: visibility 0s ease 0.25s, opacity 0.25s 0s, transform 0.25s;
    -ms-transition: visibility 0s ease 0.25s, opacity 0.25s 0s, transform 0.25s;
    -webkit-transition: visibility 0s ease 0.25s, opacity 0.25s 0s, transform 0.25s;
    transition: visibility 0s ease 0.25s, opacity 0.25s 0s, transform 0.25s;
}

Как следует из описания класса .modal, элемент DIV будет привязан к указанной в свойствах padding-top, left и top точке на экране и не изменит своего положения при прокрутке страницы документа. При этом оно (модальное окно) будет находится "поверх" всех остальных его элементов, так как свойству z-index назначается большое значение по сравнению с другими его элементами, у которых обычно оно меньше или равно нулю.

В конце указывается свойство transition, которое позволяет устанавливать значения времени, "частоты" анимации других свойств CSS. В данном случае устанавливаются значения visibility, ease, opacity и transform, которые задают ход изменения прозрачности фона, темпа отображения и времени всех трансформаций модального окна соответственно.

Как показано в листинге 2.2, модальное окно отображается согласно описанию класса .modal-dialog.

Листинг 2.2.2

.modal-dialog {
    margin:           1% auto;  /* берем 1 процент от верха с центрированием и*/
    border: 3px solid #1f4649;  /* рамкой, которая нужна для смягчения */
    border-radius:        5px;  /* краев диалога, поэтому цвет у рамки и*/
    background-color:  #1f4649; /* заднего вида одинаковый. */
    color:             #413f26; 
    vertical-align:    center; 
}

Класс .modal-head отвечает за оформление и геометрию "заголовка" и текстовый надписи, как показано в листинге 2.2.3.

Листинг 2.2.3

.modal-head{
  margin:	     1% auto;    /* центрируем по середине с отступом */
  padding:           0;          /* на 1% от краев окна диалога       */
  color:             #c5cbcb;    /* устанавливаем свойства шрифта и   */
  word-wrap:         break-word; /* и выравнивание текста */
  font-size:         1.4em;
  font-weight:       bold;
  font-style:        italic;
  font-stretch:      condensed;
  font-family: Geneva, Arial, Helvetica, sans-serif;
}

Соответственно, .modal-content отвечает за оформление и позиционирование содержимого, например текста, внутри окна диалога, как показано в листинге 2.2.4.

Листинг 2.2.4

.modal-content {
    overflow:         auto;  /* полосы прокрутки будут автоматически включаться, */
    display:         block;  /* если содержимое блока будет меньше чем его размер */
    margin-top:	     0;
    padding:         1% 1%; 
    font-size:       1.2em; 
    font-family: Georgia, 'Times New Roman', Times, serif;
    color:             #413f26;
    background-color:  #ffffe0;
    border-radius: 5px;
}

Давайте для лучшего восприятия зависимостей перечисленных классов, взглянем на макет модального окна, который показан на рисунке 2.2.1

Рисунок 2.2.1

На нем показана геометрия модального окна и расположение элементов согласно их значений, указанных в свойствах border, padding и margin классов .modal, .modal-dialog, .modal-head и .modal-content.

2.3 Использование JavaScript и HTML

После нажатия кнопки "" будет запущена функция openModalDlg() и сгенерировано (после отпускания левой клавиши "мышки") событие onclick для элемента button, объявление которых в документе HTML показано в листинге 2.3.1 .

Листинг 2.3.1

. . .
< button id="modal-btn-id" onclick="openModalDlg(this.id,'Некоторый техт в модальном окне...')">Модальное окно</button>
. . .      

Из которого видно, что функции openModalDlg(), текст которой приводится в листинге 2.3.2, передаются два аргумента: идентификатор "modal-btn-id" элемента button и текстовое сообщение в качестве содержимого модального окна.

Листинг 2.3.2

. . .
006 /* Объявление глобальных переменных */
007 var mdlTmOutId;
008 var modalId    = null;
009 var btnContext = undefined;
010  
011 function openModalDlg(ident,msg) {   
012    var body       = document.body || document.getElementsByTagName("body")[0];
013    var headName   = document.getElementById(ident);
014    var modal      = document.getElementById('open-'+ident);
015 
016    console.log( getUnixMSecs()+' click '+ident );
017 
018    if ( modal ) {
019       var content = modal.getElementsByClassName('modal-content')[0];
020       content.innerHTML = '<p>'+msg+'</p>';      
021       console.log( getUnixMSecs()+' Modify modal...' );   
022    }else{
023     body.innerHTML = '  \
024 <!-- The Modal behind--> \
025 <div id="'+'open-'+ident+'" class="modal"> \
026   <!-- Modal dialog --> \
027   <div class="modal-dialog"> \
028   <!-- Dialog header --> \
029   <div class="modal-head"><span class="close">&times;</span>'+( ( headName && headName.innerHTML ) || 'Модальное окно')+' </div> \
030   <!-- Dialog content --> \
031      <div class="modal-content"> \
032         <p>'+msg+'</p> \
033      </div> \
034   </div> \
035 </div>' + body.innerHTML;     
036     console.log( getUnixMSecs()+' create modal...' );
037   } 
038 
039   mdlTmOutId = setTimeout( setEventsToModalCallback('open-'+ident), 300 );  
040 }
. . .

В строках 006-007

Объявление глобальных переменных, содержащие:

В строках 012-014

Объявление внутренних переменных, содержащие:

В строке 016

Печатаем в консоль браузера информационное сообщение, что кнопка в нем изволила быть нажатой.

В строках 019-021

Модифицируем содержимое модального окна и печатаем об этом событии в ту же консоль.

В строках 023-036

Создаем модальное окно, добавляя его в начало элемента body, и печатаем об этом событии опять же в консоль.

В строке 039

Делаем трюк с таймером, чтобы браузер успел добавить обновку в редактируемый элемент, при срабатывании оного управление передается функции setEventsToModalCallback(), текст которого приводится в листинге 2.3.3 .

Листинг 2.3.3

. . .
042 function setEventsToModalCallback( ident, onClickModal ) {
043    var modal  = document.getElementById(ident);
044    console.log( getUnixMSecs()+' try to update modal('+ident+')' );
045    if ( modal ) {
046      var span = modal.getElementsByClassName("close")[0];
047      modal.style.display = "block";
048      modalId  = ident;
049      resizeModalWindow (event);
050      span.onclick = function() {
051           modal.style.display = "none";
052      }
053      if ( onClickModal && onClickModal == true )
054          window.onclick = function(event) {
055             if (event.target == modal) {
056               modal.style.display = "none";
057             }
058         }
059       
060      window.onresize = function(event) {
061           resizeModalWindow (event);
062      }
063      console.log( getUnixMSecs()+' clear timeout!' );
064      clearTimeout( mdlTmOutId );
065    }
066 }
. . .

В строках 042-044

Выборка по символьному идентификатору ident, переданного в первом аргументе, элемента modal модального окна и печатаем в консоль браузера о попытке его обновления. При этом второй аругумент onClickModal в настоящее время незадейстован, также как текст в строках 053-058.

В строках 050-052

Осуществляется назначение обработчика событию click, которое испускается при нажатии на символ закрытия модального окна, обозначаемое символом &times в заголовке модального окна, который был определен ранее в строке 29 листинга 2.3.2 (создание элемента SPAN).

В строках 060-064

Назначается обработка событию resize, испускаемое при изменении размера модального окна, и печать на консоль браузера сообщения о процедуре удаления таймера, о которой говорилось ранее. Указанная операция производится с помощью встроенной функции clearTimeout().

Листинг 2.3.4

. . .
068 function resizeModalWindow (event) { 
069     var modal  = document.getElementById(modalId);
070     var wPrcnt     = parseFloat(window.innerWidth || 
071                      document.documentElement.clientWidth || 
072                      document.body.clientWidth || 200.0 )/100.0;
073     var  hPrcnt    = parseFloat(window.innerHeight || 
074                      document.documentElement.clientHeight || 
075                      document.body.clientHeight || 150.0)/100.0;
076     var  wDlgPrcnt = (wPrcnt * 50.0) / 100.0;
077     var  hDlgPrcnt = (hPrcnt * 50.0) / 100.0;
078     
079     var dlg  = modal.getElementsByClassName("modal-dialog")[0];
080     var head = modal.getElementsByClassName("modal-head")[0];
081     var ctnt = modal.getElementsByClassName("modal-content")[0];
082     if ( event )
083        console.log( getUnixMSecs()+' event resize occured( geometry: '+wPrcnt+' X '+hPrcnt+' ).' );
084     else
085        console.log( getUnixMSecs()+' update events( geometry: '+widthPrcnt+' X '+heightPrcnt+' ).' );
086 
087     dlg.style.width   = wDlgPrcnt * 100.0;
088     dlg.style.height  = hDlgPrcnt * 100.0;
089 
090     head.style.width  = wDlgPrcnt * 98.0;
091     head.style.height = hDlgPrcnt * 10.0;
092 
093     ctnt.style.width  = wDlgPrcnt * 98.0; 
094     ctnt.style.height = hDlgPrcnt * 70.0;
095 
096 }
. . .

Как показано в листинге 2.3.4, функция resizeModalWindow() производит перерасчет геометрии модального окна и его элементов в процентном соотношении от половины размера текущей геометрии главного окна документа, которое устанавливется в строках 69-77. Процентные соотношения модальному окну и его элементов – в строках 087-094.

2.4 Пример вывода модального окна и сообщений в консоль

Показан на рисунке 2.4.1

Рисунок 2.4.1

3. Библиография


[1] Толкование слово модальный

[2] Модальное окно

[3] Диалоговое окно

[4] Человеко-машинный интерфейс

[5] Create a Modal Dialog

[6] How TO - CSS/JS Modal

[7] How To Create a Modal Popup Box

[8] CSS свойство. Рosition

[9] CSS3-трансформации

[10]CSS3 transitions using visibility and delay

[11]MDN web docs. CSS transition

[12]How to find the width of a div using raw javascript

[13]Getting width and height of an element

[14]Учебник JavaScript: setTimeout и setInterval