2010-06-26 20 views
5

Sto caricando alcuni script YUI dinamicamente nel mio codice in risposta a una richiesta Ajax. Il DOM e la pagina sono completamente caricati quando viene effettuata la richiesta: è una risposta per un evento utente.Caricamento dinamico degli script

Aggiungo il tag alla testa, da bambini. Ma mi sono imbattuto in alcuni problemi:

Aggiungo due script YUI ospitati su Yahoo! CDN e uno script in linea del mio responsabile per la creazione di oggetti, l'aggiunta di listener di eventi e il rendering dei widget YUI. Ma io quando il mio script esegue gli script YUI non sono ancora stati caricati e mi danno errori e non funzionano come mi aspetto.

C'è un modo per eseguire il mio script (o definire una funzione da eseguire) quando gli script YUI sono completamente caricati?

risposta

1

È possibile utilizzare un setTimeout() per eseguire una certa funzione che solo controlla se è caricato - controllare qualcosa come

if (typeof YUI_NAMESPACED_THING !== "undefined") runCode()

EDIT Grazie, CMS

+2

Il 'typeof' operatore * sempre * restituisce una stringa, il controllo dovrebbe essere' if (typeof YUI_NAMESPACED_THING! = "Undefined") // ... ' – CMS

+2

Questo è il male strada da percorrere. In primo luogo, probabilmente stai pensando a setInterval oa un setTimeout concatenato, poiché un singolo setTimeout può A) ritardare l'esecuzione troppo a lungo causando un tempo di configurazione della pagina inutilmente scarso, oppure B) fallire la condizione di competizione creata assumendo che gli script vengano caricati all'interno di un certo tempo Qualcosa basato sulla soluzione onload/onreadystatechange è migliore. – Luke

+0

@Luke Stavo pensando a setTimeout incatenato. Ma sì, sono d'accordo sul fatto che onload/onreadystatechange è una soluzione migliore. Sapevo che onload non funzionava da solo e non sapevo che ci fosse una soluzione cross browser in quel vicolo. Ho upvoted la risposta di digitalFresh –

18

Hai provato un evento onload?

Modificato: (grazie Jamie)

var script = document.createElement("script"); 
script.type = "text/javascript"; 
script.src = src; 
//IE: 
if(window.attachEvent && document.all) { 
    script.onreadystatechange = function() { 
     if(this.readyState === "complete") { 
      callback_function(); //execute 
     } 
    }; 
} 
//other browsers: 
else { 
    script.onload = callback_function; //execute 
} 
document.getElementsByTagName("head")[0].appendChild(script); 
+3

Sebbene possa funzionare in alcuni browser, gli elementi 'script' non sono richiesti per avere un gestore di eventi onLoad, per quanto ne so - http://www.w3schools.com/tags/tag_script.asp –

+2

Tutti i browser ad eccezione di IE hanno un evento 'onload' (prevedibile in genere). In IE, hai bisogno di una funzione di fallback 'onreadystatechange'. – tcooc

+0

+1 - Non avevo sentito parlare di "onreadystatechange". Buono a sapersi –

2

Se stai usando YUI 2.x Mi consiglia di utilizzare l'utilità YUI Get, come è stato studiato per gestire questo tipo di problema.

2

Se si caricano più file di script singoli da Yahoo! CDN, è necessario assicurarsi che entrambi siano caricati prima di eseguire il codice dipendente. Puoi evitarlo usando il gestore combo. Vedi il Configuratore per ottenere quello che dovrebbe essere l'url dello script per caricare entrambi/tutti i file YUI necessari da un url.

http://developer.yahoo.com/yui/articles/hosting/

Con questo in mente, assumendo è necessario caricare i file in modo asincrono YUI, è necessario utilizzare un/gestore onreadystatechange onload come notato da digitalFresh.

mi sento di raccomandare il seguente schema, però:

(function (d) { 
    var s = d.createElement('script'), 
     onEvent = ('onreadystatechange' in s) ? 'onreadystatechange' : 'onload'; 

    s[onEvent] = function() { 
     if (("loaded,complete").indexOf(this.readyState || "loaded") > -1) { 
      s[onEvent] = null; 

      // Call your code here 
      YAHOO.util.Dom.get('x').innerHTML = "Loaded"; 
     } 
    }; 

    // Set the src to the combo script url, e.g. 
    s.src = "http://yui.yahooapis.com/combo?2.8.1/..."; 

    d.getElementsByTagName('head')[0].appendChild(s); 
})(document); 
0

Se ho capito bene, la risposta Ajax con questo:

<script href="yui-combo?1"></script> 
<script href="yui-combo?2"></script> 
<p>some text here</a> 
<script> 
// using some of the components included in the previous combos 
// YAHOO.whatever here... 
</script> 

Se questo è il caso, questo è un chiaro caso in cui è necessario utilizzare il plug-in del dispatcher. Il Dispatcher emula il processo di caricamento del browser per le risposte AJAX. Fondamentalmente caricherà ed eseguirà ogni script nell'ordine esatto.

migliori saluti, Caridy

Problemi correlati