52 votes

Scripts de débogage ajoutés via la fonction getScript de jQuery

J'ai une page qui ajoute dynamiquement des références de script via jQuery $.getScript fonction. Les scripts de charger et d'exécuter fine, donc je sais que les références sont correctes. Cependant, lorsque j'ajoute un "débogueur" énoncé à l'un des scripts pour me permettre de parcourir le code dans un débogueur (tels que VS.Net, Firebug, etc.), il ne fonctionne pas. Il semble que quelque chose sur la façon jQuery charge les scripts, c'est de prévenir les débogueurs de trouver les fichiers.

Quelqu'un at-il une solution pour cela?

76voto

James Messinger Points 1265

Ok, donc il s'avère que le défaut de mise en œuvre de l' $.getScript() fonction fonctionne différemment selon que l'référencé fichier de script est sur le même domaine ou pas. Les références externes tels que:

$.getScript("http://www.someothersite.com/script.js")

sera la cause de jQuery pour créer un script externe de référence, qui peut être débogué avec pas de problèmes.

<script type="text/javascript" src="http://www.someothersite.com/script.js"></script>

Cependant, si vous faites référence à un script local de fichier telles que les suivantes:

$.getScript("http://www.mysite.com/script.js")
$.getScript("script.js")
$.getScript("/Scripts/script.js");

jQuery va télécharger le script contenu de manière asynchrone, puis l'ajouter à du contenu en ligne:

<script type="text/javascript">{your script here}</script>

Cette dernière approche ne permet pas de travailler avec tout le débogueur que j'ai testé (Visual Studio.net, Firebug, IE8 Débogueur).

La solution de contournement consiste à substituer l' $.getScript() fonction de sorte qu'il crée toujours une référence externe plutôt que du contenu en ligne. Voici le script pour le faire. J'ai testé ce dans Firefox, Opera, Safari et IE 8.

<script type="text/javascript">
// Replace the normal jQuery getScript function with one that supports
// debugging and which references the script files as external resources
// rather than inline.
jQuery.extend({
   getScript: function(url, callback) {
      var head = document.getElementsByTagName("head")[0];
      var script = document.createElement("script");
      script.src = url;

      // Handle Script loading
      {
         var done = false;

         // Attach handlers for all browsers
         script.onload = script.onreadystatechange = function(){
            if ( !done && (!this.readyState ||
                  this.readyState == "loaded" || this.readyState == "complete") ) {
               done = true;
               if (callback)
                  callback();

               // Handle memory leak in IE
               script.onload = script.onreadystatechange = null;
            }
         };
      }

      head.appendChild(script);

      // We handle everything using the script element injection
      return undefined;
   },
});
</script>

21voto

Eric Twilegar Points 130

Avec JQuery 1.6 (peut-être 1.5), vous pouvez passer à n’utiliser pas getScript, mais à utiliser jQuery.ajax (). Ensuite, définissez crossDomain: true et vous obtiendrez le même effet.

Le rappel d'erreur ne fonctionnera pas. Donc, vous pourriez aussi bien ne pas l'installer comme ci-dessous.

Cependant, je configure une minuterie et l’efface avec le succès. Donc, dites après 10 secondes si je n'entends rien, je suppose que le fichier était mauvais.

         jQuery.ajax({
            crossDomain: true,
            dataType: "script",
            url: url,
            success: function(){
                _success(_slot)
            },
            error: function(){
                _fail(_slot);
            }
        })
 

14voto

Alex Sorokoletov Points 1095

Pour ceux qui voudraient déboguer les scripts et les utiliser avec le $.quand (James Messinger réponse ne fonctionne pas bien avec $.lors de l') je vous suggérons d'utiliser ce code:

var loadScript = function (path) {
  var result = $.Deferred(),
  script = document.createElement("script");
  script.async = "async";
  script.type = "text/javascript";
  script.src = path;
  script.onload = script.onreadystatechange = function (_, isAbort) {
      if (!script.readyState || /loaded|complete/.test(script.readyState)) {
         if (isAbort)
             result.reject();
         else
            result.resolve();
    }
  };
  script.onerror = function () { result.reject(); };
  $("head")[0].appendChild(script);
  return result.promise();
};

Tous les crédits et la gloire aller à Benjamin Dumke-von der Ehe et de son article: jQuery script d'insertion et de ses conséquences pour le débogage

Cela fonctionne bien avec un $.lorsque le script est totalement visible et debuggable. Merci.

2voto

alexpts Points 21

Essaye ça,

 jQuery.extend({
getScript: function(url, callback) {
    var head = document.getElementsByTagName("head")[0];

    var ext = url.replace(/.*\.(\w+)$/, "$1");

    if(ext == 'js'){
        var script = document.createElement("script");
        script.src = url;
        script.type = 'text/javascript';
    } else if(ext == 'css'){
        var script = document.createElement("link");
        script.href = url;
        script.type = 'text/css';
        script.rel = 'stylesheet';
    } else {
        console.log("Неизветсное расширение подгружаемого скрипта");
        return false;
    }



    // Handle Script loading
    {
        var done = false;

        // Attach handlers for all browsers
        script.onload = script.onreadystatechange = function(){
            if ( !done && (!this.readyState ||
            this.readyState == "loaded" || this.readyState == "complete") ) {
                done = true;
                if (callback)
                callback();

                // Handle memory leak in IE
                script.onload = script.onreadystatechange = null;
            }
        };
    }

    head.appendChild(script);

    // We handle everything using the script element injection
    return undefined;

} 
   });
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X