Charger jQuery dans un js, puis exécuter un script qui en dépend

J’ai un problème unique –

Je conçois une application Web qui crée des widgets qu’un utilisateur peut ensuite intégrer à sa propre page (messages de blog, principalement). Je veux qu’ils aient juste à intégrer une ligne, donc je voulais que cette ligne soit une instruction include, pour retirer un Javascript de mon serveur.

Le problème est que je construis le code de widget en utilisant jQuery et que je dois charger le plug-in jQuery, car je ne sais évidemment pas si mes utilisateurs l’auront ou non. Je pensais ‘ça devrait être assez simple’ ….

function includeJavaScript(jsFile) { var script = document.createElement('script'); script.src = jsFile; script.type = 'text/javascript'; document.getElementsByTagName('head')[0].appendChild(script); } includeJavaScript('http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'); jQuery(); 

J’ajoute donc le fichier jQuery à la tête, puis essaie ensuite d’exécuter une fonction jQuery. Le problème, c’est que ça ne marche pas! Chaque fois que je l’exécute, j’obtiens l’erreur que la variable jQuery n’est pas définie. J’ai essayé quelques petites choses. J’ai essayé de placer les fonctions jQuery dans un déclencheur onLoad, afin que toute la page (y compris, probablement, le fichier jQuery) se charge avant d’appeler mon script. J’ai essayé de mettre la fonction jQuery dans un fichier séparé et de le charger après le chargement du fichier lib jQuery. Mais j’ai l’idée que je manque quelque chose de simple – jQuery n’est plus au courant, alors si je manque quelque chose d’évident, je vous présente mes excuses …

MODIFIER

OK, j’ai essayé la suggestion proposée par digitalFresh, comme suit (avec Safari 5, si cela aide), mais j’obtiens toujours la même erreur?

 function test() { jQuery() } var script = document.createElement("script"); script.type = "text/javascript"; script.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'; script.onload = test(); //execute document.body.appendChild(script); 

MODIFIER

OK, finalement, je l’ai fait fonctionner, sur une suggestion désinvolte de Brendan, en plaçant l’appel ITSELF dans un gestionnaire ‘onload’, comme ceci:

 function addLoadEvent(func) { var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = func; } else { window.onload = function() { if (oldonload) { oldonload(); } func(); } } } addLoadEvent( function() { var script = document.createElement("script"); script.type = "text/javascript"; script.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'; document.body.appendChild(script); jQuery(); }); 

Comme vous pouvez le constater, à ce stade, je n’ai même pas besoin de le mettre dans une “surcharge” – cela fonctionne. Bien que je dois l’admettre, je ne comprends toujours pas POURQUOI cela fonctionne, ce qui me dérange …

Vous devez d’abord vérifier que jQuery n’est pas déjà utilisé, par exemple:

 if (jQuery) { // jQuery is loaded } else { // jQuery is not loaded } 

Deuxièmement, vous devez vous assurer que vous utilisez jQuery en mode sans conflit et que vous n’utilisez pas l’opérateur $, car il pourrait être revendiqué par une autre bibliothèque de scripts.

Ensuite, pour intégrer, déclarez cette fonction:

 function load_script (url) { var xmlhttp; try { // Mozilla / Safari / IE7 xmlhttp = new XMLHttpRequest(); } catch (e) { //Other IE xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } xmlhttp.open('GET', url, false); x.send(''); eval(xmlhttp.responseText); var s = xmlhttp.responseText.split(/\n/); var r = /^function\s*([a-z_]+)/i; for (var i = 0; i < s.length; i++) { var m = r.exec(s[i]); if (m != null) window[m[1]] = eval(m[1]); } } 

Alors appelez ça:

 load_script('http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'); 

J'espère que cela t'aides.

La solution que vous utilisez en fin de compte fonctionne avec un temps de démarrage lent et non à 100% . Si quelqu’un réécrit window.onload, votre code ne s’exécutera pas. Window.onload se produit également lorsque tout le contenu de la page est chargé (y compris les images), ce qui n’est pas exactement ce que vous voulez. Vous ne voulez pas que votre script attende aussi longtemps.

Heureusement, les éléments , qui peut être utilisé pour coupler d'autres scripts avec eux.

 function include(file, callback) { var head = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); script.type = 'text/javascript'; script.src = file; script.onload = script.onreadystatechange = function() { // execute dependent code if (callback) callback(); // prevent memory leak in IE head.removeChild(script); script.onload = null; }; head.appendChild(script); } include('http://ajax.googleapis.com/.../jquery.min.js', myFunction); 

Dans ce cas, la fonction sera appelée exactement quand jquery sera disponible. Votre code est infaillible et démarre rapidement.

Le script n’est ni chargé ni exécuté lorsque vous appelez la fonction jQuery. C’est pourquoi vous obtenez l’erreur que jQuery n’est pas défini.

J’ai répondu à ce problème sur Chargement de scripts dynamicment . Le script est simple pour tous les navigateurs sauf IE. Ajoutez simplement un écouteur d’événement onload

Utilisez LABjs . Les balises incorporées fonctionnent car le navigateur charge et exécute le script qu’il contient ou qu’il référence lorsqu’il en voit un, mais cela signifie également que le navigateur bloquera jusqu’à ce que le script soit terminé.

Si vous utilisez jQuery, vous pouvez utiliser getScript () . Facebook a un bon exemple d’utilisation . C’est une solution plus facile à gérer que celle que j’ai publiée ci-dessous.

Alternativement:

En vous basant sur la réponse de galambalazs, vous pouvez include() sa fonction include() dans un événement tel que jQuery $(document).ready() pour créer des scripts différés avec une ligne de dépendance sans avoir à recourir à un plugin JS supplémentaire. J’ai également ajouté une callbackOnError, ce qui est pratique si vous effectuez une récupération depuis Google CDN.

 /* galambalazs's include() */ function include(file, callback, callbackOnError) { var head = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); script.type = 'text/javascript'; script.src = file; script.onload = script.onreadystatechange = function() { // execute dependent code if (callback) callback(); // prevent memory leak in IE head.removeChild(script); script.onload = null; script.onerror = null; }; script.onerror = function() { if(callbackOnError) callbackOnError(); // prevent memory leak in IE head.removeChild(script); script.onload = null; script.onerror = null; }; head.appendChild(script); } /* If you need a deferred inline script, this will work */ function init() { // Insert Code } /* Example with callback */ $(document).ready(function() { include('something.js', init); }); /* Maybe I want something on window.load() */ $(window).load(function() { // Without a callback include('whatever.js'); }); /* Or use an event to load and initialize script when it's needed */ $(".nearAButton").hover(include('button.js',function() {initButtonJS()})); function initButtonJS() { $(".nearAButton").off("mouseenter mouseleave"); } /* Attempt to load Google Code, on fail load local */ include( '//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js', function () { // Inline Callback }, function () { include('/local/jquery-ui-1.10.3.custom.min.js', function () { // Inline Callback }); } );