3

すべてのグローバルスタイルシートルールを繰り返し、それらを配列/オブジェクトに格納するこのコードを作成しました。後でこの辞書のようなオブジェクトを使用して、個々の要素にスタイルを設定するのではなく、グローバルルールを変更します。

次のコードはIE8で壊れますが、Firefox3.7と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;
        });
    });
});

Invalid procedure call or argumentエラーが発生します。デバッグしようとすると、このコードはルールを使用して2つのCSSスタイルシートファイルを正常に反復しますが、2番目の反復が実行されると失敗します。

このコードにエラーが見つからないようです。

4

3 に答える 3

13

問題

document.styleSheets徹底的なテストの結果、これはIEの通常のアレイではないことがわかりました。$.each()そのため、最後に到達すると通話が中断します。

jQuery関数自体を見るとfor、プロパティを持つオブジェクトを反復処理するループがあり、lengthそれが配列であると誤って信じています。document.styleSheetsプロパティはありlengthますが、明らかに配列ではありません。したがって、このforループイン$.each()が実行されると、次のようになります。

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

最後の要素が繰り返された後、失敗します。ご覧のとおり、このforループはそれ自体ではインクリメントされませんiが、に新しい値を割り当てている間にインクリメントされvalueます。

これは手動でも確認できます。ブラウザのアドレスバーに次の2行を入力します。

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

最初のブラウザはすべてのブラウザで正常に動作しますが、2番目のブラウザはIEで失敗します。

ソリューション

スタイルシートの反復を書き直す必要があります

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;
        });
    }
});
于 2010-02-18T17:31:51.100 に答える
0

解析ルール自体が失敗している可能性がありますか?さまざまなスタイルシートを試してルールを並べ替えて、何らかの理由でルールの解析に問題がないことを確認してください。

于 2010-02-18T16:35:20.997 に答える
-2

真のコードは次のとおりです。

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);
    }
});
于 2011-06-28T04:47:44.980 に答える