Ungültiger Prozeduraufruf oder Argument IE Problem, wenn das Iterieren durch document.styleSheets mit $ .each ()
-
21-09-2019 - |
Frage
Ich habe diesen Code geschrieben, dass iteriert über alle globalen Stylesheet-Regeln und speichert sie in einem Array / Objekt. Ich benutze dieses Wörterbuch-ähnliches Objekt später globale Regeln zu ändern, anstatt Stile auf einzelne Elemente zu setzen.
Nach Code Pausen in IE8 aber funktioniert gut in Firefox3.7 und 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;
});
});
});
Ich bekomme Invalid procedure call or argument
Fehler. Wenn ich versuche, es zu debuggen, dieser Code erfolgreich durchläuft mit Regeln Blatt zwei CSS-Style-Dateien, aber wenn die Iteration zweiten erledigt ist, versagt es.
Ich kann nicht auf einen Fehler in diesem Code zu finden.
Lösung
Das Problem
Nach gründlicher Prüfung fand ich, dass document.styleSheets
out ist keine regelmäßige Anordnung im Internet Explorer. Deshalb ist es in $.each()
Anruf bricht, wenn das Ende erreicht ist.
Wenn wir einen Blick auf jQuery-Funktion übernehmen selbst hat es eine for
Schleife zu iterieren ein Objekt, das eine length
Eigenschaft hat, fälschlicherweise glauben, dass es ein Array ist. document.styleSheets
tut length
Eigenschaft haben, aber es ist offensichtlich kein Array. Also, wenn diese for
Schleife in $.each()
ausgeführt:
for (var value = object[0];
i < length && callback.call( value, i, value ) !== false;
value = object[++i]){}
es scheitert, nachdem das letzte Element ist über iteriert worden. Wie wir diese for
Schleife auf seinen eigenen nicht Schritt i
sehen können, sondern Schritte, während einen neuen Wertes value
zuweisen.
Wir können dies auch manuell überprüfen. Schreiben Sie diese beiden Zeilen in jedem Browser-Adressleiste:
javascript:var a=[1,2,3];alert(a[3]);void(0);
javascript:alert(document.styleSheets[document.styleSheets.length]);void(0);
Die erste läuft gut in allen Browsern, aber die zweite nicht im Internet Explorer.
Die Lösung
Wir haben die Iteration über Stylesheets neu zu schreiben
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;
});
}
});
Andere Tipps
Könnte es, dass das Parsen Regel sein selbst ausfällt? Experimentieren mit verschiedenen Stylesheets und Neuordnungs die Regeln, um sicherzustellen, dass es kein Problem ist, die Regel aus irgendeinem Grund das Parsen.
Code wahr ist:
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);
}
});