Идея заключается в том, чтобы перебрать все объявленные таблицы стилей, а в них — все правила и их конечные объявления. Для этого мы начнем с массива 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) simplifyCSSBlock(ss.imports[i]); // если в cssText'е нет constExpression, сворачиваемся if (ss.cssText.indexOf("expression(constExpression(") == -1) return; var rs = ss.rules; var rl = rs.length; while (rl-- > 0) simplifyCSSRule(rs[j]); }
Затем мы уже можем обрабатывать для каждого правила cssText
и заменять его, используя функцию simplifyCSSRuleHelper
, чтобы текст объявления из динамического становился статическим.
function simplifyCSSRule(r) { var str = r.style.cssText; var str2 = str; var lastStr; // обновляем строку, пока она еще может обновляться do { lastStr = str2; str2 = simplifyCSSRuleHelper(lastStr); } while (str2 != lastStr) if (str2 != str) r.style.cssText = str2; }
Вспомогательная функция находит первое возможное выражение и исполняет его, затем заменяет выражение полученным значением.
function simplifyCSSRuleHelper(str) { var i = str.indexOf("expression(constExpression("); if (i == -1) return str; var i2 = str.indexOf("))", i); var hd = str.substring(0, i); var tl = str.substring(i2 + 2); var exp = str.substring(i + 27, i2); var val = eval(exp) return hd + val + tl; }
Наконец, нам нужно добавить вызов simplifyCSSExpression
при загрузке страницы.
if (/msie/i.test(navigator.userAgent) && window.attachEvent != null) { window.attachEvent("onload", function () { simplifyCSSExpression(); }); }