2009-11-02 11 views
11

मैं विविध पर कुछ संबंधित सामग्री शामिल कर रहा हूं। <body> टैग के अंत के पास <script> टैग जोड़कर वेब पेज, जो तब अन्य जावास्क्रिप्ट फ़ाइलों को लोड करता है। प्रवाह एक छोटे से जटिल है, इसलिए मैं अपने सवाल पूछने से पहले यह समझाने की कोशिश करेंगे:आईई को गतिशील रूप से शामिल स्क्रिप्ट को दो बार लोड करने से रोकें

  • एक ब्राउज़र <body> तत्व
  • की src विशेषता के अंत के पास हमारे <script> तत्व में कोई पृष्ठ लोड स्क्रिप्ट टैग एक जावास्क्रिप्ट फ़ाइल को इंगित करता है जो (कुछ मामलों में) एक दूसरे <script> तत्व
  • इंजेक्शन <script> तत्व की स्रोत विशेषता अभी तक एक और जावास्क्रिप्ट फ़ाइल इंगित करती है, जो अंततः पृष्ठ के उचित भाग पर कुछ सामग्री इंजेक्ट करती है।

हम अंतिम सामग्री को शामिल करने के बारे में निर्णय लेने से पहले कुछ बुनियादी प्रक्रिया करने में सक्षम होने के लिए इस दो-चरण दृष्टिकोण का उपयोग कर रहे हैं, जिसमें लोड करने में कुछ समय लग सकता है।

समस्या यह है कि IE8 (और शायद पुराने संस्करण) अंतिम जावास्क्रिप्ट को दो बार लोड करता है। ऐसा प्रतीत होता है कि src विशेषता सेट करने का कार्य एक लोड को ट्रिगर करेगा, लेकिन इसलिए स्क्रिप्ट टैग को DOM में जोड़ देगा। क्या इससे बचने का कोई तरीका है?

मैंने समस्या के bare-bones demo बनाया है। यदि आपके पास HTTP अनुरोधों का पता लगाने का कोई तरीका है, तो आप देखेंगे कि IE8 js_test2.js को दो बार लोड करता है।

उत्तर

15

जड़ अंतर यह है कि आईई एक स्क्रिप्ट तत्व पहली बार यह एक माता पिता के तत्व के childNodes में जोड़ा जाता है निष्पादित करता है, इस पर ध्यान दिए बिना कि मूल तत्व दस्तावेज़ में वास्तव में है या नहीं। अन्य ब्राउज़र केवल स्क्रिप्ट निष्पादित करते हैं जब इसे दस्तावेज़ नोड्स के दस्तावेज़ के पेड़ के अंदर नोड में जोड़ा जाता है।

jQuery के domManip समारोह (लाइन jQuery 1.3.2 के 524) है, जो append और अन्य समान jQuery तरीके से कहा जाता है, चतुर होने की कोशिश करता है और यह अंतिम पार्स HTML में पाता है किसी भी <script> तत्वों के लिए evalScript कहता है, अमल करने के लिए स्क्रिप्ट (बाहरी स्क्रिप्ट के लिए आवश्यक होने पर AJAX अनुरोध कर कर)। (वास्तविक स्क्रिप्ट तत्वों को पार्स किए गए बच्चे नोड्स से हटा दिया गया है ताकि उन्हें दस्तावेज़ में सम्मिलन पर निष्पादित करने से रोक दिया जा सके, संभवतः स्क्रिप्ट केवल तभी निष्पादित की जाती है जब उन्हें युक्त सामग्री कई तत्वों में एक साथ जोड़ दी जाती है।)

हालांकि, क्योंकि पिछले clean फ़ंक्शन, HTML को पार्स करते समय, स्क्रिप्ट तत्व को एक रैपर div में जोड़ दिया गया था, IE पहले से ही स्क्रिप्ट को निष्पादित कर लेगा। तो आपको दो निष्पादन मिलते हैं।

करने के लिए सबसे अच्छी बात यह है कि फ़ंक्शन जैसे append जैसे HTML स्क्रिप्ट्स के साथ आप स्क्रिप्ट के साथ कुछ भी कर रहे हैं।

वास्तव में, अपनी सामग्री को क्रमबद्ध HTML स्ट्रिंग में डालना भूलें और इसे पार्स करने के लिए jQuery प्राप्त करना;

var s= document.createElement('script'); 
s.type= 'text/javascript'; 
s.charset= 'UTF-8'; 
s.src= 'js_test2.js'; 
document.getElementById('some_container').appendChild(s); 

(, ईमानदारी से कहूं तो clean समारोह के पेट-मंथन स्रोत कोड को देखने के बाद, मैं jQuery के उपयोग के बारे में गंभीर संदेह आ रही हैं एचटीएमएल स्ट्रिंग आधारित: बस इसे और अधिक विश्वसनीय सादा डोम तरीके से करना । कुछ भी के लिए डोम जोड़तोड़ बिल्कुल यह ब्राउज़र कीड़े अप ठीक करने के लिए माना जाता है, लेकिन गूंगा-regex प्रसंस्करण मेरे लिए के रूप में कई समस्याओं के कारण के रूप में यह हल करती संभावना लगती है)

इस प्रारंभिक कॉल के साथ

संयोग:।

document.write(unescape("%3Cscript src='js_test1.js' type='text/javascript'%3E%3C/script%3E")); 

आपको unes की आवश्यकता नहीं है यहाँ केप; मुझे नहीं पता कि इतने सारे लोग क्यों करते हैं। अनुक्रम </ को इनलाइन स्क्रिप्ट में टालना चाहिए क्योंकि यह <script> टैग समाप्त कर देगा, और यदि आप एक्सएचटीएमएल < और & कर रहे हैं तो भी इससे बचा जाना चाहिए (या ]]> यदि आप सीडीएटीए रैपर का उपयोग कर रहे हैं), लेकिन वहां एक आसान है बस जावास्क्रिप्ट स्ट्रिंग शाब्दिक के साथ सभी कि ऐसा करने का तरीका:

document.write('\x3Cscript src="js_test1.js" type="text/javascript">\x3C/script>")); 
+0

इस बहुत संपूर्ण जवाब के लिए धन्यवाद। मैं वास्तव में अधिक पारंपरिक डोम रास्ते पर वापस आ गया है, और यह अब अच्छी तरह से काम करता है। प्रारंभिक कॉल में अनदेखा करने के बारे में: यदि मुझे सही ढंग से याद है, तो मैंने उस कोड को कॉपी किया है जिसे Google Analytics ने अपनी स्क्रिप्ट को शामिल करने के लिए उपयोग किया है, (शायद झूठी) धारणा के तहत कि अगर कोई जानता है कि रिमोट जावास्क्रिप्ट को मजबूत तरीके से कैसे शामिल किया जाए, तो यह GA लोग हैं । स्पष्टीकरण के लिए धन्यवाद। – stiang

2

ऐसा लगता है कि jquery xmlHttpRequest का उपयोग कर js_test2 का दूसरा उदाहरण ला रहा है।

मुझे क्यों पता नहीं है लेकिन JQuery का व्यवहार आपको जांच करने की आवश्यकता है।

+0

अपडेट करें यह विचित्र है, लेकिन ऐसा लगता है कि आप सही हैं। अगर मैं jQuery के संलग्न होने के बजाय appendChild का उपयोग करता हूं तो यह js_test2.js को दो बार लोड नहीं करता है। मुझे लगता है कि अगर मैंने डेमो/वास्तव में/नंगे हड्डियों (jQuery के बिना) बनाया था, तो मैं इसे स्वयं खोजता। धन्यवाद! – stiang

+0

मैंने कुछ जांच की है। परिणाम (नीचे) अच्छे नहीं हैं। – bobince

4

मैंने देखा है कि इसी तरह के परिस्थितियों में आईई के अन्य संस्करणों पर व्यवहार हो रहा है (जैसे <script> नोड्स के क्लोनिंग) और मुझे कभी नहीं पता था कि स्क्रिप्ट को दो बार निष्पादित करने से कैसे रोकें, तो मैं जो कर रहा था वह जोड़ रहा था इसके लिए स्क्रिप्ट कोड पर एक गार्ड दो बार चलाने के लिए नहीं है।

if (typeof(loaded) == 'undefined') { 
    // the whole code goes in here 
    var loaded = true; 
} 

आप स्क्रिप्ट दो बार निष्पादित करने के लिए रोकने का एक तरीका नहीं मिल रहा है, तो आप के बजाय कि दृष्टिकोण की कोशिश करना चाहते हो सकता है: यह कुछ की तरह था।

+0

भयानक, यह देखने के लिए एक तरीका खोजने का प्रयास कर रहा था कि वैश्विक चर परिभाषित किया गया था, स्क्रिप्ट चलाने से पहले इसे गलत तरीके से परिभाषित किए बिना। धन्यवाद! –

1

आप अगर एक स्क्रिप्ट दस्तावेज़ में पहले से ही है देखने के लिए जाँच कर सकते हैं लोड करने से पहले है-

function fetchscript(url, callback){ 
var S= document.getElementsByTagName('script'), L= S.length; 
while(L){ 
    if(S[--L].src== url) return true; 
} 
//create and append script and any callbacks 
} 
0

ऐसा नहीं है कि इस वजह से आप document.write का उपयोग जब आप एक <script> तत्व में पहले से ही कर रहे हैं संभव है। क्या आपने document.write के बजाय <head> में शामिल करने का प्रयास किया है?

1

मुझे एक ही समस्या मिलती है, केवल आईई में होती है।

jQuery के html() विधि चेन है: html>append>domManip>clean

clean() विधि का उपयोग करने के लिए डोम innerHTML मेकअप स्ट्रिंग, IE में innerHTML अंत में evalScript स्क्रिप्ट टैग एक बग कि script टैग तुरंत लोड होगा (पहले लोड), jQuery है domManip विधि (AJAX लोड)। फिर आईई में स्क्रिप्ट फ़ाइल लोड दो बार।

मुझे लगता है कि jQuery को इस समस्या को ठीक करना चाहिए, साफ() विधि

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