Script asynchrone Chargement en rappel

Http://jsfiddle.net/JamesKyle/HQDu6/

J'ai créé une petite fonction basée sur Mathias Bynens Optimisation du script asynchrone Google Analytics qui se déroule comme suit:

function async(src) { var d = document, t = 'script', o = d.createElement(t), s = d.getElementsByTagName(t)[0]; o.src = '//' + src; s.parentNode.insertBefore(o, s); } 

Cela fonctionne très bien et j'ai déjà commencé à l'utiliser pour plusieurs scripts différents

 // Crazy Egg async('dnn506yrbagrg.cloudfront.net/pages/scripts/XXXXX/XXXXX.js?' + Math.floor(new Date().getTime() / 3600000)); // User Voice var uvOptions = {}; async('widget.uservoice.com/XXXXX.js'); // Google Analytics var _gaq = [['_setAccount', 'UA-XXXXX-XX'], ['_setDomainName', 'coachup.com'], ['_trackPageview']]; async('google-analytics.com/ga.js'); // Stripe async('js.stripe.com/v1');​ 

Le problème vient quand je rencontre un script qui doit être appelé après son chargement:

 // Snap Engage async('snapabug.appspot.com/snapabug.js'); SnapABug.init('XXXXX-XXXXX-XXXXX-XXXXX-XXXXX'); 

Donc, j'ai pensé que je convertirais cela en une fonction de rappel qui serait utilisée comme suit:

 async('snapabug.appspot.com/snapabug.js', function() { SnapABug.init('XXXXX-XXXXX-XXXXX-XXXXX-XXXXX'); }); 

Je ne m'attendais pas à ce que ce soit difficile pour moi, mais il s'est avéré être ainsi.

Ma question est de savoir quel est le moyen le plus efficace d'ajouter un rappel sans trop compliquer le code.

Voir le jsfiddle: http://jsfiddle.net/JamesKyle/HQDu6/

Merci RASG pour https://stackoverflow.com/a/3211647/982924

Fonction asynchrone avec rappel:

 function async(u, c) { var d = document, t = 'script', o = d.createElement(t), s = d.getElementsByTagName(t)[0]; o.src = '//' + u; if (c) { o.addEventListener('load', function (e) { c(null, e); }, false); } s.parentNode.insertBefore(o, s); } 

Usage:

 async('snapabug.appspot.com/snapabug.js', function() { SnapABug.init('XXXXX-XXXXX-XXXXX-XXXXX-XXXXX'); }); 

JsFiddle

La réponse de James Kyle ne prend pas en compte IE9. Voici une version modifiée du code que j'ai trouvé dans le lien proposé dans les commentaires . Modifiez la base de données var afin qu'elle puisse trouver le script en conséquence.

 //for requiring a script loaded asynchronously. function loadAsync(src, callback, relative){ var baseUrl = "/csbasement/resources/script/"; var script = document.createElement('script'); if(relative === true){ script.src = baseUrl + src; }else{ script.src = src; } if(callback !== null){ if (script.readyState) { // IE, incl. IE9 script.onreadystatechange = function() { if (script.readyState == "loaded" || script.readyState == "complete") { script.onreadystatechange = null; callback(); } }; } else { script.onload = function() { // Other browsers callback(); }; } } document.getElementsByTagName('head')[0].appendChild(script); } 

utilisation:

 loadAsync('https://www.gstatic.com/charts/loader.js' , function(){ chart.loadCharts(); }); // OR relative path loadAsync('fastclick.js', null, true);