Ungültiger Prozeduraufruf oder Argument IE Problem, wenn das Iterieren durch document.styleSheets mit $ .each ()

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

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.

War es hilfreich?

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);
    }
});
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top