الحصول على إشعار عند تحميل صفحة DOM (ولكن قبل window.onload)

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

  •  09-06-2019
  •  | 
  •  

سؤال

أعلم أن هناك بعض الطرق لتلقي إشعارات عند تحميل نص الصفحة (قبل تحميل جميع الصور وموارد الطرف الثالث التي تقوم بتشغيل window.onload الحدث)، ولكن الأمر يختلف بالنسبة لكل متصفح.

هل هناك طريقة محددة للقيام بذلك على جميع المتصفحات؟

أعرف حتى الآن ما يلي:

  • DOMContentLoaded :على Mozilla وOpera 9 وأحدث WebKits.يتضمن ذلك إضافة مستمع إلى الحدث:

    document.addEventListener( "DOMContentLoaded", [وظيفة init], false );

  • السيناريو المؤجل:في IE، يمكنك إرسال علامة SCRIPT مع السمة @defer، والتي سيتم تحميلها بشكل موثوق فقط بعد إغلاق علامة BODY.

  • الاقتراع:في المتصفحات الأخرى، يمكنك الاستمرار في الاقتراع، ولكن هل هناك شيء قياسي للاستفتاء عليه، أم أنك بحاجة إلى القيام بأشياء مختلفة في كل متصفح؟

أود أن أكون قادرًا على الاستمرار دون استخدام document.write أو الملفات الخارجية.

يمكن القيام بذلك ببساطة عبر jQuery:

$(document).ready(function() { ... })

لكنني أكتب مكتبة JS ولا يمكنني الاعتماد على وجود jQuery دائمًا.

هل كانت مفيدة؟

المحلول

لا توجد طريقة عبر المتصفحات للتحقق من أن DOM جاهز - وهذا هو سبب وجود مكتبات مثل jQuery، للتخلص من الأجزاء الصغيرة السيئة من عدم التوافق.

تدعم موزيلا وأوبرا وWebKit الحديثة DOMContentLoaded حدث.يحتاج IE وSafari إلى اختراقات غريبة مثل تمرير النافذة أو التحقق من أوراق الأنماط.التفاصيل الدموية موجودة في ملف jQuery bindReady() وظيفة.

نصائح أخرى

لقد وجدت هذه الصفحة، والتي تعرض حلاً مدمجًا ومكتفيًا بذاته.يبدو أنه يعمل على كل متصفح ولديه شرح حول كيفية:

http://www.kryogenix.org/days/2007/09/26/shortloaded

تستخدم YUI ثلاثة اختبارات للقيام بذلك:بالنسبة إلى Firefox وWebKit الحديث، يوجد حدث DOMContentLoaded الذي تم إطلاقه.بالنسبة إلى متصفح Safari الأقدم، تمت مراقبة document.readyState حتى يصبح "محملًا" أو "مكتملًا".بالنسبة إلى IE، يتم إنشاء علامة HTML <P> ويتم استدعاء الأسلوب "doScroll()" والذي يجب أن يحدث خطأ إذا لم يكن DOM جاهزًا.المصدر ل YAHOO.util.Event يعرض الكود الخاص بـ YUI.ابحث عن "doScroll" في Event.js.

سيوفر لك استخدام مكتبة مثل jQuery ساعات لا حصر لها من عدم تناسق المتصفحات.

في هذه الحالة مع jQuery يمكنك فقط

$(document).ready ( function () {
    //your code here
});

إذا كنت فضوليًا، يمكنك إلقاء نظرة على المصدر لترى كيف يتم ذلك، ولكن في هذا اليوم وهذا العصر، لا أعتقد أنه يجب على أي شخص إعادة اختراع هذه العجلة عندما يقوم كاتب المكتبة بكل العمل المؤلم نيابةً عنك.

ما عليك سوى أخذ جزء التعليمات البرمجية ذي الصلة من jQuery، حيث قام John Resig بتغطية معظم القواعد المتعلقة بهذه المشكلة بالفعل في jQuery.

لماذا لا هذا:

<body>  
  <!-- various content -->  
  <script type="text/javascript">  
  <!--  
    myInit();  
  -->
  </script>  
</body>  

إذا فهمت الأمور بشكل صحيح، فسيتم تنفيذ myInit بمجرد وصول المتصفح إليه في الصفحة، وهو آخر شيء في النص.

الحل الرائع للمتصفح الذي تبحث عنه....غير موجود...(تخيل صوت حشد كبير يقول "آههههههههههههههههههه").

DomContentLoaded هي ببساطة أفضل لقطة لديك.ما زلت بحاجة إلى polling تقنية لـ IE-oldies.

  1. حاول استخدام addEventListener؛
  2. إذا لم يكن متاحًا (IE بشكل واضح)، فتحقق من الإطارات؛
  3. إذا لم يكن هناك إطار، فقم بالتمرير حتى لا يتم طرح أي خطأ (الاقتراع)؛
  4. إذا كان الإطار، استخدم IE events document.onreadystatechange;
  5. بالنسبة للمتصفحات الأخرى غير الداعمة، استخدم حدث document.onload القديم.

لقد وجدت نموذج التعليمات البرمجية التالي على javascript.info والتي يمكنك استخدامها لتغطية جميع المتصفحات:

function bindReady(handler){

    var called = false

    function ready() { 
        if (called) return
        called = true
        handler()
    }

    if ( document.addEventListener ) { // native event
        document.addEventListener( "DOMContentLoaded", ready, false )
    } else if ( document.attachEvent ) {  // IE

        try {
            var isFrame = window.frameElement != null
        } catch(e) {}

        // IE, the document is not inside a frame
        if ( document.documentElement.doScroll && !isFrame ) {
            function tryScroll(){
                if (called) return
                try {
                    document.documentElement.doScroll("left")
                    ready()
                } catch(e) {
                    setTimeout(tryScroll, 10)
                }
            }
            tryScroll()
        }

        // IE, the document is inside a frame
        document.attachEvent("onreadystatechange", function(){
            if ( document.readyState === "complete" ) {
                ready()
            }
        })
    }

    // Old browsers
    if (window.addEventListener)
        window.addEventListener('load', ready, false)
    else if (window.attachEvent)
        window.attachEvent('onload', ready)
    else {
        var fn = window.onload // very old browser, copy old onload
        window.onload = function() { // replace by new onload and call the old one
            fn && fn()
            ready()
        }
    }
}

هذا يعمل بشكل جيد:

setTimeout(MyInitFunction, 0);

يمكن أن يعمل استخدام setTimeout بشكل جيد، على الرغم من أن وقت تنفيذه يعود إلى المتصفح.إذا قمت بتمرير الصفر باعتباره المهلة، فسيقوم المتصفح بالتنفيذ عندما يتم "تسوية" الأمور.

والشيء الجيد في هذا هو أنه يمكنك الحصول على الكثير منها، ولا داعي للقلق بشأن تسلسل أحداث onLoad.

setTimeout(myFunction, 0);
setTimeout(anotherFunction, 0);
setTimeout(function(){ doSomething ...}, 0);

إلخ.

سيتم تشغيلها جميعًا عند انتهاء تحميل المستند، أو إذا قمت بإعداد واحد بعد تحميل المستند، فسيتم تشغيلها بعد انتهاء تشغيل البرنامج النصي.

لم يتم تحديد الترتيب الذي تعمل به، ويمكن أن يتغير بين المتصفحات.لذلك لا يمكنك الاعتماد عليه myFunction يتم تشغيلها من قبل anotherFunction على سبيل المثال.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top