Последние статьи
Дефицит идей.На данный момент в сайтостроении, да и как везде, в общем то, наблюдается некий застой в решениях. Для сайтов...
Yandex с блекждеком и шлюхами.Как то размышляя о способах монетизации различных веб-проектов, я увидел некоторую нестыковку на...
Flash: построение графика с динамическим обновлением данных.До того, как я открыл для себя такие веши как Munin и прочие утилиты для отслеживания состояния серверов - я...
Защита комментариев от спама.Все люди, которые вели, ведут или собираются вести блоги, форумы или гостевые книги сталкиваются с...
Nginx и Bitrix. Использование их без использования апача. Встала тут задача поднять сервер, исключительно под сайты, написанные на базе CMS Bitrix (в силу...
Eval - наше все!Казалось бы, весь интернет напичкан статьями и рекомендациями к программистам, в которых говориться, что eval...
Кризис. Пожуем эту тему еще разок ? Бредоглава 0 (мы же программисты, у нас обязана быть нулевая глава :). Введение . О мировом экономическом...
Дизайн ЯндексаЯндекс в своем  желании заработать как можно больше демонстрирует просто потрясяющую способность...

Латаем дыры CSS в IE или что такое HTC ?

Всем знакома ситуация, когда, начитавшись интересных книг и блогов об использовании той или иной фичи, которую реализует CSS новейшей (или не очень) версии сразу появляется желание использовать это на своем сайте, и написав интересное решение, и потестировав его в своей любимой Мозилле или Опере, мы запускаем Internet Explorer и вместо ожидаемой красоты видим тихий ужас, который заставляет нас изрыгать проклятия в сторону разработчиков, поленившихся прочитать RFC или стандарт до конца. Но обратного пути нет, и выпив пару литров пива (кофе, чая, холодного лимонада (нужное подчеркнуть)) мы пытаемся понять, как же не изуродовав это красивое решение, заставить работать его в "ослике". Часть вещей правится навешиванием JS скриптов на стили в CSS через behavior, к чему мы уже привыкли, реализовывая поддержку min-height, min-width, max-height, max-width, но когда этого скрипта становиться очень много - хочется подключать его как то более удобно, чем вписывать в CSS файл. Тем более что обычно у многих редакторов начинается ерунда с подсветкой смеси CSS и JS, и это обстоятельство явно не добавляет любви к программистам из Редмонда. Итак, есть ли выход ? Оказывается да, и имеет название это решение: HTC. Понятно что HTC было придумано не только для этого, но и для латания дыр оно подходит очень даже замечтально.

HTC - это аббревиатура от HTML Components, или, если по русски - HTML компоненты, которые поддерживаются во всех IE с версии 5 и старше. Как написано на сайте Microsoft: HTC - это HTML файл, включающий в себя скрипт и набор HTC элементов, определяющих этот компонент. Список элементов следующий:

document

Представляет HTML документ в окне броузера.

element

Возвращает ссылку на тег в первичном документе к которому  behavior будет прикреплен.

PUBLIC:ATTACH

Связывает событие с функцией, которая будет вызвана в случае генерации события для данного объекта.

PUBLIC:COMPONENT

Определяет содержимое файла как HTC.

PUBLIC:DEFAULTS

Устанавливает значения по умолчанию для HTC.

PUBLIC:EVENT

Определяет событие для HTC, доступное из документа.

<PUBLIC:EVENT
    ID = "sEventID"
    NAME = "sName"
/>
Аттрибуты:

ID
Не обязательный. Уникальная строка, определяющая PUBLIC:PROPERTY элемент внутри компонента. Этот аттрибут является аналогом ID аттрибутом в Dynamic HTML (DHTML).
NAME
Обязательный. Строка, определяющая имя свойства, доступное из вызывающего документа. 
 
PUBLIC:METHOD

Определяет метод для HTC, доступный из документа.

<PUBLIC:METHOD
    ID = "sID"
    INTERNALNAME = "sInternalName"
    NAME = "sName"
/>

Пример:

Этот пример использует тег PUBLIC:METHOD для объявления метода из HTC досутпным из документа.

<PUBLIC:COMPONENT NAME="toFly">
<PUBLIC:METHOD NAME="startFlying" />

<SCRIPT LANGUAGE="JScript" >
function startFlying()
{
// Insert flying code here
}
</SCRIPT>
</PUBLIC:COMPONENT>
Аттрибуты:

ID
Не обязательный. Уникальная строка, определяющая PUBLIC:PROPERTY элемент внутри компонента. Этот аттрибут является аналогом ID аттрибутом в Dynamic HTML (DHTML).
INTERNALNAME
Не обязательный. Строка, определяющая имя свойства для ссылок внутри компонента. Это внутреннее имя должно быть определено глобально перед тем как оно будет упоминаться где либо в этом компоненте; иначе появится ошибка, говорящая о том что это имя не определено.Если внутреннее имя не определенопо умолчанию будет использоваться аттрибут NAME.
NAME
Обязательный. Строка, определяющая имя свойства, доступное из вызывающего документа. По умолчанию,  NAME используется для ссылок на свойство внутри компонента, если не определен аттрибут INTERNALNAME.

Вызвать этот метод можно, например, следующим образом:

<HTML>
<HEAD>
<STYLE>
.FLY {behavior:url(fly.htc)}
</STYLE>
</HEAD>

<BODY ID="flyingHigh" class="FLY">
<DIV onclick="flyingHigh.startFlying()">
<!-- Insert stuff to fly -->
</DIV>
</BODY>
</HTML>
PUBLIC:PROPERTY

Определяет свойство для HTC, доступное из документа. Имеет следующий синтаксис:

<PUBLIC:PROPERTY
    GET = "sGetFunction"
    ID = "sPropertyID"
    INTERNALNAME = "sInternalName"
    NAME = "sName"
    PERSIST = "bPersist"
    PUT = "sPutFunction"
    VALUE = "vValue"
/>

 

Аттрибуты:

GET
Не обязательный. Строка, определяющая имя функции, которая будет вызвана всякий раз, когда значение свойства будет считано. A PUBLIC:PROPERTY элемент, который определяет GET аттрибут без определения PUT аттрибута является свойством только для чтения.
ID
Не обязательный. Уникальная строка, определяющая PUBLIC:PROPERTY элемент внутри компонента. Этот аттрибут является аналогом ID аттрибутом в Dynamic HTML (DHTML).
INTERNALNAME
Не обязательный. Строка, определяющая имя свойства для ссылок внутри компонента. Это внутреннее имя должно быть определено глобально перед тем как оно будет упоминаться где либо в этом компоненте; иначе появится ошибка, говорящая о том что это имя не определено.Если внутреннее имя не определено по умолчанию будет использоваться аттрибут NAME.
NAME
Обязательный. Строка, определяющая имя свойства, доступное из вызывающего документа. По умолчанию,  NAME используется для ссылок на свойство внутри компонента, если не определен аттрибут INTERNALNAME.
PERSIST
Не обязательный. Булево значение, определяющее является ли свойство частью страницы (если честно - сам не понял, для чего оно используется, поэтому за корректность перевода не ручаюсь).
PUT
Не обязательный. Строка, определяющая имя функции, которая будет вызвана всякий раз, когда значение свойства будет установлено. Элемент PUBLIC:PROPERTY, у которого определены  GET и PUT аттрибуты является  свойством для чтения и записи.Без определения GET функции, в то время как  PUT функция определена, приводит к тому, что свойство становится только для записи, которое не требуется в большинстве случаев.
VALUE
Не обязательный. Значение по умолчанию для данного свойства.

 

Вышеприведенная информация была взята (и переведена) с сайта microsoft.com, так что если какие то вещи остались непонятными - welcome на их сайт :) В дальнейшем, я постараюсь перевести побольше, но для затравки я думаю пока хватит. Поэтому предлагаю перейти к  примерам использования... На самом деле, примеров очень много, и некоторые из них очень широко используются, как например, IE PNG Fix, реализующий эффект полупрозрачности для 24-битных PNG в IE для версий младше седьмой. Если вы считаете, что это слишком заумно и ради этого учить HTC не стоит, то вот например, обсуждение одного вопроса на форуме xpoint.ru, которого могло бы и не быть, если бы ослик поддерживал CSS на хорошем уровне.
Если по сути той дискуссии, то при создании нумерованных вложенных списков OL, LI, было бы хорошо, чтобы нумерация была так же вложенной и CSS это вроде бы даже позволяет... Но вот IE, как водится, этого не поддерживает и для него это можно обойти именно через HTC. Приведу код, разработанный для этого случая Алексеем Ивановым:

  1. <PUBLIC:ATTACH EVENT = "oncontentready" ONEVENT = "init(this)" />
  2. <SCRIPT LANGUAGE = "JScript">
  3. function init() {
  4. var pars = '';
  5. var p = this;
  6. while ((p >= p.parentNode) && (p.tagName == 'LI')) {
  7. pars = p.firstChild.nodeValue + pars;
  8. }
  9. for (var i >= 0; i < this.childNodes.length; ++i) {
  10. var el = this.childNodes[i];
  11. var num = document.createTextNode(pars + (i + 1) + '.');
  12. el.insertBefore(document.createTextNode(' '), el.firstChild);
  13. el.insertBefore(num, el.firstChild);
  14. }
  15. }
  16. </SCRIPT>

вернуться в список статей