2010-08-19 5 views
4

aujourd'hui J'ai travaillé sur le chargement dynamique de code javascript (fichiers). La solution que je l'utilise est:Charger dynamiquement des fichiers Javascript et charger des événements d'achèvement

function loadScript(scriptUrl) { 
     var head = document.getElementsByTagName("head")[0]; 
     var script = document.createElement('script'); 
     script.id = 'uploadScript'; 
     script.type = 'text/javascript'; 
     script.src = scriptUrl; 
     head.appendChild(script); 
    } 

le problème est que je ne sais pas comment assurez-vous que lorsque le contenu du script sont exécutées. Puisque le script contient des classes (bien classes JS), j'ai noté une fonction qui est appelée via setTimeout et vérifie si ces objets sont définis. Ce n'est pas flexible car ce n'est pas automatique. Alors? Existe-t-il des moyens de charger ces scripts et d'avoir une notification fiable quand ils ont été exécutés?

+1

Dupicate de http://stackoverflow.com/questions/3125897/loading-scripts-dynamicically/3125918 # 3125918 – tcooc

+1

Pourquoi ne pas regarder une solution existante comme LabJS? http://labjs.com/ – Pointy

+0

aucune infraction, mais cela pue d'une mauvaise décision de conception. – Fosco

Répondre

2

Le moyen le plus simple pour une bibliothèque JS est de faire un XMLHttpRequest et eval() le retour. Votre "onload" serait quand les données sont retournées, et "oninit" serait juste après que vous avez évalué.

EDIT: Si vous voulez séquencer ceci, vous pouvez créer un AssetLoader qui prend un tableau de scripts et n'évaluera pas() un script jusqu'à ce que le précédent ait été récupéré et initialisé.

EDIT 2: Vous pouvez également utiliser les commandes script.onload dans la publication référencée dans les commentaires. La méthode eval présente un léger avantage en ce sens que vous pouvez séparer et contrôler les portions de chargement et d'exécution de l'importation de script.

EDIT 3: Voici un exemple. Considérons un fichier appelé foo.js qui contient les éléments suivants:


function foo() { 
    alert('bar'); 
} 
 

Ensuite, exécutez la commande suivante d'une autre page dans votre navigateur:



function initScript (scriptString) { 
    window.eval(scriptString); 
} 

function getScript (url, loadCallback, initCallback, callbackScope) { 

    var req = new XMLHttpRequest(); 
    req.open('GET', url); 

    req.onreadystatechange = function (e) { 

     if (req.readyState == 4) { 
      if (loadCallback) loadCallback.apply(callbackScope); 
      initScript.call(null, req.responseText); 
      if (initCallback) initCallback.apply(callbackScope); 
     } 

    } 

    req.send(); 

} 

function fooScriptLoaded() { 
    alert('script loaded'); 
} 

function fooScriptInitialized() { 
    alert('script initialized'); 
    foo(); 
} 

window.onload = function() { 
    getScript('foo.js', fooScriptLoaded, fooScriptInitialized, null); 
} 

Vous verrez les alertes « script chargé », « Script initialisé ", et" barre ". Évidemment, l'implémentation de XMLHttpRequest n'est pas complète ici et il y a toutes sortes de choses que vous pouvez faire pour la portée dans laquelle vous voulez exécuter le script, mais c'est le cœur de celui-ci.

+0

Oui, mais comment savoir qu'un script a été initialisé ??? – gotch4

+0

Après eval() le script a été initialisé. Vous pouvez lancer un bloc try-catch pour voir si des erreurs empêchent l'initialisation du script. – sevenflow

+0

J'ai mis en place un edit avec le code d'exemple – sevenflow

3

Vous pouvez utiliser le getScript de jquery et passer une fonction de rappel.

Voir: jquery.

+0

eh ... malheureusement cela doit charger jQuery lui-même uhuhuhu – gotch4

+1

+1. De cette façon, vous pouvez prendre en charge les dépendances et les charger dans l'ordre en imbriquant les appels getScript dans les fonctions de rappel. – Fosco

+0

Vous pouvez consulter le code source jQuery, il peut être facilement mis en œuvre en utilisant JavaScript, voir: http: //gist.github.com/538106 – tszming

-2

Vous pouvez utiliser une variable compteur, et une sorte de rappel:

var scriptsToLoad = 10; 
var loadedScripts = 0; 
//... 
function increaseLoadCount() { 
loadedScripts++; 
if(loadedScripts == scriptsToLoad) { 
alert("start here"); 
} 
} 

//script1-10.js 
increaseLoadCount(); 

Peut-être un peu plus agréable que d'un délai d'attente ..

Questions connexes