Домашние Картинки разработка веб-сайтов в Челябинске
+7(904) 30-76-196info@homepictures.ru
/Полезное/Статьи для веб-мастера/Эмуляция модальности в html

Эмуляция модальности в html

В практике построения интерфейсов на базе web-технологий возникают случаи, когда надо блокировать интерфейс от действий пользователя: запретить клики по ссылкам, выбирать элементы форм и т.п. К сожалению в связке javascript + html не предусмотрено сложных модальных диалоговых окон, которые часто бывают необходимы для получения данных от пользователя (например, окна авторизации). В этих случаях штатных средств функций alert и confirm явно недостаточно. Одним из способов эмулирования такой модальности может быть один из приемов, описанный ниже.

Как известно, последние стандарты каскадных стилевых таблиц (CSS) позволяют позиционировать элементы в контексте html страницы с точностью по пиксела (CSS-свойство position=absolute). С другой стороны элементы в html документе располагаются слоями, так что элементы, описанные ниже по коду, расположены выше и визуально перекрывают элементы, расположенные выше по коду. Такой порядок визуального перекрытия тоже можно поменять с помощью CSS (свойство z-index, чем выше индекс, тем выше элемент в визуальном представлении). Идея эмуляции модальности состоит в следующем. Создаются два элемента:

  1. полупрозрачное "окно-экран" с шириной и высотой равной ширине и высоте html-документа, блокирующий основное содержимое страницы. Для такого "окна" используем слой выше основного слоя содержимого html-документа. Возьмем для определенности z-index=1 (по умолчанию это свойство имеет значение 0);
  2. собственно окно формы, требующей ввода данных от пользователя. Этому окну формы назначим слой выше слоя "окна-экрана", допустим 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)">
&nbsp;
<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).

Скачать файлы примера...

Ссылки по теме:

Модальные окна в веб-приложениях