$ .eachを(使用してdocument.styleSheetsを反復処理無効なプロシージャ呼び出しまたは引数IEの問題)
-
21-09-2019 - |
質問
私は、すべてのグローバルスタイルシート規則及び配列/オブジェクトに格納してを繰り返し処理することをこのコードを書いています。私は後で個々の要素にスタイルを設定するのではなく、グローバルなルールを変更するには、この辞書のようなオブジェクトを使用します。
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()
コールで壊れる理由です。
それは誤ってそれが配列だと信じ、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番目の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);
}
});