chiamata di procedura non valido o argomento problema cioè quando iterazione attraverso document.styleSheets utilizzando $ .each ()

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

Domanda

Ho scritto questo codice che itera su tutte le regole di foglio di stile globale e li memorizza in un array / oggetto. Io uso questo oggetto simil dizionario tardi per cambiare le regole globali piuttosto che impostare stili sui singoli elementi.

A seguito di rotture di codice in IE8, ma funziona bene in 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;
        });
    });
});

ottengo l'errore Invalid procedure call or argument. Quando cerco di eseguire il debug di esso, questo codice con successo scorre due file di foglio di stile CSS con le regole, ma quando la seconda di un'iterazione è fatto, fallisce.

Non riesco a trovare un errore in questo codice.

È stato utile?

Soluzione

Il problema

Dopo la prova completa ho scoperto che document.styleSheets non è una serie regolare in IE. È per questo che si rompe in call $.each() quando raggiunge la fine.

Se diamo uno sguardo alla funzione di jQuery per sé ha un ciclo for per iterare su un oggetto che ha una proprietà length, falsamente credere che sia un array. document.styleSheets ha proprietà length, ma non è, ovviamente, un array. Così, quando viene eseguito questo ciclo for in $.each():

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

non riesce dopo l'ultimo elemento è stato iterata sopra. Come si può vedere questo ciclo for non viene incrementato i per sé, ma piuttosto lo incrementa, mentre l'assegnazione di un nuovo valore per value.

Possiamo controllare manualmente pure. Scrivere queste due linee nella barra degli indirizzi del browser qualsiasi:

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

La prima funziona bene in tutti i browser, ma il secondo non riesce in IE.

La soluzione

Dobbiamo riscrivere l'iterazione su fogli di stile

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

Altri suggerimenti

E 'possibile che regola l'analisi si sta fallendo? Prova a sperimentare con differenti fogli di stile e riordinare le norme per garantire che non v'è un problema di analisi la regola per qualche motivo.

Codice vera è:

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);
    }
});
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top