Продажа прочных чугунных ванн оптом со склада в Москве.


/* 16.05.2005 */

Плавное открытие/закрытие окна (CSS свойство clip)

Автор: Цыгырлаш Игорь (16.05.2005)

Довольно часто на web-страницах возникает потребность в диалоговых окнах. В начале мы используем "родные" javascript-овые Alert, Confirm, Prompt, но желание большего контроля над окном, рождает, со временем, окна на основе слоев. Своё окошко можно "вылизать" по своему усмотрению и показать пользователю во всей красе и не просто показать, а показать красиво - плавно развернуть окно, а затем свернуть.

Смотрите пример.

Диалоговое окно 1

Текст сообщения для пользователя.

Как плавно развернуть и свернуть окно (слой)?

Для простоты попробуем свернуть/развернуть окно по горизонтали (по вертикали выполняется аналогично).

Первым делом создадим слой:

<style type="text/css">
#dialogWindow {

/* Настраиваем внешний вид слоя */

	width: 300px; /* шириша слоя диалогового окна */
	height: 200px; /* высота слоя диалогового окна */
	background-color: #FFFFCC; /* цвет слоя диалогового окна */
	border: 1px dotted gray; /* рамка слоя диалогового окна*/

/* Позиционируем слой по центру */

	position: absolute; /* устанавливаем абсолютное позиционирование */
	left: 50%; /* устанавливаем верхний левый угол слоя по горизонтали по центру страницы */
	top:  50%; /* устанавливаем верхний левый угол слоя по вертикали по центру страницы */
	margin-top: -100px; /* сдвигаем слой вверх на половину высоты слоя */
	margin-left: -150px; /* сдвигаем слой влево на половину ширины слоя */

/* делаем слой невидимым */

	clip: rect(auto 150px auto 150px); /* свойство clip подробно рассмотрим ниже (оно ключевое) */
}

/* заголовок диалогового окна */

.dTitle {
	font-weight: bold;
	margin: 0;
	padding: 5px;
	background-color: #CCFFFF;
}

/* текст диалогового окна */

.dBody {
	text-align: center;
	margin: 0;
	padding: 10px 5px;
}
</style>

А сейчас, как я и обещал в комментарии, расмотрим свойство clip, изменение которого и дает нужный нам эффект сворачивания/разворачивания. Данное свойство определяет, так называемую, облать усечения. Что же это такое? Обратимся к спецификации CSS2, где сказано: Область усечения определяет, какая часть отображаемого содержимого элемента является видимой. По умолчанию размер и форма области усечения совпадают с размером и формой блока, порожденного элементом. Область усечения может быть изменена при помощи свойства clip.

Рассмотрим пример: пусть задан параграф P шириной 50px высотой 55px. Изначально область усечения совпадает с размером всего параграфа и параграф виден полностью, но если мы зададим свойству clip параграфа значение

P { clip: rect(15px, 30px, 50px, 10px); }

то получим следующую картину -

CSS свойство clip на примере параграфа

где серая область ограниченная сплошной черной линией - это область которую занимает параграф (P's block box), а белый прямоуголиник ограниченный пунктирной линией - это область усечения (clip region) заданая свойством clip. Так вот, в отличии от рисунка, на самом деле, все что не попадает в область усечения обрезается и становиться невидимым. Нажмите сюда чтобы применить свойство clip к нашему изображению и сюда чтобы восстановить исходное состояние.

Cсвойству clip параграфа из примера выше задано значение в форме rect (top right bottom left), где:

Также top right bottom left вместо длины отступа могут принимать значение auto, которое означает что данная сторона области вырезки совпадает со стороной элемента. т.е. clip: rect (auto auto auto auto); или просто clip: auto; - все стороны области вырезки совпадают со сторонами элемента, и элемент полностью виден.

Обратиться к свойству clip элемента через javascript можно следующим образом:

document.getElementById("elemID").style.clip

//Присвоить значение, например так
document.getElementById("elemID").style.clip = "rect(15px, 30px, 50px, 10px)";

//или так 
document.getElementById("elemID").style.clip = "rect(auto, 30px, auto, 10px)";
//сверху не обрезать (top=auto)и снизу не обрезать (bottom=auto), но обрезать по бокам
//все что меньше 10px (left) и больше 30px (right)

ВНИМАНИЕ!!! IE, включая версию 7, не понимает присвоения значения auto напрямую:

//показать весь элемент
document.getElementById("elemID").style.clip = "auto";

Поэтому для правильной работы во всех браузерах нужно писать:

document.getElementById("elemID").style.clip = "rect(auto, auto, auto, auto)";

Ну, вроде бы разобрались со свойством clip и теперь можем вернуться к нашим диалоговым баранам, в смылле диалоговым окнам. При описании стилей слоя dialogWindow мы задали clip: rect(auto 150 auto 150). Таким образом мы оставили верх и низ элемента без изменений, а правую и левую стороны обрезали каждую по 150px, что в сумме составляет полную ширину элемента - 300px. Т.е. мы просто скрыли элемент.

Попробуем развернуть скрытое окно по горизонтали. Что для этого нужно? Нужно циклически изменять значения right и left соответственно прибавляя и удаляя некоторое значение от текущих значений до тех пор пока left больше нуля, или right мешьше полной ширины слоя (досточно одного из условий). При этом top и bottom не трогаем, они у нас равны auto. Для получения эффекта постепенного появления или скрытия необходимо изменять clip с временными задержками между итерациями, ибо если их не делать то слой появиться очень быстро, и эффекта разворачивая не будет видно (разве что у вас Intel 386 на 20 MHz на который вы поставили Windows 98 - какой ужас). Заметьте, что подобный процесс сворачивания и разворачивания слоя похож на открытие и закрытие занавеса в театре. Поэтому я в названиях функций использую слово Curtain, что в переводе с англ. - зановес, штора.

var curtainStep = 10; //шаг - количество пикселей на которое будет сворачивать слой за один раз
var curtainTimeout = 15;//задержка перед последующей итерацией для эффекта плавности


//текущее количество обрезаемых пикселей слоя слева и справа
var curtainLeft = 150;
var curtainRight = 150;
var curtainWidth = 300;//ширина слоя

//ф-ция разворачивания слоя
function curtainOpen()
{
	if (curtainLeft > 0)//Пока левая граница области усечения не достигла левой границы слоя
	{
		curtainRight += curtainStep; //раскрываем область усечения справа на curtainStep пикселей
		curtainLeft -= curtainStep; //раскрываем область усечения слева на curtainStep пикселей
		
		var rect = 'rect(auto, '+ curtainRight +'px, auto, '+ curtainLeft +'px)';
		
		document.getElementById("dialogWindow").style.clip = rect;
		
		setTimeout(curtainOpen,curtainTimeout); //вызываем эту же функцию повторно через curtainTimeout миллисекунд
	}
}

Аналогично пишем функцию сворачивания слоя:

//ф-ция сворачивания слоя
function curtainClose()
{
	if (curtainLeft<curtainRight)//Пока левая граница области усечения не встретилась с правой
	{
		curtainRight -= curtainStep; //сужаем область усечения справа на curtainStep пикселей
		curtainLeft += curtainStep; //сужаем область усечения слева на curtainStep пикселей

		var rect = 'rect(auto, '+ curtainRight +'px, auto, '+ curtainLeft +'px)';

		document.getElementById("dialogWindow").style.clip = rect;

		setTimeout(curtainClose,curtainTimeout); //вызываем эту же функцию повторно через curtainTimeout миллисекунд
	}
}

Ну, вот и все! Однако на этом можно не останавливаться. Аналогично делается сворачивание по вертикали и одновременно по вертикали и по горизонтали.


-> Обсудить статью в форуме
<- Назад к списку статей
<• CSS rollover