Appel de procédure incorrect ou un argument problème IE lorsque itérer document.styleSheets à l'aide de $ .Chaque ()

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

Question

J'ai écrit ce code qui itère sur toutes les règles de feuille de style mondial et les stocke dans un tableau / objet. J'utilise cet objet dictionnaire comme plus tard pour modifier les règles globales plutôt que de définir des styles sur des éléments individuels.

Après les pauses de code dans IE8, mais fonctionne très bien dans Firefox3.7 et 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;
        });
    });
});

J'obtiens l'erreur de Invalid procedure call or argument. Lorsque je tente de le déboguer, ce code de deux fichiers à travers itère de feuille de style CSS avec des règles, mais quand la deuxième itération de l'est fait, il échoue.

Je ne peux pas sembler trouver une erreur dans ce code.

Était-ce utile?

La solution

Le problème

Après des tests approfondis j'ai découvert que document.styleSheets n'est pas un réseau régulier dans IE. Voilà pourquoi il se brise appel $.each() quand il arrive à la fin.

Si nous jetons un coup d'œil à la fonction jQuery lui-même, il a une boucle de for à itérer sur un objet qui possède une propriété length, croyant à tort qu'il est un tableau. document.styleSheets n'ont la propriété length, mais il est de toute évidence pas un tableau. Ainsi, lorsque cette boucle de for en $.each() est exécuté:

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

il échoue après le dernier élément a été itéré. Comme nous pouvons voir cette boucle de for n'incrémente pas i sur son propre mais incrémente plutôt tout en attribuant une nouvelle valeur à value.

Nous pouvons vérifier manuellement. Écrivez ces deux lignes dans la barre d'adresse de tout navigateur:

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

Le premier fonctionne très bien dans tous les navigateurs, mais la seconde échoue dans IE.

La solution

Nous devons réécrire l'itération sur des feuilles de style

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

Autres conseils

Serait-ce que la règle de l'analyse elle-même échec? Essayez d'expérimenter avec différentes feuilles de style et réorganiser les règles pour assurer qu'il n'y a pas un problème pour analyser la règle pour une raison quelconque.

vrai code est:

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);
    }
});
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top