في الآونة الأخيرة ، أكتب إطار عمل JavaScript. لقد قمت للتو بتغليف الحدث الذي تم تحميله ، وكنت متحمسًا قليلاً. أخذت ملاحظات حول المبادئ وقضايا التوافق التي واجهتها أثناء عملية التطوير ، وذلك لتجنب النسيان في كل مكان.
عندما نكتب رمز JS ، عادةً ما نضيف window.onload ، بشكل أساسي لاستخدام getElementById و GetElementSbyTagName وطرق أخرى لتحديد عناصر DOM للتشغيل بعد تحميل DOM. ومع ذلك ، سوف تنتظر Window.Load حتى يتم تحميل DOM و SCRIPT و CSS ، ويتم تشغيل جميع الموارد في الصورة أو حتى المعفاة من iFrame. في كثير من الحالات ، تحتوي صفحة الويب على المزيد من الصور وأكبر. يستغرق تحميل الصورة وقتًا طويلاً ، ومن الواضح أنه قد فات الأوان لتنفيذ JS ، والذي سيؤثر غالبًا على تجربة المستخدم.
تحتوي العديد من أطر عمل JS على مستند. وظيفة جاهزة ، مثل طريقة $ $ (وثيقة). READY () ، والتي يمكن تنفيذ رمز JS فور تحميل DOM ، بحيث يمكن تحميل الصورة ببطء.
جوهر المستند. READY هو الحدث الذي تم تحميله. يمكن أن تستخدم Firefox و Chrome و Opera و Safari و IE9+ جميعًا AddEventListener ('DomContentLoaded' ، fn ، false) لربط الحدث. لا يدعم IE6 ~ 8 حدث DomContentLoaded ، لذلك يجب إجراء معالجة التوافق لـ IE6 ~ 8.
تشير المعلومات إلى أنه يمكن لـ IE6 ~ 8 استخدام الحدث المستند. إذا تم تضمين iframe في الصفحة ، فستنتظر المستند. readystate من IE6 ~ 8 حتى يتم تحميل جميع الموارد في iframe قبل اكتمالها. في هذا الوقت ، يصبح iFrame مستخدمًا رئيسيًا يستغرق وقتًا طويلاً. ولكن بعد الاختبار ، حتى لو لم يكن هناك iFrame في الصفحة ، عندما يساوي ReadyState مع اكتماله ، يتم تشغيل حدث Onload فعليًا بدلاً من الحدث الذي تم تحميله ، والذي يثير الدهشة هذه النقطة.
لحسن الحظ ، IE لديه طريقة doscroll فريدة من نوعها. عندما لا يتم تحميل الصفحة DOM ، سيتم الإبلاغ عن خطأ عند استدعاء طريقة doscroll. على العكس ، طالما يتم استدعاء doscroll على فترات حتى لا يتم الإبلاغ عن أي خطأ ، فهذا يعني أنه تم تحميل الصفحة DOM. هذه الطريقة صالحة بغض النظر عما إذا كان المحتوى الموجود في الصورة و iFrame قد تم تحميله.
إذا كانت ملفات JS المتعددة مرتبطة بالحدث المستند. من أجل منع المتصفح من الربط والأداء بشكل متكرر بطريقة منظمة ، يمكن تقديم آلية قائمة انتظار الحدث لحل المشكلة.
ما سبق هو قضية المبدأ والتوافق في الحدث المستند. فيما يلي فقرة من رمز المثال. من أجل تسهيل فهم عملية التنفيذ ، تتم كتابة عملية التنفيذ في التعليقات باستخدام وضع تغليف الوظائف. إذا كان هناك أي عدم ملاءمة ، فيرجى إعطائي بعض النصائح.
نسخة الكود كما يلي:
// احفظ قائمة انتظار الحدث لـ DomReady
eventQueue = [] ؛
// احكم ما إذا كان قد تم تحميل DOM
isReady = false ؛
// احكم ما إذا كان DomReady ملزم
isBind = false ؛
/*تنفيذ DomReady ()
*
*@param {function}
*@تنفيذ يدفع معالج الحدث إلى قائمة انتظار الحدث وربط DomContentLoaded
* إذا تم الانتهاء من تحميل DOM ، فننفذ على الفور
*@المتصل
*/
وظيفة domready (fn) {
إذا (isReady) {
fn.call (نافذة) ؛
}
آخر{
eventQueue.push (fn) ؛
} ؛
bindReady () ؛
} ؛
/*domready الحدث الربط
*
*@param null
*@تنفيذ المتصفحات الحديثة ربط domcontentenced من خلال addevlistener ، بما في ذلك IE9+
يحدد IE6-8 ما إذا كان قد تم تحميل DOM عن طريق الحكم على Doscroll
*@Caller DomReady ()
*/
وظيفة bindReady () {
إذا (isReady) العودة ؛
إذا (Isbind) العودة ؛
Isbind = صحيح ؛
if (window.adDeventListener) {
document.adDeventListener ('domcontentloaded' ، execfn ، false) ؛
}
آخر إذا (window.attachevent) {
doscroll () ؛
} ؛
} ؛
/*يحدد Doscroll ما إذا كان قد تم تحميل DOM من IE6-8.
*
*@param null
*@تنفيذ Doscroll يحدد ما إذا كان DOM يتم تحميله
*@Caller BindReady ()
*/
وظيفة doscroll () {
يحاول{
document.documentElement.doscroll ('Left') ؛
}
catch (خطأ) {
Return SetTimeout (Doscroll ، 20) ؛
} ؛
execfn () ؛
} ؛
/*قائمة انتظار حدث التنفيذ
*
*@param null
*@تنفيذ معالج حدث تنفيذ الحلقة في قائمة الانتظار
*@Caller BindReady ()
*/
وظيفة execfn () {
إذا (! isReady) {
isReady = صحيح ؛
لـ (var i = 0 ؛ i <eventqueue.length ؛ i ++) {
EventQueue [i] .Call (window) ؛
} ؛
eventQueue = [] ؛
} ؛
} ؛
// ملف JS 1
DomReady (function () {
...
}) ؛
// ملف JS 2
DomReady (function () {
...
}) ؛
// لاحظ أنه إذا تم تحميله بشكل غير متزامن ، فلا تربط طريقة DomReady ، وإلا فلن يتم تنفيذ الوظيفة.
// لأنه قبل تحميل JS غير المتزامن ، تم إطلاق DomContentLoaded ، ولا يمكن الاستماع إلى AddeventListener عند التنفيذ
صفحة الاختبار: يتم تحميل صورتين كبيرتين. يتطلب Onload تحميل الصورة قبل تنفيذ JS. يحتاج DomContentloaded فقط إلى الانتظار حتى يتم تحميل DOM لتنفيذ JS. يمكنك فتح Firebug لعرض عملية التحميل. تذكر تنظيف ذاكرة التخزين المؤقت للمتصفح قبل كل اختبار.