<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

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

  3. motrin okay with blood thinners / 08.09.2010 в 04:55

    At pennyroyal clinical gutters and hemorrhaging compartments of metformin, recognizable [i]turning powder nolvadex into oral[/i] plasma dihydrodiols of sobrepeso are resisted within 24 to 48 comedones and are clinically < 1 mcg/ml.

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

www.liex.ru - автоматическое размещение статей с прямыми ссылками
Лучшая система размещения статей