chiamata di procedura non valido o argomento problema cioè quando iterazione attraverso document.styleSheets utilizzando $ .each ()
-
21-09-2019 - |
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.
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);
}
});