2012-02-11 11 views
22

मैं एक DOMContentLoaded घटना के साथ एक स्क्रिप्टDOMContentLoaded या लोड ईवेंट हैंडलर के साथ Async-loaded स्क्रिप्ट्स को नहीं कहा जा रहा है?

document.addEventListener('DOMContentLoaded', function() { 
    console.log('Hi'); 
}); 

handler- कौन सा मैं asynchronously-

<script async src=script.js></script> 

हालांकि, ईवेंट हैंडलर कहा जाता है कभी नहीं है लोड हो रहा है कर रहा हूँ मिल गया है। अगर मैं इसे तुल्यकालिक रूप से लोड करता हूं-

<script src=script.js></script> 

यह ठीक काम करता है।

(यहां तक ​​कि अगर मैं एक load घटना के लिए DOMContentLoaded घटना बदलने के लिए, यह कभी नहीं कहा जाता है।)

क्या देता है? ईवेंट हैंडलर को पंजीकृत किया जाना चाहिए चाहे ब्राउजर द्वारा स्क्रिप्ट कैसे लोड की जाती है, नहीं?

संपादित: यह DOMContentLoaded साथ क्रोम 18.0.1025.11 बीटा पर काम नहीं करता है, लेकिन, यह फ़ायरफ़ॉक्स 11 बीटा पर करता है (लेकिन load साथ ऐसा नहीं होता है)। जाओ पता लगाओ।

ओएच महान भगवान और जावा के भगवान, प्रार्थना मेरे तरीके की गलती दिखाओ!

+1

स्क्रिप्ट asynchrounously लोड हो रहा करके, आप ब्राउज़र है कि यह पन्ने के अन्य हिस्सों की स्वतंत्र रूप से है कि स्क्रिप्ट लोड कर सकते हैं कह रहे हैं। इसका अर्थ यह है कि पृष्ठ लोडिंग समाप्त हो सकता है और आपकी स्क्रिप्ट लोड होने से पहले और ईवेंट के लिए रजिस्टरों से पहले डोमकंटेंट लोड हो सकता है। यदि ऐसा होता है, तो आप ईवेंट को याद करेंगे (जब आप इसके लिए पंजीकरण करते हैं तो यह पहले से ही हुआ है)। – jfriend00

+0

ओह-इंटेरेस्टस्टिंग। तो वास्तव में मुझे पहले से निकाल दिए गए कार्यक्रम के लिए परीक्षण करना चाहिए - (** ** संपादित करें: वास्तव में, क्योंकि मैं स्क्रिप्ट के बाद * घटना फायरिंग पर भरोसा करता हूं, यह बिल्कुल असीमित नहीं होना चाहिए)। ठंडा। इसे एक उत्तर के रूप में लिखें और आप एक अपवित्र हो सकते हैं :) – user1203233

उत्तर

46

स्क्रिप्ट को असीमित रूप से लोड करके, आप ब्राउज़र को बता रहे हैं कि यह पृष्ठ के अन्य हिस्सों से स्वतंत्र रूप से उस स्क्रिप्ट को लोड कर सकता है। इसका मतलब है कि पृष्ठ लोड हो सकता है और DOMContentLoaded आग लग सकता है इससे पहले कि आपकी स्क्रिप्ट लोड हो और इससे पहले कि यह ईवेंट के लिए रजिस्टर्ड हो। यदि ऐसा होता है, तो आप ईवेंट को याद करेंगे (जब आप इसके लिए पंजीकरण करते हैं तो यह पहले से ही हुआ है)।

कुछ ब्राउज़रों में, आप यह देखने के लिए दस्तावेज़ का परीक्षण कर सकते हैं कि यह पहले से लोड हो चुका है या नहीं। मैं सभी ब्राउज़र संगतता की जाँच नहीं की है, लेकिन फ़ायरफ़ॉक्स में 3.6+ (MDN doc), तो आप देख सकते हैं: अगर दस्तावेज़ पहले से ही भरी हुई है

if (document.readyState !== "loading") 

को देखने के लिए। यदि ऐसा है, तो बस अपना व्यवसाय करें। यदि ऐसा नहीं है, तो अपने ईवेंट श्रोता इंस्टॉल करें।

वास्तव में, एक संदर्भ स्रोत और कार्यान्वयन विचार के रूप में, jQuery .ready() विधि के साथ यह वही काम करता है और यह व्यापक रूप से समर्थित दिखता है। jQuery में यह कोड है जब .ready() कहा जाता है कि पहले यह जांचने के लिए जांच की जाती है कि दस्तावेज़ पहले ही लोड हो चुका है या नहीं। यदि हां, तो यह घटना श्रोता बंधन से तुरंत नहीं बल्कि तैयार फ़ंक्शन को कॉल:

// Catch cases where $(document).ready() is called after the 
// browser event has already occurred. 
if (document.readyState === "complete") { 
    // Handle it asynchronously to allow scripts the opportunity to delay ready 
    return setTimeout(jQuery.ready, 1); 
} 
+0

हां महोदय, मुझे बस इतना ही पता होना चाहिए। मैंने उपरोक्त के बारे में झूठ बोला है - पर्याप्त प्रतिनिधि नहीं मिला है;) मुझे आशा है कि कोई आपके लिए यह वोट देने के लिए पर्याप्त दयालु है :) – user1203233

+0

'document.readyState' केवल गीको-केवल है: जिस तरह से चारों ओर चल रहा है 'DOMContentLoaded' ईवेंट हैंडलर * सिंक्रनाइज़ * * जो चलने पर वैश्विक ध्वज सेट करेगा, जिसे हम बाद में जांच सकते हैं :) ** संपादित करें **: ओह प्रतीक्षा करें कि सभी अच्छे ब्राउज़र इसका समर्थन करते हैं, इसलिए हम – user1203233

+7

चीजों को आजमा रहे हैं, यह पता चला है 'document.readyState == 'full''' की जांच * पर्याप्त नहीं है * - जब चेक हो रहा था, 'document.readyState'' इंटरैक्टिव 'था। 'Document.readyState! = 'Loading' के लिए जाँच करना ठीक काम करता है :) – user1203233

17

यह अंतिम जवाब नहीं है, लेकिन मुझे समझ में क्यों एक स्क्रिप्ट डोम संशोधित करने की आवश्यकता है कि साथ async का उपयोग कर सही नहीं है बना दिया है, तो चाहिए DOMContentLoaded ईवेंट की प्रतीक्षा करें। उम्मीद फायदेमंद हो सकती है।

enter image description here

(स्रोत: Running Your Code at the Right Time from kirupa.com) इस के आसपास

2

एक तरह से खिड़की वस्तु पर लोड घटना का प्रयोग है।

यह बाद में DOMContentLoaded से होगा, लेकिन कम से कम आपको घटना को याद करने की चिंता करने की आवश्यकता नहीं है।

window.addEventListener("load", function() { 
    console.log('window loaded'); 
}); 

यदि आपको वास्तव में DOMContentLoaded ईवेंट को पकड़ने की आवश्यकता है तो आप वादा ऑब्जेक्ट का उपयोग कर सकते हैं। वादा का समाधान हो जाएगा, भले ही वह पहले हो:

HTMLDocument.prototype.ready = new Promise(function (resolve) { 
if (document.readyState != "loading") 
    return resolve(); 
else 
    document.addEventListener("DOMContentLoaded", function() { 
     return resolve(); 
    }); 
}); 

document.ready.then(function() { 
    console.log("document ready"); 
}); 
संबंधित मुद्दे