Автор: Роман Панышев (irrona)
Начиная с четвертой версии Internet Explorer в обиход WEB-разработчиков прочно вошло понятие CSS (каскадные таблицы стилей), которые расширили объектную модель браузера и предоставили возможность в отдельном файле задавать аттрибуты и стили визуальных объектов Internet Explorer-а. Поняв всю важность и удобство данной технологии, разработчики из Microsoft решили расширить данную технологию и в версии 5 добавили возможность использования т.н. DHTML Behaviors (behaviors дословно "поведения").
DHTML Behaviors являются простыми, легковесными (lightweight) компонентами, инкапсулирующими специфичную функциональность или "поведение" объектов на html-странице. При использовании со стандарным объектом страницы, напр. тэгом input, behaviors наследуют, в первую очередь, "поведения" этого объекта, имеющиеся у него по-умолчанию. Являясь инкапсулированными компонентами, "поведения" обеспечивают простую позможность для отделения скрипта от содержимого. Это дает возможность не только использовать один и тот же скрипт для различных страниц, но и для различных объектов. Например, один скрипт, позволяющий изменить цвет текста элемента страницы, можно применить как к тэгу p, так и к тэгам h1...,label и другим. Возможности "поведений" были значительно расширены после выхода в свет Internet Explorer версии 5.5, т.к. в ней (в этой версии) появился новый тип "поведений" - "поведения элементов" (Element Behaviors). С тех пор имеется два основных типа "поведений". Оригинальные "поведения", появившиеся еще в версии 5 Internet Explorer стали называть "поключаемые поведения" (Attached Behaviors). Об Element Behaviors Вы можете прочитать в моей статье Практика использования Custom Tags. В этой же статье речь пойдет о первом типе DHTML Behaviors, а именно об Attached Behaviors. С помощью "поведений" становится возможным добавление интерактивности, разрабатывая отдельные компоненты, применимые на множестве web-страниц. Кроме этого легче разделить работу по созданию сайта между группами программистов, и дизайнеров. В то время, как дизайнеры работают над внешним видом страниц, программисты, используя скриптовые языки, разрабатывают компоненты, к которым в последствии применяются стили, разработанные дизайнерами.
Существует по крайней мере три общеизвестных способа применения "поведений" на web-странице. Первый - через объявление "поведения" в секции STYLE страницы:
<HEAD> <STYLE> .ROLLOVER { color:'red';letter-spacing:2 } </STYLE> </HEAD> <BODY> <UL> <LI onmouseover="this.className='ROLLOVER'" onmouseout ="this.className=''">HTML Authoring</LI> </UL> </BODY>
Показать пример (Только для IE 5+)
В данном случае для применения "поведения" на другой web-странице, нам пришлось бы скопировать код из секции STYLE, что совсем неудобно. Второй способ более инкапсулирован. Мы можем создать внешний файл с расширением *.htc, в котором описать всю необходимую реакцию компонента на события, происходящие на странице. После этого, поместив путь к файлу в секцию STYLE, использовать примерно так же, как и в первом примере:
<HEAD> <STYLE> LI { behavior:url(rollover.htc) } </STYLE> </HEAD> <BODY> <UL> <LI>HTML Authoring</LI> </UL> </BODY>
Файл rollover.htc выглядит следующим образом:
<PUBLIC:COMPONENT tagName="rollover"> <PUBLIC:ATTACH EVENT="onmouseover" FOR="element" ONEVENT="Hilite()" /> <PUBLIC:ATTACH EVENT="onmouseout" FOR="element" ONEVENT="UnHilite()" /> <PUBLIC:ATTACH event="oncontentready" onevent="fnInit()"/> </PUBLIC:COMPONENT> <SCRIPT> var normalColor = ''; function fnInit() { normalColor = element.style.color; element.style.letterSpacing = 0; } function Hilite() { element.style.color = 'red'; element.style.letterSpacing = 2; } function UnHilite() { element.style.color = normalColor; element.style.letterSpacing = 0; } </SCRIPT>
Показать пример (Только для IE 5+)
Как видите объект LI реагирует на курсор мыщи совершенно одинаково. Но теперь мы можем всего лишь опеределить в секции STYLE для какого именно объекта в иерархии объектов Internet Explorer будет действовать заданное нами "поведение". Кроме этого существует третий, на мой взгляд самый гибкий способ использования "поведений" на странице. Это возможность задавать "поведение" непосредственно для нужного нам объекта.
<HEAD> </HEAD> <BODY> <UL> <LI>HTML Authoring (part 1)</LI> <LI style="behavior:url('rollover.htc');">HTML Authoring (part 2)</LI> <LI>HTML Authoring (part 3)</LI> </UL> </BODY>
Показать пример (Только для IE 5+)
Как Вы могли убедиться, благодаря "поведениям" в руках у разработчиков web-страниц появился мощный инструмент, с помощью которого можно расширить границы пользования стандартными тэгами Internet Explorer, подгоняя их поведение под свои нужды.
В качестве заключительного примера я хочу показать реализацию DHTML Behaviors, основой для которого будет являться тэг INPUT типа text (аналогичный полю для ввода текста). Зададим поведение этого тэга таким образом, чтобы он работал как поле для ввода даты. Файл реализации компонента назовем datebox.htc.
Показать код
<public:component tagName=dtPicker> <public:attach event="oncontentready" onevent="fnInit"/> <public:attach event="onfocus" onevent="fnFocus" /> <public:attach event="onfocusout" onevent="fnFocusOut" /> <public:attach event="onkeypress" onevent="fnKeyPress" /> <public:method name="getDate" /> <public:method name="setDate" /> <public:property name="retDate" /> <public:property name="insDate" /> </public:component> <script language=vbscript> Function fnInit() element.style.border = "lightgrey 2px inset" element.value = FormatDateTime(Date, vbShortDate) End Function Function fnKeyPress() Dim fooValue fooValue = element.value If window.event.keyCode = 13 Then If Not IsDate(fooValue) Then MsgBox "Введенное значение не является датой", vbOKOnly+vbCritical,"Ошибка ввода данных" element.focus Else insDate = fooValue Call setDate() End If Else Exit Function End If End Function Function fnFocusOut() Dim fooValue fooValue = element.value If Not IsDate(fooValue) Then MsgBox "Введенное значение не является датой", vbOKOnly+vbCritical,"Ошибка ввода данных" element.focus Else insDate = fooValue Call setDate() End If End Function Function getDate() retDate = FormatDateTime(element.value, vbShortDate) End Function Function setDate() If Not IsDate(insDate) Then Exit Function element.value = FormatDateTime(insDate, vbShortDate) End Function Function fnFocus() element.select End Function </script>
После этого подключаем компонент к объекту на странице вот таким вот образом:
<INPUT type="text" style="behavior:url('datebox.htc');text-align:right;width:100px;height:22px;">
и получаем что-то наподобие этого:
если Вы не видите работу примера, значит Ваш браузер не Internet Explorer 5+
Получившееся поле для ввода даты корректно обрабатывает введенную дату и, в случае несоответствия введенного значения дате, выдает ошибку. Проверка введенного значения производится либо по нажатии кнопки "Ввод", либо при потере элементом фокуса. В качестве разделителя значений компонентов даты можно использовать символы слэш,тире,точка и запятая. Вполне достаточно для любой категории пользователей. Здесь Вы можете скачать архив, содержащий файл datebox.htc.
Если Вы уже программировали с использованием объектами, то должны знать, что каждый объект обладает некоторым набором собственных свойств (properties), методов (methods) и свойственным ему способом реагирует на различные события (events), происходящие в нем или вокруг. DHTML Behaviors являются такими же объектами, как любые другие. Соответственно разрабатывая "поведения" мы описываем реакцию объекта на события, выраженную в реализации некоторого количества методов (функций), причем при этом можем инициализировать какие-то изначальные свойства объекта. Обычно создание объекта "поведение" начинается со стандартного тэга (причем парного), который идентифицирует файл, как HTML компонент (HTC):
<PUBLIC:COMPONENT NAME = sName URN = sURN ID = sID tagName = sTagName lightWeight = true | false literalContent = true | false supportsEditMode = true | false />
где:
Внутри основного тэга <PUBLIC:COMPONENT> можно разместить объявления свойств, методов и событий компонента, что обеспечивается следующими тэгами:
<PUBLIC:PROPERTY NAME = sName ID = sPropertyID INTERNALNAME = sInternalName GET = sGetFunction PUT = sPutFunction PERSIST = bPersist VALUE = vValue />
Описывает свойство компонента, где:
<PUBLIC:METHOD NAME = sName INTERNALNAME = sInternalName ID = sID />
Описывает метод компонента, где:
<PUBLIC:EVENT NAME = sName ID = sEventID />
Описывает событие, где:
<PUBLIC:DEFAULTS tabStop = true | false style = sStyle contentEditable = true | false canHaveHTML = true | false viewInheritStyle = true | false viewMasterTab = true | false viewLinkContent = true | false />
Свойства компонента по-умолчанию, где:
О том, что такое ViewLink мы будем говорить в одной из следующих моих статей. Кроме указанных выше тэгов можно также использовать тэг:
<PUBLIC:ATTACH EVENT = sEvent FOR = document | element | window ONEVENT = sEventHandler ID = sID />
Он позволяет задать реакцию компонента на события, возникающие на странице-контейнере. То есть для обработки такого события, вы используете внутренний метод компонента, определенный Вами. Атрибуты тэга означают следующее:
Кроме событий страницы-контейнера, можно (а иногда и нужно) задавать обработку событий, присущих компонентам, таких как oncontentready (происходит после парсинга браузером содержимого объекта страницы-контейнера, к которому применено "поведение"), oncontentsave (происходит перед тем, как содержимое объекта страницы-контейнера, для которого применено "поведение" сохраняется или копируется), ondetach (происходит перед отделением "поведения" от объекта страницы-контейнера), ondocumentready (происходит после полного парсинга браузером страницы-контейнера, в которой имеются "поведения").
Более полную информацию о разработке htc-файлов Вы можете почерпнуть из топика MSDN "HTC Reference" или с сайта Microsoft (правда на английском языке :-))). А у меня на сегодня все.