2009-04-16 6 views
20

J'ai un bookmarklet qui charge jQuery et d'autres bibliothèques js.Bookmarklet attend jusqu'à ce que Javascript soit chargé

Comment puis-je:

  • Attendez que la bibliothèque javascript j'utilise est disponible/chargé. Si j'essaie d'utiliser le script avant qu'il ait fini de charger, comme utiliser la fonction $ avec jQuery avant qu'il ne soit chargé, une exception non définie est levée.
  • assurer que le bookmarklet je charge ne sera pas mis en mémoire cache (sans l'aide d'un en-tête de serveur, ou évidemment, étant que c'est un fichier javascript: un metatag)

qui le sait si onload pour dynamiquement javascript ajouté fonctionne dans IE? (Pour contredire cela post)

Quelle est la solution la plus simple, la résolution la plus propre à ces problèmes?

+0

"Attendez que la bibliothèque javascript soit disponible". Qu'est-ce que tu attends? –

Répondre

24

Cela dépend de la manière dont vous chargez réellement jQuery. Si vous ajoutez un élément de script à la page, vous pouvez utiliser la même technique que jQuery pour charger dynamiquement un script.

EDIT: J'ai fait mes devoirs et j'ai extrait une fonction loadScript du code jQuery pour l'utiliser dans votre bookmarklet. Il pourrait effectivement être utile à beaucoup (y compris moi).

function loadScript(url, callback) 
{ 
    var head = document.getElementsByTagName("head")[0]; 
    var script = document.createElement("script"); 
    script.src = url; 

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

      // Continue your code 
      callback(); 

      // Handle memory leak in IE 
      script.onload = script.onreadystatechange = null; 
      head.removeChild(script); 
     } 
    }; 

    head.appendChild(script); 
} 


// Usage: 
// This code loads jQuery and executes some code when jQuery is loaded 
loadScript("https://code.jquery.com/jquery-latest.js", function() 
{ 
    $('my_element').hide(); 
}); 
+2

oeuvre d'art :) – vsync

+1

vous n'avez pas besoin de spécifier type = "text/javascript" ? – vsync

+1

plus maintenant. De nos jours, les navigateurs supposent que les scripts non typés sont javascript – joeytwiddle

1

Pour répondre à votre première question: Javascript est interprété séquentiellement, donc tout code bookmarklet suivant ne s'exécutera pas tant que la bibliothèque n'est pas chargée (en supposant que la bibliothèque a été correctement interprétée - pas d'erreurs de syntaxe).

Pour empêcher les fichiers d'être mis en cache, vous pouvez ajouter une chaîne de requête vide de sens ...

url = 'jquery.js?x=' + new Date().getTime(); 
+0

Apparemment, le javascript ajouté dynamiquement ne fonctionne pas exactement comme vous le décrivez. L'élément est ajouté par la fonction DOM addElement et renvoie immédiatement. OnLoad aide, mais je suis dérangé par ce post: http://answers.google.com/answers/threadview?id=595949 – cgp

+0

Votre commentaire n'est pas précis, surtout quand il s'agit de cette question. altCognito a décrit le problème, permettez-moi de le rendre un peu plus clair. Si votre script ajoute dynamiquement une balise de script, le contenu de la balise dynamique ne sera pas analysé tant que vous n'aurez pas quitté la balise de script actuelle –

0

Je suis un peu plus avec this, mais pas complètement. Ce serait bien d'avoir un exemple discret de bookmarklet qui montre comment éviter la mise en cache.

1

J'ai remarqué que dans Chrome, l'ordre des scripts chargés est indéterminé, en utilisant la technique de @Vincent Robert. Dans ce cas, une petite modification aide:


(function() { 
    var callback = function() { 
     // Do you work 
    }; 
     // check for our library existence 
    if (typeof (MyLib) == 'undefined') { 
     var sources = [ 
       'http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js', 
      'https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js', 
      'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js', 
      'http://myhost.com/javascripts/mylib.min.js']; 

     var loadNextScript = function() { 
      if (sources.length > 0) { 
       var script = document.createElement('script'); 
       script.src = sources.shift(); 
       document.body.appendChild(script); 

       var done = false; 
       script.onload = script.onreadystatechange = function() { 
        if (!done 
          && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete")) { 
         done = true; 

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

         loadNextScript(); 
        } 
       } 
      } else { 
       callback(); 
      } 
     } 
     loadNextScript(); 

    } else { 
     callback(); 
    } 
})(); 
Questions connexes