2009-12-18 14 views
25

प्रारंभिक पृष्ठ लोड की अवधि को कम करने के लिए मैं गतिशील स्क्रिप्ट लोडिंग का उपयोग करता हूं। यह सुनिश्चित करने के लिए कि एक स्क्रिप्ट द्वारा परिभाषित कार्य और वस्तुएं सुलभ हैं, मुझे यह सुनिश्चित करने की आवश्यकता है कि स्क्रिप्ट पूरी तरह से लोड हो गई है।क्या script.ready गतिशील स्क्रिप्ट लोडिंग के अंत का पता लगाने के लिए विश्वसनीय हो सकता है?

मैंने इस अंत में my own Javascript library विकसित किया है, और इस प्रकार इस विषय पर काफी सारे शोध किए हैं, यह अध्ययन करते हुए कि विभिन्न पुस्तकालयों में यह कैसे किया जाता है। इस मुद्दे से संबंधित एक चर्चा के दौरान, केली सिम्पसन, LABjs के लेखक, ने कहा कि:

LABjs (और कई अन्य लोडर) सेट दोनों "ऑनलोड" और "onreadystatechange" सभी स्क्रिप्ट तत्वों पर, यह जानकर कि कुछ ब्राउज़रों एक सक्रिय होगा, और कुछ अन्य सक्रिय कर देगा ...

आप the current version of jQuery as of this writing, v1.3.2 में इस का एक उदाहरण देख सकते हैं:

// Attach handlers for all browsers 
script.onload = script.onreadystatechange = function(){ 
    if (!done && (!this.readyState || 
    this.readyState == "loaded" || this.readyState == "complete")) { 
     done = true; 
     success(); 
     complete(); 

     // Handle memory leak in IE 
     script.onload = script.onreadystatechange = null; 
     head.removeChild(script); 
    } 
}; 

यह कला की स्थिति है, लेकिन ओपेरा 9.64 में एक अजीब व्यवहार के विश्लेषण के दौरान, मैं इस निष्कर्ष पर पहुंचा कि, इस तकनीक का उपयोग करके, ऑनलोड कॉलबैक बहुत जल्दी निकाल दिया गया।

मैं इस प्रश्न के उत्तर में अपने स्वयं के निष्कर्ष पोस्ट करूंगा, और समुदाय से और सबूत और प्रतिक्रिया इकट्ठा करना चाहता हूं।

+0

कोई भी jQuery 1.x-master शाखा में वर्तमान कोड का पता लगाता है? ऐसा लगता है कि उन्होंने '.onreadystatechange' और '.onload' का उपयोग करके छोड़ दिया है और उन्हें वादे के साथ बदल दिया है? [क्लिकी] (https://github.com/jquery/jquery/blob/1.x-master/src/ajax.js) – Campbeln

उत्तर

7

ओपेरा में, script.readyState संपत्ति पर भरोसा नहीं किया जा सकता है। उदाहरण के लिए, ओपेरा 9.64 में स्क्रिप्ट चलाने से पहले तैयार लोड "लोड" निकाल दिया जा सकता है।

मैंने ओपेरा 9 में the same test प्रदर्शन किया।64 और ओपेरा 10, विभिन्न परिणामों के साथ।

ओपेरा 9.64 में, पहले से ही एक बार पहले और एक बार स्क्रिप्ट चलाने के बाद, पहले से ही हैंडलर को दो बार निकाल दिया जाता है। readyState संपत्ति "लोडेड" दोनों ही मामलों में है, जिसका अर्थ है कि यह मान स्क्रिप्ट लोड हो रहा है के अंत का पता लगाने के भरोसा नहीं किया जा सकता है:

# Fri Dec 18 2009 17:54:43 GMT+0100 
# Opera/9.64 (Windows NT 5.1; U; en) Presto/2.1.1 
Test for script.readyState behavior started 
Added script with onreadystatechange handler 
readystatechange: loaded 
test1.js: Start 
test1.js: Start of closure 
test1.js: End of closure 
readystatechange: loaded 

ओपेरा 10 में, onreadystatechange हैंडलर अभी भी दो बार मूल्य के साथ निकाल दिया जाता " लोड ", लेकिन स्क्रिप्ट के बाद दोनों बार भाग गया:

# Fri Dec 18 2009 18:09:58 GMT+0100 
# Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.10 
Test for script.readyState behavior started 
Added script with onreadystatechange handler 
test1.js: Start 
test1.js: Start of closure 
test1.js: End of closure 
readystatechange: loaded 
readystatechange: loaded 

ये अलग-अलग व्यवहार संकेत मिलता है कि onreadystatechange ओपेरा में एक स्क्रिप्ट लोड हो रहा है के अंत का पता लगाने के लिए एक विश्वसनीय तरीका नहीं है। चूंकि ओपेरा ऑनलोड श्रोता का भी समर्थन करता है, इसके बजाए इस अन्य तंत्र का उपयोग किया जाना चाहिए।

इन परीक्षणों के परिणामों के आधार पर, पहले से ही एक्सचेंज का उपयोग केवल इंटरनेट एक्सप्लोरर में स्क्रिप्ट लोडिंग के अंत का पता लगाने के लिए किया जाना चाहिए, और इसे अन्य ब्राउज़रों में सेट नहीं किया जाना चाहिए।

+0

कम से कम, आप पहली घटना को अनदेखा कर सकते हैं। –

+2

@ जस्टिन जॉनसन जो अजीब लगता है, क्या आप "लोड" घटनाओं को गिनेंगे, लेकिन सिर्फ ओपेरा में? –

3

फ़ायरफ़ॉक्स, सफारी और क्रोम में, पहले से ही हैंडलर नेवर को पहले से ही कहा जाता है।

मैं एक छोटी परीक्षण का मामला बनाया केवल onreadystatechange हैंडलर सेट के साथ एक गतिशील स्क्रिप्ट बनाने,:,

<script type="text/javascript" language="javascript"> 
bezen.log.info(new Date(),true); 
bezen.log.info(navigator.userAgent,true); 

// Activate logs 
bezen.log.on(); 
bezen.log.info('Test for script.readyState behavior started'); 

var script = document.createElement('script'); 
script.src = 'test1.js'; 
script.onreadystatechange = function(){ 
    bezen.log.info('readystatechange: '+script.readyState); 
}; 
document.body.appendChild(script); 
bezen.log.info('Added script with onreadystatechange handler'); 
</script> 

मैं फ़ायरफ़ॉक्स 2, Firefox 3, Firefox 3.5, सफ़ारी 3 में एक स्थानीय फ़ाइल पर परीक्षण किया

Fri Dec 18 2009 17:53:58 GMT+0100 
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 
Test for script.readyState behavior started 
Added script with onreadystatechange handler 
test1.js: Start 
test1.js: Start of closure 
test1.js: End of closure 

onreadystatechange कभी नहीं कहा जाता हो जाता है: Safari 4 और क्रोम 3, और इसी तरह के परिणाम (यहां लॉग एफएफ 3.5 में दर्ज की गई) मिला है। इन ब्राउज़रों में, केवल स्लोड लोडिंग के अंत का पता लगाने के लिए केवल अधिभार श्रोता उपयोगी होता है, ऑनवर्स्टस्टेन्चेंज की आवश्यकता नहीं होती है।

1

इंटरनेट एक्सप्लोरर में, स्क्रिप्ट के अंत के बाद, पहले से ही हैंडलर की अपेक्षा की जाती है।

Fri Dec 18 18:14:51 UTC+0100 2009 
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729) 
Test for script.readyState behavior started 
Added script with onreadystatechange handler 
test1.js: Start 
test1.js: Start of closure 
test1.js: End of closure 
readystatechange: complete 

एक साथ, यहाँ:

मैं same test इंटरनेट एक्सप्लोरर 6, Internet Explorer 7 और Internet Explorer 8 में इन तीन ब्राउज़रों में इसी तरह के परिणाम के साथ (यहाँ लॉग एक्सप्लोरर 6 इंटरनेट में दर्ज की गई) का प्रदर्शन किया, स्थानीय फ़ाइल का उपयोग करके परीक्षण करें, तैयारस्टेट हमेशा "पूर्ण" होता है, और यह कई पेज रीफ्रेश के बाद भी वही था।

हालांकि, जैसा कि this post by Nicholas C. Zakas में उल्लेख किया गया है, आप विभिन्न परिस्थितियों में "लोड" और "पूर्ण" या बस "लोड" भी देख सकते हैं।

1

मुझे पता चला है कि इंटरनेट एक्सप्लोरर (9 में परीक्षण) हमेशा तैयार होने पर आपकी स्क्रिप्ट तैयार नहीं होती हैस्टेट === 'लोड'। मुझे इस घटना हैंडलर का उपयोग करके सफलता मिली है (9 बजे में) पर निष्क्रिय करें। पहले मेरे बालों को खींच रहा था।

0

क्रोम में इसी तरह के परिणाम।

onready नहीं ले करता है ...

बस ऑनलोड और onerror।

संबंधित मुद्दे