<abbr> и <q> в Internet Explorer

Octane, 03.08.2008

Всем известно, что самый замечательный браузер «Internet Explorer» ниже 7-й версии не поддерживает тег <abbr> — аббревиатура, а в вплоть до 7-й версии включительно невозможно средствами CSS задать оформление кавычек для тега <q> — inline-цитата. Что же делать? В случае с <abbr> можно заменить этот тег на похожий <acronym>, который поддерживает IE, а вот с <q> все сложнее, потому что IE не поддерживает ни «Generated Content» не селекторы «:before» и «:after» в CSS.

Итак, добавим поддержку <abbr>, а точнее его эмуляцию, для IE ниже 7-й версии. Для этого заменим <abbr></abbr> на <span class="abbr"></span>:

function abbr() {
  var node = document.getElementsByTagName('body')[0];
  node.innerHTML = node.innerHTML
  .replace(/<ABBR/g, '<SPAN class="abbr"')
  .replace(/<\/ABBR>/g, '</SPAN>');
}

Почему используется «innerHTML», а не «getElementsByTagName('abbr')»? Потому что IE не воспринимает <abbr> как тег, и «getElementsByTagName('abbr')» вернет «пустой» массив. Еще одна особенность IE (и Opera) — имена тегов, в нашем случае, необходимо писать заглавными буквами: .replace(/<\/ABBR>/g, '</SPAN>'), а не .replace(/<\/abbr>/, '</span>').

Мы заменили все <abbr> на <span class="abbr"> тем самым добавили поддержку отображения текста, записанного в атрибут «title», во «всплывающей» подсказке.

Пример: XHTML

Теперь оформим <span class="abbr"> так же, как и <abbr> в CSS:

abbr, span.abbr {
/* стили для <abbr> */
} 

Добавим распознавание IE и его версии, чтобы не выполнять замену для нормальных браузеров и ненорм IE версии 7 и выше:

var MSIE = 0/*@cc_on+@_jscript_version*10%10@*/;
function abbr() {
  if(MSIE && MSIE < 7) {
    var node = document.getElementsByTagName('body')[0];
    node.innerHTML = node.innerHTML
    .replace(/<ABBR/g, '<SPAN class="abbr"')
    .replace(/<\/ABBR>/g, '</SPAN>');
  }
}

Переменная «MSIE» равна 0 если используется любой браузер, кроме IE, или содержит номер версии «JScript», поддерживаемый IE:

  • 1 — «JScript» версии 5.1 в IE5.0
  • 5 — «JScript» версии 5.5 в IE5.5
  • 6 — «JScript» версии 5.6 в IE6.0
  • 7 — «JScript» версии 5.7 в IE 7.0 и 8.0b1

Таким образом, мы еще и отсекаем IE4, т. к. результатом выполнения выражения «0 + @_jscript_version * 10 % 10» будет 0.

Что же за конструкция «/*@cc_on … @*/» и переменная «@_jscript_version»? Первое — это «Conditional Compilation» — условное выполнение в «JScript». Это аналог «условных комментариев» (Conditional Comments), которые воспринимает только IE, второе — зарезервированная переменная, в которой хранится номер версии «JScript».

Эта пляска с собачками называется «условное выполнение» (Conditional Compilation) и формально вообще не является JavaScript'ом, это JScript. Если я не ошибаюсь, только его IE и понимает, а официальный JavaScript работает только благодаря довольно широкой совместимости этих языков.

Вадим Макеев

Браузеры, поддерживающие «JavaScript», просто проигнорируют выражение внутри «/*@cc_on … @*/», посчитав его за обычный комментарий вида «/* … */», и переменная «MSIE» останется равной 0.

Получается, что выражение «MSIE && MSIE < 7» будет равно «true» в случае если используется IE5.0, 5.5 или 6.0, что собственно нам и требовалось.

Добавим кавычки для inline-цитат в IE ниже 8-й версии:

function quote() {
  if(MSIE && navigator.userAgent.search('MSIE 8.') == -1) {
    var i, list = document.getElementsByTagName('q'),
    length = list.length;
    for(i = 0; i < length; i++)
      list[i].innerHTML = '&laquo;' + list[i].innerHTML + '&raquo;';
  }
}

IE8b1 выдает такой же номер версии «JScript», как и IE 7, поэтому «отсекаем» его, используя поиск подстроки «MSIE 8.» в строке, возвращаемой выражением «navigator.userAgent».

Добавление кавычек выполняется заменой «.innerHTML» для каждого тега <q> на результат сложения 3-х строк: «&laquo;», «list[i].innerHTML» и «&raquo;», где «list[i].innerHTML» — HTML-код текущего тега <q> на каждом шаге цикла «for», перебирающего по порядку все теги <q>, встречающиеся в документе. Вставляем именно «&laquo;» и «&raquo;» — «елочки», потому что в русской типоргафике принято ставить кавычки такого вида. Можно пойти дальше и по правилам типографики оформить вложенные inline-цитаты, но такие случаи встречаются крайне редко, поэтому не будем усложнять код и остановимся на таком варианте.

Перепишем наш код более грамотно, чтобы не засорять глобальное пространство имен:

var correction = {
  MSIE: 0/*@cc_on+@_jscript_version*10%10@*/,
  abbr: function() {
    if(this.MSIE && this.MSIE < 7) {
      var node = document.getElementsByTagName('body')[0];
      node.innerHTML = node.innerHTML
      .replace(/<ABBR/g, '<SPAN class="abbr"')
      .replace(/<\/ABBR>/g, '</SPAN>');
    }
  },
  quote: function() {
    if(this.MSIE && navigator.userAgent.search('MSIE 8.') == -1) {
      var i, list = document.getElementsByTagName('q'),
      length = list.length;
      for(i = 0; i < length; i++)
        list[i].innerHTML = '&laquo;' + list[i].innerHTML + '&raquo;';
    }
  }
};

Теперь объект «correction» содержит числовое значение «MSIE» и 2 функции: «abbr» и «quote». Выполним эти функции по событию «window.onload»:

var correction = {
  MSIE: 0/*@cc_on+@_jscript_version*10%10@*/,
  abbr: function() {
    if(this.MSIE && this.MSIE < 7) {
      var node = document.getElementsByTagName('body')[0];
      node.innerHTML = node.innerHTML
      .replace(/<ABBR/g, '<SPAN class="abbr"')
      .replace(/<\/ABBR>/g, '</SPAN>');
    }
  },
  quote: function() {
    if(this.MSIE && navigator.userAgent.search('MSIE 8.') == -1) {
      var i, list = document.getElementsByTagName('q'),
      length = list.length;
      for(i = 0; i < length; i++)
        list[i].innerHTML = '&laquo;' + list[i].innerHTML + '&raquo;';
    }
  },
  fixIE: function(listener) {
    if(window.attachEvent) window.attachEvent('onload', function() {
      correction.abbr();
      correction.quote();
    });
  }
};

correction.fixIE();

Мы добавили функцию «fixIE», которая поместит в обработчик события «window.onload» запуск функций «abbr» и «quote». Объект «correction» можно расширять, добавляя всевозможные «фиксы» для разных браузеров.

Теперь Вы можете использовать теги <abbr> и <q> на страницах Вашего сайта, не боясь, что для пользователей IE они будут представлены в неправильном виде.

Подписаться на обновления блога

Вам понравился наш блог, хотите следить за обновлениями? Подпишитесь на RSS рассылку или рассылку по электронной почте. Так же вы можете следить за нами в Twitter.

Категории: Internet Explorer, JavaScript | Комментировать

Комментарии

  1. мамбет / 18.09.2009 в 22:13

    Почему нельзя просто сделать так:

    document.createElement(‘abbr’);

    и не плодить кучу кода?

  2. Octane / 19.09.2009 в 01:54

    Да, лучше так и сделать :-) не знал я этого способа, когда писал статью.

Оставить комментарий

480×60
480×60