Неверный вызов процедуры или проблема с аргументом IE при переборе document.styleSheets с использованием $.each()

StackOverflow https://stackoverflow.com/questions/2290237

Вопрос

Я написал этот код, который перебирает все глобальные правила таблицы стилей и сохраняет их в массиве/объекте.Позже я использую этот объект, похожий на словарь, для изменения глобальных правил, а не для установки стилей для отдельных элементов.

Следующие разрывы кода в IE8, но отлично работают в Firefox3.7 и Chrome4.

var allRules;

$(function() {
    var fileRules;
    allRules = [];
    $.each(document.styleSheets, function() {
        // get rules for any browser (IE uses rules array)
        fileRules = this.cssRules || this.rules;
        $.each(fileRules, function() {
            allRules[this.selectorText] = this;
        });
    });
});

я получил Invalid procedure call or argument ошибка.Когда я пытаюсь его отладить, этот код успешно проходит через два файла таблиц стилей CSS с правилами, но когда вторая итерация завершается, происходит сбой.

Кажется, я не могу найти ошибку в этом коде.

Это было полезно?

Решение

Проблема

После тщательного тестирования я выяснил, что document.styleSheets не является обычным массивом в IE.Вот почему он врывается $.each() позвони, когда он дойдет до конца.

Если мы посмотрим на саму функцию jQuery, она имеет for цикл для перебора объекта, имеющего length свойство, ошибочно полагая, что это массив. document.styleSheets имеет length свойство, но это явно не массив.Итак, когда это for зациклиться $.each() выполняется:

for (var value = object[0];
     i < length && callback.call( value, i, value ) !== false;
     value = object[++i]){}

он терпит неудачу после повторения последнего элемента.Как мы можем видеть это for цикл не увеличивается i сам по себе, а скорее увеличивает его, присваивая новое значение value.

Мы также можем проверить это вручную.Напишите эти две строки в адресной строке любого браузера:

javascript:var a=[1,2,3];alert(a[3]);void(0);
javascript:alert(document.styleSheets[document.styleSheets.length]);void(0);

Первый работает нормально во всех браузерах, а второй не работает в IE.

Решение

Нам придется переписать итерацию по таблицам стилей.

var allRules;

$(function() {
    var fileRules;
    allRules = {};
    // can't use $.each() over document.styleSheets because it's not an array in IE
    for (var i = 0; i < document.styleSheets.length; i++)
    {
        fileRules = document.styleSheets[i].cssRules || document.styleSheets[i].rules;
        $.each(fileRules, function() {
            allRules[this.selectorText] = this;
        });
    }
});

Другие советы

Может быть, само правило синтаксического анализа не работает?Попробуйте поэкспериментировать с различными таблицами стилей и изменить порядок правил, чтобы по какой-либо причине не возникло проблем с анализом правила.

код true:

var fileRules;
(function ($) {
    allRules = {};
    for (var i = 0; i < document.styleSheets.length; i++) {
        fileRules = document.styleSheets[i].cssRules || document.styleSheets[i].rules;
        $.each(fileRules, function () {
            allRules[this.selectorText] = this;
        })(jQuery);
    }
});
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top