llamada de procedimiento no válido o argumento cuestión es decir, cuando la iteración a través document.styleSheets utilizando $ each ()

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

Pregunta

He escrito el código que itera sobre todas las reglas de hojas de estilo globales y los almacena en una matriz / objeto. Yo uso este diccionario como objeto después de cambiar las reglas globales en lugar de crear estilos en elementos individuales.

Después de roturas de código en Internet Explorer 8, pero funciona bien en Firefox3.7 y 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;
        });
    });
});

Me sale error Invalid procedure call or argument. Cuando trato de depurarlo, repite este código con éxito a través de dos archivos de hojas de estilo CSS con reglas pero cuando se hace iteración de la segunda, se produce un error.

Me parece que no puede encontrar un error en el código.

¿Fue útil?

Solución

El problema

Después de pruebas exhaustivas descubrí que document.styleSheets no es una matriz regular en el IE. Es por eso que se rompe en la llamada $.each() cuando se llega al final.

Si echamos un vistazo a la función jQuery en sí tiene un bucle for para iterar sobre un objeto que tiene una propiedad length, creyendo falsamente que es una matriz. document.styleSheets tiene la propiedad length, pero no es, evidentemente, una matriz. Así que cuando se ejecuta este bucle for en $.each():

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

falla después del último elemento ha sido repiten a lo largo. Como podemos ver este bucle for no incrementa i por su propia cuenta, sino más bien la incrementa, mientras que la asignación de un nuevo valor a value.

Podemos comprobar esto manualmente. Escribir estas dos líneas en la barra de direcciones de cualquier navegador:

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

La primera de ellas funciona muy bien en todos los navegadores, pero la segunda falla en IE.

La solución

Tenemos que volver a escribir la iteración sobre las hojas de estilo

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

Otros consejos

¿Podría ser que la regla de análisis en sí está fallando? Experimentar con otras hojas de estilo y reordenar las reglas para asegurarse de que no hay un problema al analizar la regla por alguna razón.

verdadero código es:

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);
    }
});
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top