developer.co.ua

Holy Copypasters
12.07.2007
Андрей Друченко

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

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

Наиболее часто модальные окна используются для 

Пример модального окна, для регистрации на сайте

http://developer.co.ua/upload/Image/js_modal/modal_example.gif


В данном материале мы рассмотрим некоторые из известных мне JavaScript библиотек которые предоставляют необходимый функционал для реализации модальных окон в веб-приложениях. Сразу же оговорюсь, что вся подборка так или иначе использует популярный яваскрипт фреймворк Prototype

В забеге принимают участие:
  1. LightBox Gone wild (http://particletree.com/features/lightbox-gone-wild/)
  2. Control.Modal (http://livepipe.net/projects/control_modal/)
  3. subModal (http://sublog.subimage.com/articles/2006/01/01/subModal)
  4. Prototype window (http://prototype-window.xilinus.com/)
  5. ModalBox (http://wildbit.com/demos/modalbox/)

Моя субьективная оценка по каждой библиотеке, фактически сводилась к оценке по четырем параметрам
  1. Наличие развитого API 
  2. Кроссбраузерность
  3. Документация
  4. Размеры кода

Как это работает

Все библиотеки так или иначе используют одну довольно простую идею, а именно — модальное окно создается посредством двух <div> элементов, один из них обычно покрывает всю рабочую область (viewport) браузера, а второй позиционируется поверх второго и собственно, представляет собой модальное окно в которое загружается нужный нам контент.

Первый <div> обычно называется overlay, и бывает прозрачным, для того чтобы создавать визуальный эффект затемнения и таким образом информировать пользователя что данная рабочая область недоступна. Прозрачный <div> создается с помощью CSS, кодом вроде этого:

#overlay{
display:none;
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
z-index:5000;
background-color:#000;
-moz-opacity: 0.8; /* код для движков Mozilla */
opacity:.80;  /*свойство из спецификации CSS3, которое поддерживается не всеми браузерами*/
filter: alpha(opacity=80); /* код для IE */
} 


Итак, начнем.

1. Lightbox Gone Wild


http://developer.co.ua/upload/Image/js_modal/lightbox.gif
http://particletree.com/features/lightbox-gone-wild/

После того как вы загрузите исходники (которые уже содержат сжатый Prototype) можно приступить к созданию модальных окон. Включаем загруженные файлы в заголовок нашего HTML документа:

<link rel="stylesheet" href="css/lightbox.css" type="text/css" />
<script src="scripts/prototype.js" type="text/javascript"></script>
<script src="scripts/lightbox.js" type="text/javascript"></script>


После этого создаем внешний файл, в нашем примере — test.html и наполняем его информацией для нашего модального окна:
<h3>What is a Lightbox?</h3>

<p class="highlight">Lightbox is an unobtrusive script used to overlay 
content on  the current page. Because it places content above your 
current page, it frees you from the constraints of the layout, 
particularly column widths.</p>


Для того чтобы вызвать наше модальное окно нам достаточно просто создать ссылку на файл с контентом для загрузки в модальное окно с классом “lbOn”:
<a href="form.html" class="lbOn">Email This</a>

Если необходимо чтобы модальное окно можно было закрыть после его показа, нужно создать вот такой код внутри содержимого модального окна:
<a href="#" class="lbAction" rel="deactivate">Close Lightbox.</a>

Также возможно сделать переход(перезагрузку) в пределах уже открытого модального окна:
<a href="confirm.html" class="lbAction" rel="insert">Go to Another Lightbox</a>


В детали реализации модальных окон этой библиотеки мы углубляться не будем, отметим лишь некоторые характерные особенности, которые так или иначе будут задействоваться другими библиотеками в нашем обзоре.
Среди прочих, для себя я отметил такие:

Оценка

1. Наличие развитого API
JS API у данной библиотеки, фактически, отсутствует. В общем-то это и неудивительно, поскольку идеология этой библиотеки подразумевает использование семантической разметки, а не явного перехвата событий пользователя и выполнение какого-либо пользовательского яваскрипт кода. Если подходить к созданию страницы с семантической точки зрения, удобочитаемости для поисковиков, то библиотека Lightbox находится вне конкуренции. Если же вам надо иметь тотальный контроль над тем что происходит в модальном окне, то тут у вас возможностей весьма мало.

2. Кроссбраузерность
Я тестировал демо в Firefox 2, IE 6/7 — и проблем обнаружено не было.

3. Размеры кода
lightbox.js + lightbox.css занимают в сумме порядка 7Кб

4. Документация
Поскольку API, фактически отсутствует, то вся документация заключается в обучающей статье а также в хорошо документированном яваскрипт коде.

2. Control.Modal


http://developer.co.ua/upload/Image/js_modal/control.modal.gif
http://livepipe.net/projects/control_modal/

Загрузив исходники данной библиотеки, сразу же приступим к изучению примера:
<a href="#test_one_contents" id="modal_link_one">Relative Modal</a>
<div id="test_one_contents">
    I am the innerHTML of a div with the id "test_one_contents". 
    You can make a modal window open relative to any element on the page.
</div>

<script>
    new Control.Modal('modal_link_one',{
        opacity: 0.8,
        position: 'relative',
        width: 300,
        height: 50
    });
</script>

В данном примере, на событие onclick ссылки с id="modal_link_one" навешивается действие по открытию модального окна. При этом, модальное окно сразу же имеет несколько параметров: прозрачность (opacity), позиционирование (relative/absolute), ширина(width) и высота(height).
В отличие от Lightbox(где содержимое окон по умолчанию подгружается через AJAX), в случае отключенного яваскрипта (это как раз случай с поисковиками) содержимое модальных окон будет проиндексировано, что является несомненным плюсом библиотеки.


Кроме, собственно, обычных центрированных модальных окон возможно также

Оценка

1. Наличие развитого API
Данная библиотека имеет вполне развитое API, которое предоставляет контроль над основными параметрами окна, а также делает возможным перехват событий модального окна, как-то beforeOpen(), afterOpen(), beforeClose(), afterClose() и прочие. Создание модальных окон происходит посредством создания экземпляров объекта Control.Modal, и автоматической привязки событий к элементам с определенными классами как это было в случае с Lightbox не просходит (хотя можно включить и такое поведение).

2. Кроссбраузерность
При остальных прочих преимуществах, библиотека не особо порадовала меня в разных браузерах.
Я тестировал демки с сайта в Firefox 2, IE 6 и 7. В FF, как и ожидалось все работало гладко. В IE6 все демки сработали тоже хорошо,
за исключением пары случаев, когда IE6 отказался вообще грузить страницу выдав загадочное сообщение «Невозможно загрузить страницу. Операция прервана.» Я неоднократно встречался с подобными выходками IE6, и недавно узнал что подобное может быть вызвано утечками памяти при обработке Яваскрипта.
Из-за поведения в IE7 от библиотеки пришлось отказаться и вовсе, т.к. было обнаружено весьма странное поведение — при повторном вызове модального окна по одной и той же ссылке срабатывает только показ оверлея, в то время как самого модального окна не видно.

Также в библиотеке присутствует код который устанавливает фокус на первый попавшийся <input> элемент в содержимом модального окна — он тоже не всегда срабатывает и вызывает ошибку в IE7.

3. Размеры кода
явасрипт + CSS занимают в сумме порядка 18Кб

4. Документация
На сайте присутствует обучающий материал, описание API, а также форум

3. subModal

http://developer.co.ua/upload/Image/js_modal/submodal.gif
http://sublog.subimage.com/articles/2006/01/01/subModal

Скачаем исходники версии 1.5 этой библиотеки и рассмотрим пример использования:

<head>
    <link rel="stylesheet" type="text/css" href="subModal.css" />
    <script type="text/javascript" src="common.js"></script>
    <script type="text/javascript" src="subModal.js"></script>
</head>

<body>
<script>
var onclose_callbackfunction = function () { alert('We're going to close!'); }
</script>

<button onclick="showPopWin('modalContent.html', 400, 200, onclose_callbackfuntion);">
   show modal window 
</button>
</body>

Итак, что происходит в данном примере? После подключения соответствующих JS файлов, нам становится доступной для использования функция showPopWin(), которая имеет три параметра: 1) URL страницы для загрузки в окно, 2) Ширина 3) Высота 4) Callback функция которая будет вызвана при закрытии данного окна.

Отличительной особенностью данной библиотеки является то, что она не использует Prototype (все вспомагательные функции находятся в файле common.js) а также то что контент в модальное окно загружается через IFrame. Если хотите грузить что-либо через AJAX придется делать модификации оригинальных исходников.

Оценка

1. Наличие развитого API
API библиотеки ограничивается все одной функцией showPopWin(). Cама библиотека реализована в виде набора функций, которые используют глобальные переменные — при использовании в большом JavaScript приложении это несомненный минус.

2. Кроссбраузерность
На сайте библиотеки заявлено о поддержке браузеров IE 6, Firefox 0.9+ и Opera 7. Я тестировал в IE6, FF 2.0 и IE7. Хотя на момент написания библиотеки (январь 2006), IE7 был еще в разработке, но, на удивление, в IE7 демка возможностей отлично работала. В IE6 и FF 2 проблем тоже не было обнаружено.
Из особенностей, следует заметить использование прозрачных PNG для поддержки прозрачности оверлея в Opera 7 (насколько я помню, в Opera 9 уже можно обойтись без прозрачных PNG). Особо любопытные могут изучить следующий код из файла subModal.css, чтобы понять о чем идет речь:
#popupMask {
  position: absolute;
  z-index: 200;top: 0px;left: 0px;width: 100%;height: 100%;
  opacity: .4;
  filter: alpha(opacity=40);
  /* this hack is so it works in IE
   * I find setting the color in the css gives me more flexibility 
   * than the PNG solution.
   */
  background-color:transparent !important;
  background-color: #333333;
  /* this hack is for opera support
   * you can uncomment the background-image if you don\'t care about opera.
   * this gives you the flexibility to use any bg color that you want, instead of the png
   */
  background-image/**/: url("maskBG.png") !important; /* For browsers Moz, Opera, etc. */
  background-image:none;
  background-repeat: repeat;
  display:none;
} 


3. Размеры кода
явасрипт + CSS занимают в сумме порядка 12Кб (Если учесть что эта библиотека не требует фреймворка Prototype, то это может оказаться весьма большим преимуществом, но судя по всему остальному — и единственным)

4. Документация
На сайте присутствует обучающая статья с примером, а также рассылка http://groups.google.com/group/subModal

4. Prototype window

http://developer.co.ua/upload/Image/js_modal/pwc.gif
(http://prototype-window.xilinus.com/)
Скачав исходники версии 1.3 рассмотрим один из самых простых примеров этой многофункциональной библиотеки (скорей всего даже фреймворка):

<script type="text/javascript" src="/javascripts/prototype.js"> </script>
 <script type="text/javascript" src="/javascripts/window.js"> </script>
 <link href="/stylesheets/themes/default.css" rel="stylesheet" type="text/css"/> 

<!-- добавляем этот CSS для отрисовки окон в стиле MacOS --> 
 <link href="themes/mac_os_x.css" rel="stylesheet" type="text/css"/> 


<script>
win = new Window({
         className: "mac_os_x",  
         title: "Sample",
         width:200, 
         height:150, 
         destroyOnClose: true, 
         recenterAuto:false});

win.getContent().update("<h1>Hello world !!</h1>"); 
win.showCenter(); 
</script>


В вышеприведенном коде создается модальное окно, использующее CSS из mac_os_x.css заголовком “Sample”, шириной 200, высотой 150, которое уничтожается при закрытии (destroyOnClose:true — по умолчанию окно просто скрывается), и которое автоматически не центрируется при изменении размеров окна браузера(recenterAuto:false).
Все параметры можно упустить, так как для каждого из них имеются значения по умолчанию. Весь список возможных параметров (довольно таки внушительный) для конструктора класса Window доступен в документации. Контент в модальное окно загружается через AJAX, посредством вызова отдельного метода. Точно также происходит и активация окна.

По своим возможностям Prototype Window, на мой взгляд, явно превосходит всех остальных участников обзора поскольку позволяет следующее:

С подобным списков возможностей грех было не создать подобие оконного менеджера, что автор библиотеки и сделал. На выходе получилось детище под названием PWC-OS

Оценка

1. Наличие развитого API
Данная библиотека имеет весьма развитое API, что позволяет контролировать любое поведение окон. Сама библиотека состоит из класса Window, фабрики Windows и Dialog а также нескольких примочек к Windows — WindowsStore.init, WindowCloseKey.init и TooltipManager

2. Кроссбраузерность
На сайте заявлено о поддержке Safari, Camino, Firefox, IE6 + Opera. Я протестировал большинство примеров в FF 2.0, IE6/7 и Opera 9 — проблем обнаружено не было.

3. Размеры кода
явасрипт + базовый CSS занимают в сумме порядка 131Кб. (Если использовать только базовый класс Windows то — 67Кб)

4. Документация
На сайте присутствует подробная документация, примеры использования а также форум

5. ModalBox

http://developer.co.ua/upload/Image/js_modal/modalbox.gif
(http://wildbit.com/demos/modalbox/)
Качаем исходники и приступаем к примеру:

<html>
<head>
<script type="text/javascript" src="includes/prototype.js"></script>
<script type="text/javascript" src="includes/scriptaculous.js"></script>
<script type="text/javascript" src="includes/modalbox.js"></script>

<link rel="stylesheet" href="includes/modalbox.css" type="text/css" 
media="screen" />
</head>

<body>
<a href="frame_send-link.html" title="Simple form" 
    onclick="Modalbox.show(this.title, this.href, {width: 600});return false;">  
      Send link to a friend 
</a>

</body>
</html>


Разберем детальней что именно происходит в данном коде. А происходит следующее: по нажатию на ссылку вызывается метод глобального JS-OO объекта ModalBox, которому на вход подаются а) Заголовок окна (в нашем случае “Simple form”), б) URL страницы которую надо загрузить в окно, в) массив параметров состоящий пока что из одной высоты (width=600)

Cреди особенностей можно отметить:

Оценка

1. Наличие развитого API
Вся прелесть API данной библиотеки заключается в том что ее API маленькое и компактное, и не перегружено большим количеством всяких опций. Глобальный объект ModalBox имеет всего три метода show(), hide() и resize() — названия более чем лаконичные. Также ModalBox поддерживает необходимый минимум callback событий: beforeLoad(), afterLoad(), afterHide(), afterResize(), onShow(), onUpdate()


2. Кроссбраузерность
На сайте заявлено о поддержке IE6, IE7, Firefox 1.0, 1.5, 2.0, Safari, Camino, Opera 8 and 9. Я протестировал демо-wizard в FF 2.0, IE6/7 и Opera 9 — проблем обнаружено не было.

3. Размеры кода
явасрипт + CSS занимают в сумме порядка 20Кб. (код можно сильно уменьшить поудаляв довольно подробные комментарии)

4. Документация
На сайте присутствует минимальная документация с примерами использования.


Заключение

В данной статье мы сделали обзор 5 различных библиотек для создания модальных окон посредством JavaScript, логично было бы дать короткую сравнительную характеристику каждой из них. Сразу оговорюсь, характеристики каждой библиотеки — чисто субьективные. Итак, будем оценивать каждую библиотеку по пятибальной шкале, по 4-м ранее упоминавшимся параметрам.

Таблица 1–1. Cравнительная характеристика JavaScript библиотек создания модальных окон

APIКроссбраузерностьРазмеры кодаДокументация
LightBox Gone wild
http://developer.co.ua/posts/rating/1/.png
http://developer.co.ua/posts/rating/4/.png
http://developer.co.ua/posts/rating/5/.png http://developer.co.ua/posts/rating/1/.png
Control.Modal
http://developer.co.ua/posts/rating/4/.png
http://developer.co.ua/posts/rating/3/.png
http://developer.co.ua/posts/rating/3/.png http://developer.co.ua/posts/rating/5/.png
subModal
http://developer.co.ua/posts/rating/1/.png
http://developer.co.ua/posts/rating/4/.png
http://developer.co.ua/posts/rating/4/.png http://developer.co.ua/posts/rating/2/.png
Prototype window
http://developer.co.ua/posts/rating/5/.png
http://developer.co.ua/posts/rating/5/.png
http://developer.co.ua/posts/rating/1/.png http://developer.co.ua/posts/rating/5/.png
ModalBox
http://developer.co.ua/posts/rating/4/.png
http://developer.co.ua/posts/rating/5/.png
http://developer.co.ua/posts/rating/4/.png http://developer.co.ua/posts/rating/4/.png


В итоге, получаем — если вы собрались строить довольно масштабное ajax приложение, с повсеместным применением окон как модальных так и немодальных, то я бы посоветовал Prototype window. Список ее возможностей впечатляет, и что самое главное, вокруг библиотеки сформировалось довольно живое сообщество.
С другой стороны, если вам нужна хорошая и элегантная реализация именно модальных окон, и при этом важна как кроссбраузерность так и размеры кода, я бы посоветовал ModalBox.


P.S.

Статья родилась в результате работы над одним очень массивным ajax приложением, в котором требовалось реализовать модальные окна. Поскольку в нем и так было напичкано много стороннего JavaScript функционала, то критичными были размер кода + кроссбраузерность. Но это все оказалось цветочками, после того как каждая очередная библиотека отказывалась либо правильно работать, либо вызывала ошибки в других частях приложения (видимо по причине каких-то конфликтов с уже существующим JavaScript кодом). В итоге, решение в виде ModalBox оказалось единственным работоспособным в моем случае, за что огромное спасибо автору библиотеки — Андрею Оконечникову


1 2 3 4 5

Последние комментарии:

Кодировка Sol
Подскажите как поменять кодировку
(содержимое окна отображаться только если писать на русском)

Автору Sol
тоже интересует решение вопроса Александра:
Подскажите как прописать картинку в качестве ссылки на модальное окно?

Лайтбокс Александр
Подскажите как прописать картинку в качестве ссылки на модальное окно?

Prorok
Помогите пожалуйста, что подойдёт для формы + передача из неё параметров

re: А какую Вы посоветуете? автор
Из базовых библиотек я бы посоветовал либо Prototype либо jQuery.
У меня больше опыта с Prototype, и подборка библиотек для модальных окон в этой статье подобрана как раз для Prototype. Но в последнее время Prototype сильно вырос в размерах, да и решений на jQuery появилось побольше, и некоторые из них поэлегантней будут (в плане кол-ва кода и читаемости)
Потому я бы на вашем месте начал копать в сторону jQuery

Обсудить (комментариев: 40)