2011-08-04 17 views
10

मैं स्क्रिप्ट पूरी तरह से लोड होने के बाद कुछ करने की कोशिश कर रहा हूं। (IE8)गतिशील रूप से स्क्रिप्ट बनाना: readyState कभी भी "पूर्ण"

स्क्रिप्ट मैं परीक्षण के लिए उपयोग: http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js
और अवैध एक: http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.minaaaaaaaa.js

कोड ...

var script = create the element and append to head... 

// this works fine with FF/Chrome/... 
script.onload = function() {alert('script loading complete');} 
script.onerror = function() {alert('error loading script');} 

// and for IE 
script.onreadystatechange = function() { 
    // this will alert 1.loading 2.loaded 
    alert(this.readyState); 

    // this never works 
    if(this.readyState == 'complete') {alert('script loading complete');} 

    // this works with either a valid or INVALID url 
    else if(this.readyState == 'loaded') {alert('script loaded');} 
}; 

मेरे मामले में, कभी नहीं "पूर्ण" पता चलता है, "लोड" दिखाता है भले ही एक यूआरएल अमान्य है। तो यह बताने का कोई तरीका नहीं है कि आईई के तहत एक स्क्रिप्ट को सीधे लोड किया गया है या नहीं।

क्या मैं कुछ गलत कर रहा हूं? मैं पूरी स्थिति कैसे प्राप्त नहीं करूं?

अद्यतन

ठीक है, मैं तो बस कुछ लेख पढ़ सकते हैं और ऐसा लगता है कि readyState स्क्रिप्ट लोड हो रहा है पता लगाने के लिए एक विश्वसनीय तरीका नहीं है।

तो ऐसा करने का एक और तरीका है? jQuery के बिना, लेकिन शुद्ध जावास्क्रिप्ट।

+0

मुझे यकीन नहीं है कि आप क्या करना चाहते हैं, लेकिन मैं स्क्रिप्ट को गतिशील रूप से लोड करने के तरीके के बारे में 'jQuery # getScript' में देखने का सुझाव देता हूं। सबसे महत्वपूर्ण बात यह है कि, AJAX पैटर्न का उपयोग करने से आपको HTTP त्रुटियों के लिए परीक्षण करने की सुविधा मिलती है जैसा आपको लगता है। यह नहीं कर सकता - afaik - 'स्क्रिप्ट' टैग पर DOM 'ईवेंट' का उपयोग करके पूरा किया जा सकता है। – FK82

+0

इनपुट के लिए धन्यवाद, एफके 82। मैं बस 100% सुनिश्चित करना चाहता हूं कि लिपि लोड हो गई है। जैसा कि मैंने कहा, एफएफ/क्रोम में, अधिभार और आतंक पूरी तरह से काम करता है। लेकिन आईई के तहत, भले ही एक स्क्रिप्ट यूआरएल अमान्य है (या शायद समय समाप्त हो), तैयार स्टार्ट अभी भी लोड हो जाता है। कारण मैं शुद्ध जावास्क्रिप्ट का उपयोग करना चाहता हूं क्योंकि मैं यह सुनिश्चित करना चाहता हूं कि jQuery पहले सीडीएन से सही ढंग से लोड हो, और फिर सामान करने के लिए jQuery का उपयोग करें। और हाँ, मुझे यह भी लगता है कि यह AJAX तरीके से जाना चाहिए। (कोशिश नहीं की है) – pepsi600

+0

कृपया मेरे उत्तर पर एक नज़र डालें। आप AJAX/XHR ('XMLHttpRequest') पैटर्न का उपयोग करके विभिन्न HTTP त्रुटियों को पकड़ने में सक्षम होंगे। साथ ही, मेरा मानना ​​है कि क्रॉस-ब्राउज़र संगतता के मामले में यह अधिक स्थिर होगा। – FK82

उत्तर

5

अपनी टिप्पणी के अनुसार, यहां कैसे गतिशील रूप का उपयोग करते हुए एक स्क्रिप्ट टैग को जोड़ने के लिए की एक योजनाबद्ध है एक्सएचआर (XMLHttpRequest):

var handleRequest = function() { //!! set up the handleRequest callback 

    if(this.status != undefined) { 

     /* do something with the status code here */ 

    } 

    if(this.readyState == 4) { 

      var script = document.createElement("script") ; 
       script.setAttribute("type","text/javascript") ; 
      var text = document.createTextNode(this.responseText) ; 
       script.appendChild(text) ; 

      var head = document.getElementsByTagName("head")[0] ; 
       head.insertBefore(script,head.firstChild) ; 

    } 

} ; 

var request ; //!! supposing you have a way to get a working XHR Object 

//.. set the XHR Object 

request.open("GET",url,true) ; 
request.overrideMimeType("text/javascript") ; 
request.onreadystatechange = handleRequest ; 
request.send(null) ; 

कृपया ध्यान रखें कि यह आपके मैं क्या मतलब है की एक विचार देने के लिए ही है । एक कामकाजी उदाहरण को jQuery स्रोत कोड से अधिक विस्तृत निर्णय लेना होगा।


लिंक:

+0

आपके समाधान चट्टानों, लेकिन 100% होने के लिए इसे सीओआरएस हैंडलिंग के साथ बढ़ाया जाना चाहिए ताकि यह आपके डोमेन के बाहर स्क्रिप्ट भी लोड कर सके, अन्यथा जो स्क्रिप्ट आप लोड कर सकते हैं वे उसी मूल नीति तक सीमित हैं :) – rupps

+0

धन्यवाद। (: आप सही हैं जहां तक ​​सीओआरएस कार्यान्वयन को क्रॉस-ब्राउजर का समर्थन किया जाता है। क्रॉस डोमेन स्क्रिप्ट एक्सेस के लिए फॉलबैक एससीआरआईपीटी टैग का उपयोग कर रहा है। – FK82

-1

का पता लगा रहा लोड समापन

[..] एक वेब पेज कुछ ईवेंट हैंडलर्स जब लोड पूरा हो गया है कि कहा जाएगा की स्थापना का सुझाव दिया। हम ऐसा पिछले कोड में निम्न पंक्तियां जोड़कर:

var head= document.getElementsByTagName('head')[0]; 
var script= document.createElement('script'); 
script.type= 'text/javascript'; 
script.onreadystatechange= function() { 
    if (this.readyState == 'complete') helper(); 
} 
script.onload= helper; 
script.src= 'helper.js'; 
head.appendChild(script); 

यहाँ हम नव निर्मित स्क्रिप्ट टैग पर दो अलग-अलग ईवेंट हैंडलर्स की स्थापना की। ब्राउज़र के आधार पर, स्क्रिप्ट समाप्त होने पर इन दो हैंडलरों में से एक या अन्य को कॉल किया जाना चाहिए। पहले से ही हैंडलर केवल आईई पर काम करता है। ऑनलोड हैंडलर गेको ब्राउज़र और ओपेरा पर काम करता है।

"this.readyState == 'पूर्ण'" परीक्षण वास्तव में पूरी तरह से काम नहीं करता है। readyState सैद्धांतिक रूप से राज्यों की एक श्रृंखला के माध्यम से चला जाता है:

  • 0 अप्रारंभीकृत
  • 1 लोड हो रहा है
  • 2 लोड
  • 3 इंटरैक्टिव
  • 4 पूरा

लेकिन वास्तव में, राज्य छोड़ दिया जा सकता है। आईई 7 के साथ अपने अनुभव में, आपको या तो एक लोड की गई घटना या एक पूर्ण घटना मिलती है, लेकिन दोनों नहीं।

यह कैश से लोड हो रहा है या नहीं, इसके साथ कुछ करने के लिए हो सकता है लेकिन अन्य कारक हैं जो आपको प्राप्त करने वाली घटनाओं को प्रभावित करते हैं। कभी-कभी मुझे लोडिंग या इंटरैक्टिव इवेंट भी मिलते हैं, और कभी-कभी मैं नहीं करता हूं। यह संभव है कि परीक्षण "this.readyState == 'loaded' || this.readyState == 'पूर्ण' होना चाहिए, लेकिन यह जोखिम दो बार ट्रिगर हो रहा है।

http://unixpapa.com/js/dyna.html

अद्यतन

कृपया आप इस के साथ अपने script.onreadystatechange कॉलबैक sobstitute कर सकते हैं:

newjs.onreadystatechange = function() { 
    if (newjs.readyState === 'loaded' || newjs.readyState === 'complete') { 
     newjs.onreadystatechange = null; 
     alert('script is complete or loaded."); 
    } 

};

मैंने देखा है कि एक और चीज यह है कि आप == ऑपरेटर के साथ स्ट्रिंग तुलना कर रहे हैं। यह भ्रामक हो सकता है। इसके बजाय === का उपयोग करें।

+0

चलो ........ क्या आपने बस कॉपी और पेस्ट किया था?आपको मेरा वही कोड मिला है (मेरा मतलब संरचना है), और यही वह है जिसके बारे में मैं बात कर रहा हूं ... "readyState" कभी "पूर्ण" नहीं है !!! और मैं इसे समझने की कोशिश कर रहा हूं। – pepsi600

+0

ऐसा लगता है कि लोड करने या पूर्ण होने के बारे में जानने का कोई तरीका नहीं है। जावास्क्रिप्ट पैटर्न "मांग पर लोड हो रहा है" देखो। लेखक ने यह लिखा: • आईई में आप तैयारस्टेटेड ईवेंट की सदस्यता लेते हैं और एक तैयार स्टेट "लोड" या "पूर्ण" की तलाश करते हैं। अन्य सभी ब्राउज़र इसे अनदेखा करेंगे। – user278064

+1

वह कह रहा है कि भार निकाल दिया गया है, लेकिन जब स्क्रिप्ट अमान्य है और विफल रहता है (404, आदि) तब भी यह आग लगती है। वह जानना चाहता है कि इसका पता कैसे लगाया जाए। –

10

मुझे आईई 7 और आईई 8 में स्क्रिप्ट नोड 'पूर्ण' बनाने के लिए एक चाल मिली है। और स्क्रिप्ट लोड करते समय त्रुटि वास्तव में तब होती है जब पता लगाने के लिए (node.onerror केवल IE9 + में काम कर रहा है)। हैक

  1. नए बनाए गए तत्व को डीओएम (एक बार में) डालने में नहीं है।
  2. नोड.चिल्डेरेन संपत्ति को कॉल करना और इसके बाद नोड.ऑनरेस्टस्टेट संपत्ति की जांच करना। अगर संपत्ति 'पूर्ण' में बदल जाती है - आपने स्क्रिप्ट लोड की है, तो यह 'लोडिंग' में बदल जाती है - यह निश्चित स्क्रिप्ट लोडिंग त्रुटि के लिए है।

इसे आज़माएं!

var node = document.createElement('script'); 
node.src = 'some-[un]existing-url.js'; 
node.type = 'text/javscript'; 

node.onreadystatechange = (function(node) { 
    return function() { 
     if (/loaded|complete/.test(node.readyState)) { 
      _finish(); 
     } 
    }; 
})(node); 

var _finish=function() { 

     if (node.readyState == 'complete') { 
      // insert node only after completing the request, though this is not necessary 
      var head = document.head; 
      head || (head = document.getElementsByTagName('head')[0]); 
      head.appendChild(node); 
      // call success function 
      _success(); 
      return; 
     } 

     var firstState = node.readyState; 

     // hack: calling 'children' property changes node's readyState from 'loaded' to complete 
     // (if script was loaded normally) or to 'loading' - if error detected 
     node.children; 

     // error detected 
     if (firstState == 'loaded' && node.readyState == 'loading') { 
      // custom error code 
      _error(); 
     } 
} 
+0

यह ** ** ** स्क्रिप्ट इंजेक्शन के लिए ** का सबसे अच्छा समाधान है IE8 ** सफलता और त्रुटि हैंडलर के साथ। यह बहुत बेहतर है कि स्क्रिप्ट को AJAX के माध्यम से लोड करना क्योंकि स्क्रिप्ट इंजेक्शन द्वारा ** AJAX CORS सीमा लागू नहीं होती ** ** 'node.children' चाल के साथ बढ़िया खोज! बीटीडब्ल्यू। 'var node = createNode ( 'स्क्रिप्ट', '... निश्चित रूप से सादा वेनिला जावास्क्रिप्ट ' var node = document.createElement ('script');' ... – Semmel

+0

मुझे यकीन नहीं है कि node.onerror IE9 में काम कर रहा है। – f1lt3r

+0

बहुत अच्छा, धन्यवाद! –

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