Андрей Друченко
Модальные окна в веб-приложениях
Не секрет, что последние веяния моды в стиле веб 2.0 принесли с собой много новых возможностей и техник которые ранее были доступны только настольным приложениям.Последние версии современных браузеров в достаточной мере поддерживают CSS и Javascript требующийся для реализации модальных окон. Вкратце, модальное окно представляет собой окно которое полностью перехватывает на себя фокус, не давая пользователю взаимодействовать с какими-либо другими окнами на экране.
Наиболее часто модальные окна используются для
- Диалогов авторизации пользователя
- Вывода информационных сообщений
- Различного рода формы
В данном материале мы рассмотрим некоторые из известных мне JavaScript библиотек которые предоставляют необходимый функционал для реализации модальных окон в веб-приложениях. Сразу же оговорюсь, что вся подборка так или иначе использует популярный яваскрипт фреймворк Prototype
В забеге принимают участие:
- LightBox Gone wild (http://particletree.com/features/lightbox-gone-wild/)
- Control.Modal (http://livepipe.net/projects/control_modal/)
- subModal (http://sublog.subimage.com/articles/2006/01/01/subModal)
- Prototype window (http://prototype-window.xilinus.com/)
- ModalBox (http://wildbit.com/demos/modalbox/)
Моя субьективная оценка по каждой библиотеке, фактически сводилась к оценке по четырем параметрам
- Наличие развитого API
- Кроссбраузерность
- Документация
- Размеры кода
Как это работает
Все библиотеки так или иначе используют одну довольно простую идею, а именно — модальное окно создается посредством двух <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://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>
В детали реализации модальных окон этой библиотеки мы углубляться не будем, отметим лишь некоторые характерные особенности, которые так или иначе будут задействоваться другими библиотеками в нашем обзоре.
Среди прочих, для себя я отметил такие:
- Наличие хака(workaround) для IE6 связанного с сокрытием элементов типа <select>, причем сокрытие посредством visibility: hidden, а не display: none, поскольку первое не убирает рабочие области элементов с экрана. Если их не скрывать, то прозрачный оверлей почему-то не покроет эти элементы, и они останутся видны.
- Наличие хака для IE6 связанного с абсолютным позиционированием модального окна (при скроллинге страницы модальное окно должно всегда оставаться по центру). Если взглянуть на код lightbox.js то там можно увидеть соответствующие методы, которые занимаются решением данной проблемы в IE6 (setScroll(), getScroll(), prepareIE() )
Оценка
1. Наличие развитого APIJS API у данной библиотеки, фактически, отсутствует. В общем-то это и неудивительно, поскольку идеология этой библиотеки подразумевает использование семантической разметки, а не явного перехвата событий пользователя и выполнение какого-либо пользовательского яваскрипт кода. Если подходить к созданию страницы с семантической точки зрения, удобочитаемости для поисковиков, то библиотека Lightbox находится вне конкуренции. Если же вам надо иметь тотальный контроль над тем что происходит в модальном окне, то тут у вас возможностей весьма мало.
2. Кроссбраузерность
Я тестировал демо в Firefox 2, IE 6/7 — и проблем обнаружено не было.
3. Размеры кода
lightbox.js + lightbox.css занимают в сумме порядка 7Кб
4. Документация
Поскольку API, фактически отсутствует, то вся документация заключается в обучающей статье а также в хорошо документированном яваскрипт коде.
2. Control.Modal
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), в случае отключенного яваскрипта (это как раз случай с поисковиками) содержимое модальных окон будет проиндексировано, что является несомненным плюсом библиотеки.
Кроме, собственно, обычных центрированных модальных окон возможно также
- Относительно пизиционированные модальные окна
- Подгрузка содержимого окна по AJAX
- Подгрузка через iframe
- Эффект плавного затемнения рабочей области браузера (fading) при показе модального окна (необходим script.aculo.us)
- Возможность создания подсказок (tooltips) которые всплывают при наведении мышкой на определенные элементы страницы.
- Возможность давать ссылки с якорями на модальные окна. (например http://livepipe.net/projects/control_modal/#test_one_contents)
Оценка
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://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. Наличие развитого APIAPI библиотеки ограничивается все одной функцией 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://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, на мой взгляд, явно превосходит всех остальных участников обзора поскольку позволяет следующее:
- Изменяющие размер окна (resizable windows)
- Возможность сворачивать/разворачивать окна
- Собственно модальные окна/диалоги
- Различные визуальные эффекты, ограниченные только библиотекой script.aculo.us которую PW активно использует.
- Возможность стилизировать окна задавая внешние стили (в исходниках идут сразу несколько тем MacOS, Alert, Alphacube, DarkX, Lighting, Spread)
- Готовые классы-фабрики для управления несколькими окнами (Windows) а также класс для создания модальных диалогов (Dialog)
С подобным списков возможностей грех было не создать подобие оконного менеджера, что автор библиотеки и сделал. На выходе получилось детище под названием 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://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реди особенностей можно отметить:
- Загрузка содержимого модальных окон через AJAX
- В случае простого решения, наличие одного глобального объекта ModalBox с 3 методами сильно упрощает жизнь разработчику
- Легкое создание «мастеров» (wizards) — последовательных форм-диалогов (делается простым вызовом того же ModalBox.show() но уже внутри самого модального окна)
- Настроенные по умолчанию эффекты — SlideDown (окно выезжает сверху, как в консольном *nix приложении Yakuake) + эффект плавного изменения размеров (resize) модального окна, т.е. если ваш следующий диалог в цепочке имеет отличные от предыдущего размеры, то он плавно превращается в следующий, а не просто заменяется.
Оценка
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 | ||||
Control.Modal | ||||
subModal | ||||
Prototype window | ||||
ModalBox |
В итоге, получаем — если вы собрались строить довольно масштабное ajax приложение, с повсеместным применением окон как модальных так и немодальных, то я бы посоветовал Prototype window. Список ее возможностей впечатляет, и что самое главное, вокруг библиотеки сформировалось довольно живое сообщество.
С другой стороны, если вам нужна хорошая и элегантная реализация именно модальных окон, и при этом важна как кроссбраузерность так и размеры кода, я бы посоветовал ModalBox.
P.S.
Статья родилась в результате работы над одним очень массивным ajax приложением, в котором требовалось реализовать модальные окна. Поскольку в нем и так было напичкано много стороннего JavaScript функционала, то критичными были размер кода + кроссбраузерность. Но это все оказалось цветочками, после того как каждая очередная библиотека отказывалась либо правильно работать, либо вызывала ошибки в других частях приложения (видимо по причине каких-то конфликтов с уже существующим JavaScript кодом). В итоге, решение в виде ModalBox оказалось единственным работоспособным в моем случае, за что огромное спасибо автору библиотеки — Андрею ОконечниковуПоследние комментарии:
Кодировка | Sol |
---|---|
Подскажите как поменять кодировку (содержимое окна отображаться только если писать на русском) |
|
Автору | Sol |
тоже интересует решение вопроса Александра: Подскажите как прописать картинку в качестве ссылки на модальное окно? |
|
Лайтбокс | Александр |
Подскажите как прописать картинку в качестве ссылки на модальное окно? | |
Prorok | |
Помогите пожалуйста, что подойдёт для формы + передача из неё параметров | |
re: А какую Вы посоветуете? | автор |
Из базовых библиотек я бы посоветовал либо Prototype либо jQuery. У меня больше опыта с Prototype, и подборка библиотек для модальных окон в этой статье подобрана как раз для Prototype. Но в последнее время Prototype сильно вырос в размерах, да и решений на jQuery появилось побольше, и некоторые из них поэлегантней будут (в плане кол-ва кода и читаемости) Потому я бы на вашем месте начал копать в сторону jQuery |
|
Обсудить (комментариев: 40)