Читать «Разгони свой сайт» онлайн - страница 82

Николай Мациевский

Динамические выражения

Давайте рассмотрим следующий блок CSS-кода:

#myDiv {

border: 10px solid Red;

width: expression(ieBox ? "100px" : "80px");

}

Даже при том предположении, что ieBox — это постоянный флаг, который выставляется в true, когда IE находится в режиме обратной совместимости, заданное выражение будет вычисляться каждый раз в "80px". Хотя выражение будет постоянным для данной страницы, оно все равно будет пересчитываться много раз. Основной вопрос заключается в том, как избавиться от этих ненужных вычислений.

Вычисление постоянных

Вот что мы собираемся сделать: пройтись по всем объявлениям стилей и заменить вычисление выражения его постоянным значением. В предыдущем примере, предполагая, что мы используем IE6 в стандартном режиме, нам хотелось бы видеть следующий код:

#myDiv {

border: 10px solid Red;

width: 80px;

}

Итак, как нам убедиться в том, что наше выражение постоянно? Самым простым путем является пометить само выражение, чтобы мы могли его легко обнаружить. Решением в данном случае будет заключение выражения в вызов функции, которая нам известна и заранее объявлена.

function constExpression(x) {

return x;

}

Итак, в нашем CSS-блоке мы напишем следующее:

#myDiv {

border: 10px solid Red;

width: expression(constExpression(ieBox ? "100px" : "80px"));

}

Использование

Во-первых, мы сперва должны подключить библиотеку cssexpr.js (о ней речь чуть ниже) и только потом вызывать нашу функцию constExpression.

<script type="text/javascript" src="cssexpr.js"></script>

После этого можно использовать constExpression в любом задаваемом блоке стилей (<style>), или любом подключаемом файле стилей (<link>), или при использовании директивы @import. Следует заметить, что атрибут style у тегов для ускорения работы не проверяется.

Реализация

Идея заключается в том, чтобы перебрать все объявленные таблицы стилей, а в них — все правила и их конечные объявления. Для этого мы начнем с массива document.styleSheets.

function simplifyCSSExpression() {

try {

var ss = document.styleSheets;

var i = ss.length

while (i-- > 0) {

simplifyCSSBlock(ss[i]);

}

}

catch (exc) {

alert("Обнаружили ошибку при обработке css. Страница будет " +

"работать в прежнем режиме, хотя, возможно, не так “ +

“быстро");

throw exc;

}

}

В таблицах стилей мы пройдемся по массиву импортируемых таблиц (@import), а затем уже по объявлениям стилевых правил. Для того чтобы не совершать пустых телодвижений, будем проверять, что cssText содержит expression(constExpression).

function simplifyCSSBlock(ss) {

// Проходимся по import'ам

var i = ss.imports.length;

while (i-- > 0)