<abbr> и <q> в Internet Explorer
Всем известно, что самый замечательный браузер «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 = '«' + list[i].innerHTML + '»';
}
}
IE8b1 выдает такой же номер версии «JScript», как и IE 7, поэтому «отсекаем» его, используя поиск подстроки «MSIE 8.» в строке, возвращаемой выражением «navigator.userAgent».
Добавление кавычек выполняется заменой «.innerHTML» для каждого тега <q> на результат сложения 3-х строк: ««», «list[i].innerHTML» и «»», где «list[i].innerHTML» — HTML-код текущего тега <q> на каждом шаге цикла «for», перебирающего по порядку все теги <q>, встречающиеся в документе. Вставляем именно ««» и «»» — «елочки», потому что в русской типоргафике принято ставить кавычки такого вида. Можно пойти дальше и по правилам типографики оформить вложенные 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 = '«' + list[i].innerHTML + '»';
}
}
};
Теперь объект «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 = '«' + list[i].innerHTML + '»';
}
},
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-лента комментариев к этой статье | Обратная ссылка (trackback link)



Почему нельзя просто сделать так:
document.createElement(’abbr’);
и не плодить кучу кода?
Да, лучше так и сделать
не знал я этого способа, когда писал статью.
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.