Procedimento inválido Ligue ou argumento, isto é, quando itera através do document.stylesheets usando $ .EECH ()

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

Pergunta

Eu escrevi este código que itera sobre todas as regras da folha de estilo global e as armazena em uma matriz/objeto. Eu uso esse objeto semelhante ao dicionário posteriormente para alterar as regras globais, em vez de definir estilos em elementos individuais.

Após as quebras de código no IE8, mas funciona bem no Firefox3.7 e 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;
        });
    });
});

eu recebo Invalid procedure call or argument erro. Quando tento depurar, esse código itera com sucesso através de dois arquivos de folha de estilo CSS com regras, mas quando a segunda é feita, ela falha.

Não consigo encontrar um erro neste código.

Foi útil?

Solução

O problema

Após testes completos, descobri que document.styleSheets Não é uma matriz regular no IE. É por isso que quebra $.each() Ligue quando chegar ao fim.

Se dermos uma olhada na função jQuery, ele tem um for loop para iterar sobre um objeto que tem um length Propriedade, acreditando falsamente que é uma matriz. document.styleSheets tem length propriedade, mas obviamente não é uma matriz. Então, quando isso for loop in $.each() É executado:

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

Falha depois que o último elemento foi iterado. Como podemos ver isso for O loop não aumenta i por si só, mas o incrementam ao atribuir um novo valor a value.

Podemos verificar isso manualmente também. Escreva essas duas linhas na barra de endereços de qualquer navegador:

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

O primeiro funciona bem em todos os navegadores, mas o segundo falha no IE.

A solução

Temos que reescrever a iteração sobre as folhas de estilo

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;
        });
    }
});

Outras dicas

Será que a própria regra da análise está falhando? Tente experimentar diferentes folhas de estilo e reordenar as regras para garantir que não haja um problema para analisar a regra por algum motivo.

O código 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);
    }
});
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top