$ .eachを(使用してdocument.styleSheetsを反復処理無効なプロシージャ呼び出しまたは引数IEの問題)

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

質問

私は、すべてのグローバルスタイルシート規則及び配列/オブジェクトに格納してを繰り返し処理することをこのコードを書いています。私は後で個々の要素にスタイルを設定するのではなく、グローバルなルールを変更するには、この辞書のようなオブジェクトを使用します。

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エラーを取得します。私はそれをデバッグしようとすると、このコードはsucessfullyルールを持つ2つのCSSスタイルシートファイルを反復処理が、第2 1の反復が行われたときに、それが失敗します。

私はこのコードでエラーを見つけることができないようです。

役に立ちましたか?

解決

問題

は徹底的なテストの後、私はdocument.styleSheetsはIEでの規則的な配列ではないことが分かりました。それが最後に到達したとき$.each()コールで壊れる理由です。

私たちは、jQueryの機能そのものを見てみた場合、それは誤ってそれが配列だと信じ、forプロパティを持つオブジェクトを反復処理するためにlengthループを持っています。 document.styleSheetslength性質を持っているが、それは明らかに、配列ではありません。だから、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番目の1が、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;
        });
    }
});

他のヒント

それはパース、ルール自体が失敗していることだろうか?何らかの理由でルールを解析し、問題がないことを保証するために、異なるスタイルシートとし、ルール順序を変更試してみます。

コードTRUEです。

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);
    }
});
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top