webentwicklung-frage-antwort-db.com.de

Überprüfen Sie, ob das externe Skript geladen ist

Ich erstelle ein Jquery-Plugin und möchte, dass ein externes Skript geladen wird. Dies ist für eine interne Web-App und ich kann den Skriptnamen/-ort konsistent halten (mysscript.js). Dies ist auch ein Ajaxy-Plugin, das auf der Seite oft aufgerufen werden kann. 

Wenn ich feststellen kann, dass das Skript nicht geladen ist, lade ich es mit:

jQuery.getScript()

Wie kann ich überprüfen, ob das Skript geladen ist, weil ich nicht möchte, dass dasselbe Skript mehrmals auf der Seite geladen wird? Ist es etwas, um das ich mich wegen des Zwischenspeichens des Skripts nicht sorgen muss?

Aktualisieren: Ich habe möglicherweise keine Kontrolle darüber, wer dieses Plugin in unserer Organisation verwendet, und kann möglicherweise nicht erzwingen, dass sich das Skript nicht bereits mit oder ohne spezifische ID auf der Seite befindet. Der Skriptname wird jedoch immer an derselben Stelle angezeigt mit dem gleichen Namen Ich hoffe, ich kann den Namen des Skripts verwenden, um zu überprüfen, ob es tatsächlich geladen ist.

50

Wenn das Skript Variablen oder Funktionen im globalen Bereich erstellt, können Sie deren Vorhandensein überprüfen:

Externe JS (im globalen Bereich) -

var myCustomFlag = true;

Und um zu überprüfen, ob dies gelaufen ist:

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

Aktualisieren

Sie können das Vorhandensein des betreffenden <script>-Tags überprüfen, indem Sie alle <script>-Elemente auswählen und deren src-Attribute überprüfen:

//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>');
}

Oder Sie können diese .filter()-Funktionalität einfach im Selector backen:

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

Dies war jetzt sehr einfach, da mir klar geworden ist, wie ich das mache, dank all der Antworten, die mich zur Lösung geführt haben. Ich musste $ .getScript () aufgeben, um die Quelle des Skripts anzugeben ... manchmal ist es am besten, Dinge manuell zu erledigen. 

Lösung

//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

Erstellen Sie das Skript-Tag mit einer bestimmten ID und prüfen Sie, ob diese ID vorhanden ist.

Alternativ können Sie Skript-Tags durchlaufen und nach dem Skript 'src' suchen. Stellen Sie sicher, dass diese nicht bereits mit dem gleichen Wert geladen sind wie der, den Sie vermeiden möchten.

Edit: folgendes Feedback, dass ein Codebeispiel nützlich wäre:

(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?
    }
})();

Wie in den Kommentaren ( https://stackoverflow.com/users/1358777/alwin-kesler ) erwähnt, kann dies eine Alternative sein (nicht im Benchmark):

(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

Dieser Thread befindet sich im oberen Bereich der SO - Jquery-Tags FAQ und bietet eine Vielzahl von Methoden zum Überprüfen vorhandener Skripts

Der beste Weg, um Googles gehostete jQuery zu verwenden, aber meine gehostete Bibliothek bei Google zurückgreifen -

Viel Feedback zu verschiedenen Methoden

3
charlietfl

Die Antwort von @ jasper ist absolut richtig, aber bei modernen Browsern könnte eine Standard-Javascript-Lösung Folgendes sein:

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

Eine andere Möglichkeit, um zu prüfen, ob ein externes Skript geladen ist oder nicht, können Sie die Funktion data von jquery verwenden und ein Validierungsflag speichern. Beispiel als:

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

Mehrere Antworten von oben zu einer benutzerfreundlichen Funktion zusammenfügen 

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

Einige zu viele Antworten auf diese Frage, aber ich denke, es lohnt sich, diese Lösung hinzuzufügen. Es kombiniert einige unterschiedliche Antworten.

Wichtige Punkte für mich waren

  • fügen Sie ein #id-Tag hinzu, damit es leicht zu finden und nicht zu duplizieren ist
  • Verwenden Sie .onload (), um zu warten, bis das Skript vollständig geladen ist, bevor Sie es verwenden

    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

Ich denke, es ist besser, window.addEventListener ('error') zu verwenden, um den Skriptladefehler zu erfassen und zu versuchen, ihn erneut zu laden. Dies ist nützlich, wenn Skripts von einem CDN-Server geladen werden. Wenn wir kein Skript vom CDN laden können, können wir es von unserem Server laden.

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

Einfach prüfen, ob die globale Variable verfügbar ist , falls nicht erneut prüfen . Um zu verhindern, dass der maximale Callstack überschritten wird setzen Sie ein 100ms Timeout in der Prüfung 

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