web-dev-qa-db-fra.com

Vérifier que le script externe est chargé

Je crée un plugin jQuery et je veux vérifier qu'un script externe est chargé. Ceci est pour une application Web interne et je peux garder le nom/l'emplacement du script cohérent (mysscript.js). C'est aussi un plugin ajaxy qui peut être appelé plusieurs fois sur la page. 

Si je peux vérifier que le script n'est pas chargé, je le chargerai en utilisant:

jQuery.getScript()

Comment vérifier que le script est chargé car je ne veux pas que le même script soit chargé plusieurs fois sur la page? Est-ce une chose dont je ne devrais pas avoir à m'inquiéter à cause de la mise en cache du script?

Mettre à jour:  Je ne contrôle peut-être pas qui utilise ce plugin dans notre organisation et je ne suis peut-être pas en mesure de faire en sorte que le script ne soit pas déjà sur la page avec ou sans identifiant spécifique, mais le nom du script sera toujours au même endroit. avec le même nom. J'espère pouvoir utiliser le nom du script pour vérifier qu'il est réellement chargé.

50
AGoodDisplayName

Si le script crée des variables ou des fonctions dans l'espace global, vous pouvez vérifier leur existence:

JS externe (à portée globale) -

var myCustomFlag = true;

Et pour vérifier si cela a fonctionné:

if (typeof window.myCustomFlag == 'undefined') {
    //the flag was not found, so the code has not run
    $.getScript('<external JS>');
}

Mettre à jour

Vous pouvez vérifier l'existence de la balise <script> en question en sélectionnant tous les éléments <script> et en vérifiant leurs attributs src:

//get the number of `<script>` elements that have the correct `src` attribute
var len = $('script').filter(function () {
    return ($(this).attr('src') == '<external JS>');
}).length;

//if there are no scripts that match, the load it
if (len === 0) {
    $.getScript('<external JS>');
}

Ou vous pouvez simplement intégrer cette fonctionnalité .filter() directement dans le sélecteur:

var len = $('script[src="<external JS>"]').length;
117
Jasper

C’était très simple, maintenant que je réalisais comment le faire, grâce à toutes les réponses qui m’avaient conduit à la solution. J'ai dû abandonner $ .getScript () afin de spécifier la source du script ... Parfois, il est préférable de faire les choses manuellement. 

Solution

//great suggestion @Jasper
var len = $('script[src*="Javascript/MyScript.js"]').length; 

if (len === 0) {
        alert('script not loaded');

        loadScript('Javascript/MyScript.js');

        if ($('script[src*="Javascript/MyScript.js"]').length === 0) {
            alert('still not loaded');
        }
        else {
            alert('loaded now');
        }
    }
    else {
        alert('script loaded');
    }


function loadScript(scriptLocationAndName) {
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = scriptLocationAndName;
    head.appendChild(script);
}
8
AGoodDisplayName

Créez la balise de script avec un ID spécifique, puis vérifiez si cet ID existe?

Sinon, parcourez les balises de script en recherchant le script 'src' et assurez-vous qu'elles ne sont pas déjà chargées avec la même valeur que celle que vous souhaitez éviter?

Edit: suite à des commentaires qu'un exemple de code serait utile:

(function(){
    var desiredSource = 'https://sitename.com/js/script.js';
    var scripts       = document.getElementsByTagName('script');
    var alreadyLoaded = false;

    if(scripts.length){
        for(var scriptIndex in scripts) {
            if(!alreadyLoaded && desiredSource === scripts[scriptIndex].src) {
                alreadyLoaded = true;
            }
        }
    }
    if(!alreadyLoaded){
        // Run your code in this block?
    }
})();

Comme mentionné dans les commentaires ( https://stackoverflow.com/users/1358777/alwin-kesler ), il peut s'agir d'une solution de rechange (non référencée):

(function(){
    var desiredSource = 'https://sitename.com/js/script.js';
    var alreadyLoaded = false;

    for(var scriptIndex in document.scripts) {
        if(!alreadyLoaded && desiredSource === scripts[scriptIndex].src) {
            alreadyLoaded = true;
        }
    }
    if(!alreadyLoaded){
        // Run your code in this block?
    }
})();
4
MyStream

Ce fil est en haut des balises SO jQuery FAQ et propose une grande variété de méthodes pour vérifier le script existant.

Meilleure façon d'utiliser le jQuery hébergé de Google, mais de revenir à ma bibliothèque hébergée lorsque Google échoue

Beaucoup de retours sur différentes méthodes

3
charlietfl

La réponse de @ jasper est tout à fait correcte, mais avec les navigateurs modernes, une solution Javascript standard pourrait être:

function isScriptLoaded(src)
{
    return document.querySelector('script[src="' + src + '"]') ? true : false;
}
3
abhiweb

Pour vérifier si un script externe est chargé ou non, vous pouvez utiliser data function de jQuery et stocker un indicateur de validation. Exemple en tant que:

if(!$("body").data("google-map"))
    {
        console.log("no js");

        $.getScript("https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=initilize",function(){
            $("body").data("google-map",true);

            },function(){
                alert("error while loading script");
            });
        }
    }
    else
    {
        console.log("js already loaded");
    }
2
Sunil Sharma

Fusion de plusieurs réponses précédentes en une fonction facile à utiliser 

function GetScriptIfNotLoaded(scriptLocationAndName)
{
  var len = $('script[src*="' + scriptLocationAndName +'"]').length;

  //script already loaded!
  if (len > 0)
      return;

  var head = document.getElementsByTagName('head')[0];
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = scriptLocationAndName;
  head.appendChild(script);
}
1
Aaron Sherman

Peu de réponses à ce sujet, mais j'estime qu'il vaut la peine d'ajouter cette solution. Il combine plusieurs réponses différentes.

Les points clés pour moi étaient

  • ajoutez une balise #id, il est donc facile à trouver et non dupliqué
  • Utilisez .onload () pour attendre la fin du chargement du script avant de l'utiliser.

    mounted() {
      // First check if the script already exists on the dom
      // by searching for an id
      let id = 'googleMaps'
      if(document.getElementById(id) === null) {
        let script = document.createElement('script')
        script.setAttribute('src', 'https://maps.googleapis.com/maps/api/js?key=' + apiKey)
        script.setAttribute('id', id)
        document.body.appendChild(script) 
    
        // now wait for it to load...
        script.onload = () => {
            // script has loaded, you can now use it safely
            alert('thank me later')
            // ... do something with the newly loaded script
        }      
      }
    }
    
0
comfytoday

Je pense qu'il est préférable d'utiliser window.addEventListener ('error') pour capturer l'erreur de chargement du script et essayer de le charger à nouveau . C'est utile lorsque nous chargeons des scripts à partir d'un serveur CDN Si nous ne pouvons pas charger le script à partir du CDN, nous pouvons le charger à partir de notre serveur.

window.addEventListener('error', function(e) {
  if (e.target.nodeName === 'SCRIPT') {
    var scriptTag = document.createElement('script');
    scriptTag.src = e.target.src.replace('https://static.cdn.com/', '/our-server/static/');
    document.head.appendChild(scriptTag);
  }
}, true);
0
Duke

Tout simplement vérifiez si la variable globale est disponible, sinon vérifiez à nouveau. Afin de empêcher le dépassement du nombre maximal d'appels, définissez un délai de 100 ms timeout sur le contrôle: 

function check_script_loaded(glob_var) {
    if(typeof(glob_var) !== 'undefined') {
    // do your thing
    } else {
    setTimeout(function() {
    check_script_loaded(glob_var)
    }, 100)
    }
}
0
Cybernetic