2010-05-10 17 views
6

मैं पृष्ठ लोड के बाद कुछ तत्वों को गतिशील रूप से <script> टैग जोड़ रहा हूं। मैं समझता हूं कि स्क्रिप्ट्स को असीमित रूप से लोड किया जाता है, लेकिन क्या मैं उन्हें उनके द्वारा जोड़े गए क्रम में पार्स करने की उम्मीद कर सकता हूं?गतिशील स्क्रिप्ट अतिरिक्त आदेश दिया जाना चाहिए?

मैं फ़ायरफ़ॉक्स में अपेक्षित व्यवहार देख रहा हूं, लेकिन सफारी या क्रोम में नहीं। Chrome डेवलपर टूल और Firebug में दस्तावेज़ को देखते हुए, दोनों निम्नलिखित दिखाने -

<html> 
    <head> 
    ... 
    <script type="text/javascript" src="A.js"></script> 
    <script type="text/javascript" src="B.js"></script> 
    </head> 
    ... 
</html> 

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

क्या मुझे निर्दिष्ट क्रम में फ़ाइलों को पार्स करने के लिए क्रोम/सफारी की अपेक्षा करनी चाहिए? ओएस एक्स पर क्रोम 5.0.375.29 बीटा का प्रयोग 10.6.3

संपादित करें (10/5/10): जब मैं पार्स कहते हैं, मेरा मतलब है पर अमल - आक्रामक पार्स करने के अनेक लाभ देख सकते हैं - THX rikh

संपादित करें (11/5/10): ठीक है, इसलिए मैंने नीचे juandopazo द्वारा इसके साथ एक परीक्षण रखा। हालांकि मैं जावास्क्रिप्ट के साथ सीधे सिर पर स्क्रिप्ट तत्व जोड़ना

  1. सहित चीजों का एक संयोजन, जोड़ लिया है। (टेस्ट ए -> डी)
  2. jquery की append() विधि का उपयोग कर सिर पर स्क्रिप्ट तत्व जोड़ना। (टेस्ट ई -> एच)
  3. jquery's getScript() विधि के साथ स्क्रिप्ट लोड हो रहा है। (टेस्ट मैं -> एल)

मैं भी 'async' और 'आस्थगित करें' स्क्रिप्ट टैग पर विशेषताओं के सभी संयोजन की कोशिश की।

आप यहाँ परीक्षण का उपयोग कर सकते - http://dyn-script-load.appspot.com/, और स्रोत देखें देखने के लिए कि यह कैसे काम करता है। लोड की गई स्क्रिप्ट बस अपडेट() फ़ंक्शन को कॉल करती हैं।

नोट करने के लिए पहली बात यह है, कि केवल 1 और 3 तरीकों से ऊपर समानांतर में संचालित है - 2 अनुरोध क्रमिक रूप से निष्पादित करता है।

चित्र 1 - - आप यहाँ इस का ग्राफ देख सकते हैं अनुरोध जीवनचक्र का ग्राफ़
Request lifecycle Graph http://dyn-script-load.appspot.com/images/dynScriptGraph.png

यह भी दिलचस्प है कि jQuery संलग्न() दृष्टिकोण भी ब्लॉक getScript() कहता है - आप में से कोई भी देख सकते हैं जब तक सभी संलग्न() कॉल पूर्ण नहीं होते हैं, तब तक निष्पादित होते हैं, और फिर वे सभी समानांतर में चलते हैं। इस पर अंतिम नोट यह है कि jQuery एपेंड() विधि निष्पादित होने के बाद दस्तावेज़ शीर्ष से स्क्रिप्ट टैग को स्पष्ट रूप से हटा देती है। केवल पहली विधि दस्तावेज़ में स्क्रिप्ट टैग छोड़ देती है।

क्रोम परिणाम

परिणाम है कि क्रोम हमेशा की तरह, वापस जाने के लिए परीक्षण की परवाह किए बिना पहले स्क्रिप्ट निष्पादित करता है। इसका मतलब है कि jQuery एपेंड() विधि को छोड़कर सभी परीक्षण 'असफल' हैं।

छवि 2 - क्रोम 5.0.375।29 बीटा परिणाम
Chrome Results http://dyn-script-load.appspot.com/images/chromeDynScript.png

फ़ायरफ़ॉक्स परिणाम

फ़ायरफ़ॉक्स, हालांकि, ऐसा लगता है कि अगर पहली विधि का इस्तेमाल किया जाता है, और async गलत है (यानी सेट नहीं), तो स्क्रिप्ट मज़बूती में निष्पादित करेंगे आदेश।

छवि 3 - एफएफ 3.6.3 परिणाम
FF Results http://dyn-script-load.appspot.com/images/ffDynScript.png

ध्यान दें कि सफारी क्रोम के रूप में एक ही तरीके से, जो समझ में आता है में विभिन्न परिणाम देने के लिए लगता है।

इसके अलावा, मेरे पास केवल धीमी स्क्रिप्ट पर 500 मिलीमीटर देरी है, केवल शुरुआत-> समय समाप्त करने के लिए। क्रोम और सफारी सबकुछ पर असफल होने के लिए आपको दो बार रीफ्रेश करना पड़ सकता है।

ऐसा लगता है कि ऐसा करने के तरीके के बिना, हम समानांतर में डेटा पुनर्प्राप्त करने की क्षमता का लाभ नहीं उठा रहे हैं, और ऐसा कोई कारण नहीं है कि हमें (फ़ायरफ़ॉक्स शो के रूप में) क्यों नहीं करना चाहिए।

+0

मैं क्रोम मुद्दों में एक बग के रूप में इस उठाया गया है रजिस्टर - - http://code.google.com/p/chromium/issues/detail मोटे तौर पर, यहाँ कुछ कोड से पता चलता है कि हम क्या किया है? आईडी = 4610 9 – hawkett

उत्तर

2

मेरे अपने प्रश्न का उत्तर देने के लिए खेद है, लेकिन यह थोड़ी देर हो गया है और हम समाधान के साथ आए हैं। हम जो भी साथ आए थे, वह जावास्क्रिप्ट को एक जेसन ऑब्जेक्ट में निहित टेक्स्ट के रूप में लोड करना था, और उसके बाद eval() का उपयोग किया गया था जब वे सभी सही क्रम में निष्पादित करने के लिए लोड हो गए थे। समवर्ती लोड प्लस निष्पादन का आदेश दिया। आपके उपयोग के मामले के आधार पर आपको जेसन की आवश्यकता नहीं हो सकती है।

// 'requests' is an array of url's to javascript resources 
var loadCounter = requests.length; 
var results = {}; 

for(var i = 0; i < requests.length; i++) { 
    $.getJSON(requests[i], function(result) { 
     results[result.id] = result; 
     ... 
     if(--loadCounter == 0) finish(); 
    }); 
} 

function finish() { 
    // This is not ordered - modify the algorithm to reflect the order you want 
    for(var resultId in results) eval(results[resultId].jsString); 
} 
0

जैसा कि मैं इसे समझता हूं, वे को दस्तावेज़ में दिखाई देने के क्रम में निष्पादित करने के लिए हैं। कुछ ब्राउज़र ऑर्डर के बाहर कुछ पार्सिंग करने में सक्षम हो सकते हैं, लेकिन उन्हें अभी भी सही क्रम में निष्पादित करना होगा।

+0

यह मेरी समझ भी थी। – hawkett

0

नहीं, आप उम्मीद नहीं कर सकते कि सभी ब्राउज़र लोड होने तक दोनों स्क्रिप्ट के निष्पादन को रोक देंगे (** विशेष रूप से जब आप उन्हें गतिशील रूप से जोड़ रहे हों)।

के बाद ही A.js भरी हुई है आप B.js में कोड निष्पादित करने के लिए चाहते हैं, तो आपका सर्वश्रेष्ठ दांव A.js कि एक चर और देखने के लिए अगर उस चर स्थापित किया गया है की जाँच करता है कि B.js के लिए एक और एक सेट के लिए एक onload कॉलबैक जोड़ने के लिए है, तो है यह B.js में आवश्यक फ़ंक्शन निष्पादित करता है यदि (और A.js लोड नहीं हुआ है, तो यह एक टाइमर शुरू करता है जो समय-समय पर लोड होने तक जांचता है)।

0

डाउनलोड ऑर्डर और निष्पादन आदेश एक ही चीज़ नहीं है। आपके पृष्ठ में, भले ही बीजे पहले डाउनलोड हो जाएं, ब्राउज़र का इंजन पृष्ठ को संसाधित करना जारी रखने के लिए एजे की प्रतीक्षा करेगा।

स्क्रिप्ट निश्चित रूप से संसाधित होते हैं, न केवल दस्तावेज़ में दिखाई देने के क्रम में, बल्कि उस स्थान पर भी दिखाई देते थे।

कल्पना कीजिए कि अगर ऐसा नहीं होगा, तो jQuery की लाइब्रेरी से पहले आपकी छोटी स्क्रिप्ट डाउनलोड और संसाधित की जाती है, तो कई त्रुटियां होंगी।

इसके अलावा, जब आप किसी जेएस फ़ाइल में "document.write" करते हैं, तो ऐसा लगता है कि स्क्रिप्ट को घोषित किया गया है। आप स्क्रिप्ट घोषणा के बाद दिखाई देने वाले DOM ऑब्जेक्ट्स तक नहीं पहुंच सकते हैं।

यही कारण है कि पृष्ठ के बहुत नीचे स्क्रिप्ट डालने की सिफारिशें हैं, ताकि वे जल्द ही निष्पादन को रोक सकें और पृष्ठ के "कथित भार समय" को कम कर सकें, क्योंकि ब्राउजर का प्रतिपादन इंजन जल्द ही बंद हो जाता है लिपि संसाधित है।

माइक

संपादित करें: यदि वे जावास्क्रिप्ट के साथ गतिशील रूप से जोड़ा जाता है, मुझे लगता है कि वे क्रम में वे कुछ ही समय में जोड़ा गया था में कार्रवाई की जाती है।

+0

ग्रेट यही वह है जो मैं उम्मीद कर रहा था - इसलिए यदि मैं स्क्रिप्ट को देख रहा हूं * नहीं * ऑर्डर में निष्पादित किया गया है कि वे दस्तावेज़ में दिखाई देते हैं (जो वह क्रम भी है जिसमें उन्हें समय में जोड़ा गया था), तो यह एक बग होगा वेबकिट में? मुझे चार चीजें मिल रही हैं जो मुझे चल रही हैं (1) सही क्रम में स्क्रिप्ट दिखाते हुए डीओएम की वास्तविक संरचना (2) देव स्क्रिप्ट में संसाधन लोड दृश्य पहली स्क्रिप्ट को पहली बार प्राप्त किया जा रहा है (3) कंसोल लॉग स्क्रिप्ट को जोड़ने के क्रम में दिखा रहा है (समय में), और (4) कंसोल लॉग दूसरी स्क्रिप्ट को पहले – hawkett

+0

निष्पादित किया जा रहा है, शायद एजे की आखिरी पंक्ति में, बीजे को शामिल करने के लिए एक लाइन डालें एक "document.write"? –

+0

मुख्य लक्ष्य स्क्रिप्ट को समानांतर में लोड करना है, लेकिन वे जोड़े गए क्रम में निष्पादित करें। यह फ़ायरफ़ॉक्स में काम करता है, लेकिन क्रोम/सफारी में नहीं। मैं सभी ब्राउज़रों में सही निष्पादन आदेश की गारंटी के लिए परीक्षण में दूसरे दृष्टिकोण का उपयोग कर सकता हूं (मुख्य पोस्ट में संपादित देखें), लेकिन यह समवर्ती नहीं है। मैं सोच रहा हूं कि धारावाहिक लोडिंग (और इस प्रकार निष्पादन) प्राप्त करने के लिए आपके सुझाए गए दृष्टिकोण को लेने के बजाय, मैं jQuery.append() के साथ जाऊंगा, क्योंकि स्क्रिप्ट में स्वयं को कोई अतिरिक्त कोड की आवश्यकता नहीं है। उस ने कहा, मेरे पास सीरियल लोड अभी काम कर रहा है - मैं प्रदर्शन - चीयर्स को बेहतर बनाने के लिए एक समवर्ती लोड समाधान की तलाश में हूं। – hawkett

0

आप b.jsa.js से 100% सुनिश्चित करने के लिए लोड कर सकता है ... हालांकि मैं इस सवाल अपने आप से निश्चित जवाब चाहते हैं, विशेष रूप से लिपियों के सिंक ajax लोड हो रहा है के साथ।

+0

यह निश्चित रूप से काम करता है - मैं स्क्रिप्ट को एक साथ लोड करने के प्रदर्शन लाभ प्राप्त करने के लिए ऐसा करने से दूर जाने की प्रक्रिया में हूं :) – hawkett

0

मैं छोटी पुस्तकालय पर काम करते समय इसकी जांच कर रहा था जो यूयूआई 3 की गतिशील रूप से मॉड्यूल लोड करता है। मैंने यहां एक छोटा परीक्षण बनाया है जो दो स्क्रिप्ट लोड करता है जो सिर्फ divs में सामग्री डालता है। एक एक सामान्य जेएस फ़ाइल है और दूसरा एक PHP फ़ाइल है जो निष्पादित करने के लिए 3 सेकंड प्रतीक्षा करती है।

http://www.juandopazo.com.ar/tests/asyn-script-test.html

आप देख सकते हैं, स्क्रिप्ट क्रियान्वित कर रहे हैं जब वे लोड होने, और जिस क्रम में आप उन्हें डोम को संलग्न, हर ब्राउज़र में में नहीं।

+0

मैंने परीक्षण के लिए डोम संरचना पर एक नज़र डाली, और कुछ चीजों को नोट किया - सबसे पहले स्क्रिप्ट सिर के बजाए शरीर में होती हैं, और दूसरी लिपि पहले सूचीबद्ध होती है - इसलिए यदि ऑर्डरिंग को सम्मानित किया गया था, तो आप स्क्रिप्ट 2 को पहले अच्छे परीक्षण निष्पादित करने की उम्मीद करेंगे, हालांकि स्क्रिप्ट टैग के परिणाम देखने के लिए अच्छा होगा क्रम में। टा – hawkett

+0

दाएं। क्षमा करें, मैं उन्हें सिर में रखना भूल गया। वे गलत क्रम में थे क्योंकि मैंने appildChe() के बजाय insertBefore() का उपयोग किया था। मैंने इसे बदल दिया और नतीजा वही है। आपको कुछ प्रकार की कतार लिखने की तलाश करनी चाहिए। वैश्विक ऑब्जेक्ट से विधियों को कॉल करने वाली विभिन्न फ़ाइलों में मॉड्यूल के लिए पूछें। YUI3 कैसे काम करता है इस पर एक नज़र डालें। अपने कोड के साथ स्क्रिप्ट आमतौर पर लगता है कि:। YUI() का उपयोग ('module1', 'module2', समारोह (वाई) { // कुछ करना}); और प्रत्येक मॉड्यूल शुरू होता है: वाईयूआई()।जोड़ें ('मॉड्यूल 1', फ़ंक्शन (वाई) { // अपनी सामग्री वाई } में जोड़ें;); – juandopazo

+0

इसके लिए धन्यवाद - मुझे खेद है चिह्नित करने के लिए पर्याप्त प्रतिष्ठा नहीं है। बस काम करने की कोशिश कर रहा हूं कि मैं अपने परिदृश्य में अपेक्षित फ़ायरफ़ॉक्स क्यों व्यवहार कर रहा हूं, लेकिन आपके अंदर नहीं। ऐसा लगता है कि मैंने शायद अपनी स्थिति को गलत तरीके से पढ़ा है। – hawkett

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