В практике построения интерфейсов на базе web-технологий возникают случаи, когда надо блокировать интерфейс от действий пользователя: запретить клики по ссылкам, выбирать элементы форм и т.п. К сожалению в связке javascript + html не предусмотрено сложных модальных диалоговых окон, которые часто бывают необходимы для получения данных от пользователя (например, окна авторизации). В этих случаях штатных средств функций alert
и confirm
явно недостаточно. Одним из способов эмулирования такой модальности может быть один из приемов, описанный ниже.
Как известно, последние стандарты каскадных стилевых таблиц (CSS) позволяют позиционировать элементы в контексте html страницы с точностью по пиксела (CSS-свойство position=absolute
). С другой стороны элементы в html документе располагаются слоями, так что элементы, описанные ниже по коду, расположены выше и визуально перекрывают элементы, расположенные выше по коду. Такой порядок визуального перекрытия тоже можно поменять с помощью CSS (свойство z-index
, чем выше индекс, тем выше элемент в визуальном представлении). Идея эмуляции модальности состоит в следующем. Создаются два элемента:
z-index=1
(по умолчанию это свойство имеет значение 0);z-index=2
.Первоначально эти два окна находяться с состоянии невидимости (CSS-свойство display=none
). При инициации диалога эти оба окна делают выдимыми (display=block
) и позиционируя "окно-экран" в верхний левый угол с одновременным растяжение на всю площадь документа, а второе "окно-формы" позиционируем по центру. После ввода данных пользователем опять "гасим" эти окна для предоставляния доступа к элементам html-документа.
В эту схему вкрадывается один ньюанс, который надо учитывать. Чтобы блокировать контекст html страницы, "окно-экран" должно быть непрозрачно, иначе элементы под экраном становяться доступными. С другой строны полностью скрывать контекст страницы было бы нежелательно по эстетическим причинам. Поэтому экран должен быть полупрозрачным. Полупрозрачности можно добиться использованием фона с заливкой графикой в формате PNG c альфа-каналом необходимой прозрачности, такой png-файл легко создается в фотошопе. Тут как раз возникает одна сложность. Дело в том, что Internet Explorer не поддерживает полупрозрачность PNG. С другой стороны у Internet Explorer есть возможность применения фильтров, среди которых есть фильтр Alfa, который как раз задает степень прозрачности элемента. Таким образом, нам нужно применить разную тактику использования полупрозрачности в развисимости от типа браузера. Этого мы добьемся с помощью javascript и динамическим созданием html элемента.
<script type="text/javascript">
var isIE = window.navigator.userAgent.indexOf("MSIE")>-1; //true, если браузер - Internet Explorer
var GlassWindow=null; //ссылка на "окно-экран"
var Dialog=null; //ссылка на "окно формы"
// функция ShowGlassWindow показывает/скрывает экран
function ShowGlassWindow(show){
if(GlassWindow==null){
// на первом проходе создаем элемент - "полупрозрачный экран"
GlassWindow=document.createElement('DIV');
with(GlassWindow.style){
//стили экрана после создания
display='none'; //невидим
position='absolute'; //абсолютное позиционирование
height=0; width=0; //любые значения
zIndex=1; // слой выше основного слоя документа
if(isIE){// в Internet Explorer применяем фильтр Alpha (Opacity непрозрачность)
backgroundColor = '#FFFFFF';
filter="progid:DXImageTransform.Microsoft.Alpha(Opacity=40, Style=0)";
}
else //для остальных браузеров фон из полупрозрачного PNG
backgroundImage = 'url(alfa40-fon.png)';
}
// добавлем созданный элемент в структуру документа
document.body.appendChild(GlassWindow);
}
if(show){
var s = getDocumentSize(); //размеры документа
with(GlassWindow.style){
// позиционируем экран на всю площадь документа
left = top = 0;
width = s[0]+'px';
height = s[1]+'px';
}
}
GlassWindow.style.display=show?'block':'none';
}
//функция ShowModalWindow показывает/скрывает форму
function ShowModalWindow(show){
ShowGlassWindow(show); //показываем/скрываем экран
// получим ссылку на форму диалога (элемент с id=modal)
if(Dialog==null) Dialog=document.getElementById('modal');
if(show){
//позиционируем по центру окна браузера и отображаем
var c = getClientCenter();
Dialog.style.left = (c[0]-150)+'px';
Dialog.style.top = (c[1]-75)+'px';
Dialog.style.display='block';
Dialog.focus();
}
else Dialog.style.display='none';
}
/* вспомогательные функции получения размеров */
// функция кроссбраузерного вычисления размеров документа
function getDocumentSize(){
return [
document.body.scrollWidth > document.body.offsetWidth ?
document.body.scrollWidth : document.body.offsetWidth,
document.body.scrollHeight > document.body.offsetHeight ?
document.body.scrollHeight : document.body.offsetHeight
];
}
// функция кроссбраузерного вычисления размеров рабочего окна браузера
function getClientSize(){
if(document.compatMode=='CSS1Compat')
return [document.documentElement.clientWidth, document.documentElement.clientHeight];
else
return [document.body.clientWidth, document.body.clientHeight];
}
// функция кроссбраузерного вычисления значений скроллинга
function getDocumentScroll(){
return [
self.pageXOffset || (document.documentElement && document.documentElement.scrollLeft)
|| (document.body && document.body.scrollLeft),
self.pageYOffset || (document.documentElement && document.documentElement.scrollTop)
|| (document.body && document.body.scrollTop)
];
}
// функция получения центра экрана
function getClientCenter(){
var sizes = getClientSize();
var scrl = getDocumentScroll();
return [parseInt(sizes[0]/2)+scrl[0], parseInt(sizes[1]/2)+scrl[1]];
}
</script>
Саму форму диалогового окна опишем следующим html и css кодом, конечный вариант будет зависеть от дизайна и функциональных требований к вашей форме диалога.
<div class="modal" id="modal">
<p align="center">Этот элемент вместе с "полупрозрачным экраном" эмулирует модальность.</p>
<p align="center">
<input type="button" value="Да" onclick="ShowModalWindow(false)">
<input type="button" value="Нет" onclick="ShowModalWindow(false)">
</p>
</div>
<style type="text/css">
div.modal{
position:absolute;
z-index:2;
display:none;
width:300px;
height:150px;
background-color:#DDDDDD;
border-top:2px solid #EEEEEE;
border-left:2px solid #EEEEEE;
border-bottom:2px solid #AAAAAA;
border-right:2px solid #AAAAAA;
padding:10px;
}
</style>
Для инициации диалога остается только вызвать функцию ShowModalWindow(true)
, а для скрытия дилогового окна соотвественно ShowModalWindow(false)
.
Ссылки по теме:
Модальные окна в веб-приложениях
Этот элемент вместе с "полупрозрачным экраном" эмулирует модальность.