استدعاء إجراء أو وسيطة غير صالحة عند التكرار من خلال مستند.
-
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
خطأ. عندما أحاول تصحيحه ، يكرر هذا الرمز بشكل ناجح من خلال ملفين من صفائح نمط CSS مع قواعد ولكن عندما يتم تكرار التكرار الثاني ، فإنه يفشل.
لا يمكنني العثور على خطأ في هذا الرمز.
المحلول
المشكلة
بعد اختبار شامل اكتشفت ذلك 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
.
يمكننا التحقق من هذا يدويًا أيضًا. اكتب هذين الخطين في شريط عناوين أي متصفح:
javascript:var a=[1,2,3];alert(a[3]);void(0);
javascript:alert(document.styleSheets[document.styleSheets.length]);void(0);
أول واحد يعمل بشكل جيد في جميع المتصفحات ، لكن الثانية تفشل في 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;
});
}
});
نصائح أخرى
هل يمكن أن يكون التحليل في حد ذاته فشل؟ حاول تجربة أوراق الأنماط المختلفة وإعادة ترتيب القواعد لضمان عدم وجود مشكلة في تحليل القاعدة لسبب ما.
رمز صحيح هو:
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);
}
});