23 Stimmen

Wie kann ich überprüfen, ob eine JS-Datei bereits eingebunden wurde?

Ich habe mein JavaScript in verschiedene Dateien aufgeteilt. Ich möchte verhindern, dass JavaScript-Dateien zweimal geladen werden. Wie kann ich das machen?

29voto

cwallenpoole Punkte 75701

Hier ist ein Test, um zu sehen, ob ein Skript aufgrund des Pfads zur js-Datei eingeschlossen wurde:

function isScriptAlreadyIncluded(src){
    var scripts = document.getElementsByTagName("script");
    for(var i = 0; i < scripts.length; i++) 
       if(scripts[i].getAttribute('src') == src) return true;
    return false;
}

Es funktioniert für alle Skripte, die nicht über AJAX geladen wurden, obwohl Sie es möglicherweise ändern möchten, wenn Sie JSONP-Code ausführen.

5voto

Ivan Chaer Punkte 6814

Manchmal wurde die js-Datei auf andere Weise geladen (zum Beispiel über js).

Dann kann window.performance nützlich sein. Anstatt wie in anderen Antworten unter den script-Tags zu überprüfen, können wir unter den geladenen Ressourcen prüfen mit:

let resources = performance.getEntries()
    .filter(e => e.entryType === 'resource')
    .map(e => e.name);
if (resources.indexOf("//domain.com/path/to/script.js") === -1) {
    // Skript wurde noch nicht geladen.
}

Die Browser-Kompatibilität von window.performance ist heutzutage nicht schlecht: https://caniuse.com/mdn-api_performance_getentries

Wenn wir sowohl die script-Tags überprüfen möchten (für alle Skript-Tags im DOM bis zu diesem Zeitpunkt, einschließlich URLs von Skripts, die möglicherweise noch nicht geladen wurden) als auch die window.resources (für alle bis zu diesem Zeitpunkt geladenen Skripte, einschließlich der über js geladenen), könnten wir es in einer Funktion zusammenfassen:

function is_script_already_included(src){
  const found_in_resources = performance.getEntries()
      .filter(e => e.entryType === 'resource')
      .map(e => e.name)
      .indexOf(src) !== -1;
  const found_in_script_tags = document.querySelectorAll(`script[src*="${src}"]`).length > 0;
  return found_in_resources || found_in_script_tags;
}

3voto

Geeky Guy Punkte 8958

Include sie nicht zweimal. Immerhin bist du es, der die Includes macht.

Wenn du diese Inklusionen jedoch dynamisch machst, kannst du überprüfen, ob eine globale Funktion oder ein Objekt vom Skript gesetzt wurde. Wenn zum Beispiel das folgende Skript in einer Datei steht:

Foo = function () {};

Und dann füge es so ein:

Vor dem Parsen des Skript-Tags durch den Browser ist Foo undefined. Nachdem der Tag verarbeitet wurde, ist Foo eine Function. Du könntest auf dieser Logik basierend feststellen, ob du eine Datei einbeziehen solltest oder nicht.

2voto

Ich habe das mit einer generischen selbstaufrufenden Funktion gelöst, die am Ende jedes dynamisch geladenen Skripts hinzugefügt wird.

Zuerst - durch Deklarieren eines neuen leeren Arrays in meiner Basdatei oder einem Skript, das immer geladen wird, z. B. der Hauptseite in meinem Fall index.php

var scriptsLoaded = new Array();

Fügen Sie dann eine selbstausführende Funktion am Ende des geladenen Skripts hinzu:

(function () { scriptsLoaded.push( 'this_script_name.js' ) })();

Mit diesem Ansatz sollte sich jede Datei im scriptsLoaded-Array nur auf Skripts beziehen, die bereits vollständig geladen wurden. Einfaches Überprüfen dieses Arrays würde anzeigen, ob ein Skript geladen wurde, was auch als Prüfung verwendet werden kann, ob Onload-Style-Funktionen für das benötigte Skript ausgeführt werden sollen

1voto

UweB Punkte 4012

Ohne die Verwendung eines Frameworks (das ich kenne), kann dies nur erreicht werden, indem überprüft wird, ob eine bestimmte Variable im globalen Bereich bereits deklariert wurde.

Sie könnten eine Variable var include1 = true; innerhalb von include1.js deklarieren und etwas ähnliches tun wie

if (window.include1 !== true) {
    // Datei dynamisch laden
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X