Источник: A jQuery Client Status Bar
Последнее время ко мне неоднократно обращались с вопросами по поводу строки состояния в моем фотоальбоме на jQuery. На самом деле здесь нет ничего сложного, но, поскольку это заинтересовало несколько человек, я подумал, что стоит рассказать как же все-таки это работает. Несмотря на то, что в данном примере используется jQuery, того же эффекта можно легко достичь с помощью простого кода DOM или любой другой библиотеки JavaScript. Однако, большую часть работы все же проделывает CSS (и, полагаю, именно об этом и было большинство полученных мною вопросов), а не клиентский код, хотя компонент, с которым я познакомлю вас в конце задействован не меньше.
Зачем нужна строка состояния?
Как правило, я использую строки состояния для вывода информации на большинстве своих административных панелей, а иногда и во внешнем интерфейсе некоторых сайтов. Как и в случае с настольными приложениями, использование окон предупреждений для вывода информации при написании клиентских скриптов не очень удобно для пользователя, целесообразнее использовать некое постоянное место для вывода сообщений. Для решения этой задачи мне нравится использовать строки состояния, располагая их как наверху, так и внизу страницы.
В приложении фотоальбом строка состояния находится внизу страницы, имеет фиксированное положение и определенную прозрачность фона, так что строка состояния всегда видна, но вместе с тем она находится поверх остального содержания страницы:

Иногда при выводе сообщений в строке состояния может быть превышено время ожидания, и тогда там будет отображаться заданное по умолчанию сообщение (как правило, это «Готово»). Новые сообщения выделяются:

Через заданный промежуток времени выделение текста снимается. Это лучше делать с помощью CSS класса statusbar.
Пример строки состояния на странице фотоальбома можно посмотреть здесь:
http://www.west-wind.com/rick/photoalbum/demoMaui2006/default.aspx?Admin=true
После сохранения изменений и удаления изображений происходит обновление строки состояния (так же как и в случае с Ajax-овыми ошибками в методе-обработчике, которые не должны происходить).
Начнем с CSS
Для выполнения большей части работы необходимо использовать CSS стили элементов. Строка состояния – не просто тэг
.statusbar
{
position: fixed;
bottom: 5px;
left: 0px;
right: 0px;
height: 16px;
padding: 5px;
background: black;
color: white;
border: solid 1px lightgray;
opacity: .70;
filter: alpha(opacity="70");
z-index: 200;
overflow: hidden;
overflow-y: auto;
}
.statusbarhighlight
{
font-weight: bold;
background-color: khaki;
color: Maroon;
border: solid 1px silver;
}
Главным для строки состояния является фиксированное положение, при котором она всегда находится внизу страницы и остается там постоянно независимо от состояния полосы прокрутки браузера. Я предпочитаю размещать строку состояния на расстоянии 5px (5 пикселей) над нижней частью окна и затем применять прозрачность, чтобы сквозь строку состояния просвечивалась расположенная под ним страница. Полагаю, необходимо убедиться, что строка состояния находится над остальным содержимым страницы, а не определять ее абсолютное положение по нижнему краю.
В дополнение к классу statusbar применяется выделение, таким образом, выделенное сообщение сочетает оба стиля. Выделение просто изменяет цвет и рамку сообщения в строке состояния на определенный заданный промежуток времени.
Вы, конечно, можете отредактировать CSS по своему желанию и таким образом изменить отображение строки состояния: квадратная или прямоугольная; горизонтальная или вертикальная — справа или слева. В этом суть.
Простой вариант кода JavaScript на jQuery
Первоначально при создании строки состояния я использовал стандартную функцию – дешево и сердито. Она создает элемент DOM для строки состояния и применят соответствующие классы. Это самая простая функция, которая выполняет несколько вещей:
function showStatus(message,timeout,add)
{
if (typeof _statusbar == "undefined")
{
// ** Create a new statusbar instance as a global object
_statusbar =
$("
")
.appendTo(document.body)
.show();
}
if (add)
// *** add before the first item
_statusbar.prepend( "
" + message + "
")[0].focus();
else
_statusbar.text(message)
_statusbar.show();
if (timeout)
{
_statusbar.addClass("statusbarhighlight");
setTimeout( function() { _statusbar.removeClass("statusbarhighlight"); },timeout);
}
}
А теперь воспользуйтесь функцией showStatus() и CSS. Эту функцию можно применить в любом месте кода:
showStatus("Photo Collection has been updated",5000);
Обратите внимание, что функция также имеет параметр add, который определяет, добавлять ли сообщение к уже существующим в начало списка в тэге div. Это удобно, если вы собираетесь использовать строку состояния для вывода отладочных сообщений и при этом просматривать весь список сообщений. Чтобы это работало, возможно, потребуется увеличить высоту в классе .statusbar до 40px и более, дабы просматривать несколько сообщений с полосой прокрутки для перемещения по списку.
Обратите внимание, что CSS дает возможность управлять расположением и видом строки состояния. В целом, суть этого кода состоит в создании глобальной переменной _statusbar наряду со стилями .statusbar и .statusbarhighlight для корректного отображения строки состояния.
Создание более продвинутого компонента Statusbar
Основной код верен и самодостаточен, но, возможно, лучше создать более стандартный базовый компонент. На самом деле я не старался сделать этот код идеальным и не всегда следовал основным принципам jQuery для написания плагинов, потому что на самом деле предпочитаю создавать компонент с помощью одной функции и одного вызова для инициализации, а не служебной функции jQuery. С этой точки зрения этот компонент немного отличается от типичного плагина jQuery, потому что он не подходит к набору объектов jQuery.
По существу, написанная мной версия – это один класс с несколькими методами. Идея состоит в создании и конфигурации экземпляра класса в коде инициализации:
_statusbar = new StatusBar("#divStatus",
{showCloseButton: true,
additive: true,
afterTimeoutText: "Click on caption to edit text..."});
в дальнейшем вы можете использовать любой из двух вариантов функций:
_statusbar.show("Images have been reloaded",5000);
showStatus("Photo Collection has been updated",5000);
Последняя является служебной функцией, которая просто инкапсулирует создание переменной класса посредством глобальной переменной _statusbar с помощью конструктора по умолчанию. Это довольно удобно, так как дает возможность вызывать функцию без предварительной инициализации.
Следует также описать этот компонент с точки зрения конфигурации через свойства. В jQuery любое свойство может быть передано посредством массива объектов свойств, который определяет свойства класса StatusBar. Так, в примере выше я задал три свойства: одно для закрытия строки состояния; второе для аддитивного вывода сообщений, т.е. такого, чтобы при этом сохранялась и отображалась история сообщений; и третье для снятия выделения и вывода сообщения по умолчанию по истечении заданного промежутка времени.
Исходный код класса StatusBar:
function StatusBar(sel,options)
{
var _I = this;
var _sb = null;
// options
this.elementId = "_showstatus";
this.prependMultiline = true;
this.showCloseButton = false;
this.afterTimeoutText = null;
this.cssClass = "statusbar";
this.highlightClass = "statusbarhighlight";
this.errorClass = "statuserror";
this.closeButtonClass = "statusbarclose";
this.additive = false;
$.extend(this,options);
if (sel)
_sb = $(sel);
// create statusbar object manually
if (!_sb)
{
_sb = $("
" +
"
" +
(_I.showCloseButton ? " X
" : "") )
.appendTo(document.body)
.show();
}
if (_I.showCloseButton)
$("." + _I.cssClass).click(function(e) { $(_sb).hide(); });
this.show = function(message,timeout,isError)
{
if (_I.additive)
{
var html = "
" + message + "
";
if (_I.prependMultiline)
_sb.prepend(html);
else
_sb.append(html);
}
else
{
if (!_I.showCloseButton)
_sb.text(message);
else
{
var t = _sb.find("div.statusbarclose");
_sb.text(message).prepend(t);
}
}
_sb.show();
if (timeout)
{
if (isError)
_sb.addClass(_I.errorClass);
else
_sb.addClass(_I.highlightClass);
setTimeout(
function() {
_sb.removeClass(_I.highlightClass);
if (_I.afterTimeoutText)
_I.show(_I.afterTimeoutText);
},
timeout);
}
}
this.release = function()
{
if(_statusbar)
$(_statusbar).remove();
}
}
// use this as a global instance to customize constructor
// or do nothing and get a default status bar
var _statusbar = null;
function showStatus(message,timeout,additive,isError)
{
if (!_statusbar)
_statusbar = new StatusBar();
_statusbar.show(message,timeout,additive,isError);
}
Класс обеспечивает реализацию, а для свободного доступа к объекту создается дополнительный статический экземпляр _statusbar. В качестве альтернативы можно использовать представленную ниже функцию showStatus(), которая создает стандартный экземпляр строки состояния и запускает его. Таким образом, имея стили для statusbar и statushighlight, получаем отображение строки состояния в соответствии со стилем.
showStatus("Updated photo settings.",5000);
Если нужно настроить вывод строки состояния, можно с помощью конструктора с параметрами явно создать экземпляр _statusbar. Использование конструктора позволяет переопределить поведение и предоставляет еще несколько дополнительных свойств отображения статусной строки:
- Многострочное окно информации о состоянии
- Аддитивные статусные сообщения с добавлением новых снизу или сверху всего списка сообщений
- Показывать кнопку «закрыть»
- Возможность использования пользовательских классов CSS
Для настройки этих элементов необходимо на странице кода инициализации сделать следующее:
$(document).ready( function() {
if (serverVars.adminMode)
{
MakeListEditable();
var status = "Click on caption to edit text. Drag image to sort list..."
_statusbar = new StatusBar(null,{showCloseButton: true,
additive:true,
afterTimeoutText: status });
_statusbar.show(status);
}
} );
Есть возможность передачи свойств для настройки всех свойств строки состояния с помощью стандартного метода jQuery.extend(), куда можно передать объект со свойствами, которыми нужно расширить StatusBar.
Свойство additive позволяет отображать несколько статусных сообщений и добавлять новые сообщения сверху или снизу всего списка (используя свойство prependMultiline). Это дает возможность использовать строку состояния также в качестве средства отладки, так что вы сможете выводить статусные сообщения, а также избежать использования окон предупреждений alert(). А вот как это будет выглядеть:

Создав несколько экземпляров класса StatusBar можно создать на странице несколько строк состояния. Так, вы можете создать строку состояния для вывода сообщений и строку состояния для отладки и даже назначить им разные стили. Отладочную строку состояния удобнее разместить вертикально с правого или с левого края браузера. Для этого вы, скорее всего, пожелает изменить CSS.
Однако, есть еще несколько компонентов, обеспечивающих вывод отладки и если вам необходим инструмент вывода трассировки для помощи в отладке, вам, вероятно, лучше использовать один из плагинов jQuery. Но если вам нужен простой и быстрый способ вывода сообщений на экран в приложениях или даже в библиотечном коде, вышеописанный подход подойдет отлично, так как он может быть реализован простым дополнением строки кода без последующей настройки, подключая библиотечный код после загрузки скрипта.
На стороне сервера
Несколько человек спрашивали, как использовать компонент jQuery в ASP.NET. Ответ на этот вопрос так же прост как сама строка состояния: просто добавьте необходимый код JavaScript на страницу посредством объекта ClientScript (или с помощью ScriptManager, если вы используете MS AJAX). Представьте, что вам нужно установить исходное сообщение о состоянии, которое будет отображаться при загрузке страницы из кода ASP.NET. Для этого можно использовать такой код:
protected void ShowStatus(string message, int timeout)
{
var script =
@"
jQuery(document).ready( function() {{
var status = '{0}';
_statusbar = new StatusBar(null,{{showCloseButton: true,
additive:true,
afterTimeoutText: status}} );
_statusbar.show(status,{1});
}});";
this.ClientScript.RegisterStartupScript(this.GetType(),
"showStatus",
string.Format(script, message, timeout), true);
}
Затем из любого места кода сделайте вызов:
this.ShowStatus("Click to start",0);
И вуаля – взаимодействие сервер-страница готово. Скорее всего, вы пожелаете убрать код инициализации со страницы со скриптом во избежание путаницы какое сообщение обрабатывать первым. Следует убедиться, что ShowMessage вызывается по крайней мере один раз для инициализации исходного сообщения и объекта _statusbar. При многократном использовании данной функциональности можно применять объект _statusbar в серверном компоненте и получить несколько свойств, управляющих исходным сообщением, а также настроить другие свойства компонента со стороны сервера. Это исключит необходимость в каких-либо специальных знаниях как, например, необходимость вывода исходного сообщения заранее без явного вызова метода ShowStatus. Возможно, для данного простого компонента это перегиб, но для более сложных компонентов будет, несомненно, полезным.
Строка состояния как плагин jQuery?
Как отмечалось ранее, только начало создания усовершенствованного класса и, скорее всего, придется потрудиться немного больше для окончательной шлифовки кода. Я также пытался реализовать строку состояния как плагин jQuery, но пока не могу найти эффективного способа.
jQuery допускает использование служебных функций над статическими сущностями jQuery, но я не думаю, что класс Statusbar будет действительно хорош в качестве статической функции/объекта, так как вся его работа заключается в добавлении префикса $/jQuery в синтаксис. В общем, в данном в случае я не вижу от этого никакой пользы. Класс Statusbar также не совсем приемлем как набор функций jQuery, посколку строка состояния объект в основном статичный.. Одним словом, я считаю, что строка состояния в качестве плагина jQuery лишь неоправданно усложнит компонент.
Есть другие идеи?
Что ж, надеюсь, кому-то статья будет полезной. Некоторое время я не редко прибегал к использованию строк состояния во многих своих приложениях, ведь этот компонент значительно упрощает вывод статусных сообщений в приложениях. Надеюсь, вы смогли найти здесь идеи создания различных вспомогательных функций/классов и сможете реализовать их в своем клиентском коде.
Download: wwjQuery.zip
Популярность: 43%
ROM
RSS Записей
Поддержи сайт!




