it-swarm.com.de

Wie kann ich auf das Skripttag verweisen, das das aktuell ausgeführte Skript geladen hat?

Wie kann ich auf das Skriptelement verweisen, das das aktuell ausgeführte Javascript geladen hat?

Hier ist die Situation. Ich habe ein "Master" -Skript hoch oben auf der Seite geladen, zuerst unter dem Tag HEAD.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type="text/javascript" src="scripts.js"></script>

Es gibt ein Skript in "scripts.js", das in der Lage sein muss, andere Skripte nach Bedarf zu laden. Die normale Methode funktioniert für mich nicht ganz, da ich neue Skripts hinzufügen muss, ohne auf den Tag HEAD zu verweisen, da das HEAD -Element nicht mit dem Rendern fertig ist:

document.getElementsByTagName('head')[0].appendChild(v);

Ich möchte auf das Skriptelement verweisen, das das aktuelle Skript geladen hat, sodass ich danach meine neuen dynamisch geladenen Skript-Tags an das DOM anfügen kann.

<script type="text/javascript" src="scripts.js"></script>
loaded by scripts.js--><script type="text/javascript" src="new_script1.js"></script>
loaded by scripts.js --><script type="text/javascript" src="new_script2.js"></script>
248
geuis

So erhalten Sie das aktuelle Skriptelement:

1. Verwenden Sie document.currentScript

document.currentScript gibt das <script>-Element zurück, dessen Skript gerade verarbeitet wird. 

<script>
var me = document.currentScript;
</script>

Leistungen

  • Einfach und explizit. Zuverlässig.
  • Das Skript-Tag muss nicht geändert werden
  • Funktioniert mit asynchronen Skripten (defer & async)
  • Arbeitet mit dynamisch eingefügten Skripten

Probleme

  • Funktioniert nicht in älteren Browsern und IE.

2. Wählen Sie das Skript anhand der ID aus

Wenn Sie dem Skript ein id-Attribut zuweisen, können Sie es mithilfe von document.getElementById() mithilfe der id leicht auswählen. 

<script id="myscript">
var me = document.getElementById('myscript');
</script>

Leistungen

  • Einfach und explizit. Zuverlässig.
  • Fast überall unterstützt
  • Funktioniert mit asynchronen Skripten (defer & async)
  • Arbeitet mit dynamisch eingefügten Skripten

Probleme

  • Erfordert, dem Script-Tag ein benutzerdefiniertes Attribut hinzuzufügen
  • Das id-Attribut kann in einigen Browsern für einige Edge-Fälle ein merkwürdiges Verhalten für Skripts verursachen

3. Wählen Sie das Skript mit einem data-*-Attribut aus

Wenn Sie dem Skript ein Attribut data-* geben, können Sie es leicht von innen auswählen. 

<script data-name="myscript">
var me = document.querySelector('script[data-name="myscript"]');
</script>

Dies hat wenige Vorteile gegenüber der vorherigen Option. 

Leistungen

  • Einfach und explizit.
  • Funktioniert mit asynchronen Skripten (defer & async)
  • Arbeitet mit dynamisch eingefügten Skripten

Probleme

  • Erfordert, dem Script-Tag ein benutzerdefiniertes Attribut hinzuzufügen
  • HTML5 und querySelector() sind nicht in allen Browsern kompatibel
  • Weniger verbreitet als das id-Attribut
  • Umgeht <script> mit id Edge-Fällen. 
  • Kann verwirrt werden, wenn ein anderes Element auf der Seite das gleiche Datenattribut und den gleichen Wert aufweist.

4. Wählen Sie das Skript mit Hilfe von src aus

Anstatt die Datenattribute zu verwenden, können Sie das Skript nach Quelle mit dem Selektor auswählen:

<script src="//example.com/embed.js"></script>

In embed.js:

var me = document.querySelector('script[src="//example.com/embed.js"]');

Leistungen

  • Zuverlässig
  • Funktioniert mit asynchronen Skripten (defer & async)
  • Arbeitet mit dynamisch eingefügten Skripten
  • Keine benutzerdefinierten Attribute oder IDs erforderlich

Probleme

  • Funktioniert not nicht für lokale Skripts
  • Wird in verschiedenen Umgebungen, wie Entwicklung und Produktion, Probleme verursachen
  • Statisch und zerbrechlich. Wenn Sie den Speicherort der Skriptdatei ändern, müssen Sie das Skript ändern
  • Weniger verbreitet als das id-Attribut
  • Wird Probleme verursachen, wenn Sie dasselbe Skript zweimal laden

5. Durchlaufen Sie alle Skripts, um das gewünschte zu finden

Wir können auch jedes Skriptelement durchlaufen und jedes einzeln überprüfen, um das gewünschte Element auszuwählen:

<script>
var me = null;
var scripts = document.getElementsByTagName("script")
for (var i = 0; i < scripts.length; ++i) {
    if( isMe(scripts[i])){
      me = scripts[i];
    }
}
</script>

Auf diese Weise können wir beide älteren Techniken in älteren Browsern verwenden, die querySelector() nicht gut mit Attributen unterstützen. Zum Beispiel:

function isMe(scriptElem){
    return scriptElem.getAttribute('src') === "//example.com/embed.js";
}

Dies erbt die Vorteile und Probleme des gewählten Ansatzes, ist jedoch nicht auf querySelector() angewiesen und funktioniert daher auch in älteren Browsern.

6. Holen Sie sich das zuletzt ausgeführte Skript

Da die Skripts sequenziell ausgeführt werden, ist das letzte Skriptelement häufig das aktuell ausgeführte Skript: 

<script>
var scripts = document.getElementsByTagName( 'script' );
var me = scripts[ scripts.length - 1 ];
</script>

Leistungen

  • Einfach.
  • Fast überall unterstützt
  • Keine benutzerdefinierten Attribute oder IDs erforderlich

Probleme

  • Funktioniert not mit asynchronen Skripten (defer & async)
  • Funktioniert not mit dynamisch eingefügten Skripts
549
brice

Da Skripts sequenziell ausgeführt werden, ist das aktuell ausgeführte Skript-Tag immer das letzte Skript-Tag auf der Seite bis dahin. Um das Skript-Tag zu erhalten, können Sie Folgendes tun:

var scripts = document.getElementsByTagName( 'script' );
var thisScriptTag = scripts[ scripts.length - 1 ];
87
Coffee Bite

Am einfachsten wäre es wahrscheinlich, Ihrem Skript-Tag ein id-Attribut zu geben.

11
Greg

Script werden nur dann sequentiell ausgeführt, wenn sie weder ein Attribut "defer" noch "async" haben. Die Kenntnis eines der möglichen ID/SRC/TITLE-Attribute des Script-Tags könnte auch in diesen Fällen funktionieren. Also sind sowohl Greg als auch Justin Vorschläge richtig.

In den WHATWG-Listen gibt es bereits einen Vorschlag für einen document.currentScript.

EDIT: Firefox> 4 implementieren diese sehr nützliche Eigenschaft bereits, aber sie ist in IE11 nicht verfügbar. Zuletzt habe ich überprüft und ist nur in Chrome 29 und Safari 8 verfügbar.

EDIT: Niemand hat die "document.scripts" -Sammlung erwähnt, aber ich glaube, dass das Folgende eine gute browserübergreifende Alternative sein kann, um das aktuell laufende Skript zu erhalten:

var me = document.scripts[document.scripts.length -1];
10
Diego Perini

Hier ist eine Art Polyfill, das document.CurrentScript nutzt, falls vorhanden, und das Skript anhand der ID findet.

<script id="uniqueScriptId">
    (function () {
        var thisScript = document.CurrentScript || document.getElementByID('uniqueScriptId');

        // your code referencing thisScript here
    ());
</script>

Wenn Sie dies am Anfang jedes Skript-Tags einfügen, können Sie sicher feststellen, welches Skript-Tag ausgelöst wird, und Sie können auch das Skript-Tag im Kontext eines asynchronen Rückrufs referenzieren.

Ungetestet, also lassen Sie uns ein Feedback für andere, wenn Sie es versuchen.

9
Art Lawry

Es muss beim Laden der Seite und beim Hinzufügen eines Skript-Tags mit Javascript (z. B. mit ajax) funktionieren.

<script id="currentScript">
var $this = document.getElementById("currentScript");
$this.setAttribute("id","");
//...
</script>
6
David Callizaya

Ein Ansatz für den Umgang mit asynchronen und verzögerten Skripts besteht darin, den Onload-Handler zu nutzen, einen Onload-Handler für alle Skript-Tags.

function getCurrentScript(callback) {
  if (document.currentScript) {
    callback(document.currentScript);
    return;
  }
  var scripts = document.scripts;
  function onLoad() {
    for (var i = 0; i < scripts.length; ++i) {
      scripts[i].removeEventListener('load', onLoad, false);
    }
    callback(event.target);
  }
  for (var i = 0; i < scripts.length; ++i) {
    scripts[i].addEventListener('load', onLoad, false);
  }
}

getCurrentScript(function(currentScript) {
  window.console.log(currentScript.src);
});
3
Pete Blois

Folgen Sie diesen einfachen Schritten, um einen Verweis auf den aktuell ausgeführten Skriptblock zu erhalten:

  1. Fügen Sie eine zufällige eindeutige Zeichenfolge in den Skriptblock ein (muss in jedem Skriptblock eindeutig sein/unterschiedlich sein)
  2. Iteriere das Ergebnis von document.getElementsByTagName ('script') und schaue die eindeutige Zeichenfolge von jedem Inhalt an (abgerufen von der innerText/textContent-Eigenschaft).

Beispiel (ABCDE345678 ist die eindeutige ID) :

<script type="text/javascript">
var A=document.getElementsByTagName('script'),i=count(A),thi$;
for(;i;thi$=A[--i])
  if((thi$.innerText||thi$.textContent).indexOf('ABCDE345678'))break;
// Now thi$ is refer to current script block
</script>

Übrigens, für Ihren Fall können Sie einfach die altmodische document.write () - Methode verwenden, um ein anderes Skript einzubeziehen .. Da Sie bereits erwähnt haben, dass DOM noch nicht gerendert wurde, können Sie den Vorteil nutzen, dass der Browser das Skript immer linear ausführt Sequenz (mit Ausnahme von verzögertem, das später wiedergegeben wird), so dass der Rest Ihres Dokuments immer noch "nicht vorhanden" ist ..__ Alles, was Sie über document.write () schreiben, wird direkt nach dem Aufruferskript eingefügt.

Beispiel einer ursprünglichen HTML-Seite :

<!doctype html>
<html><head>
<script src="script.js"></script>
<script src="otherscript.js"></script>
<body>anything</body></html>

Inhalt von script.js :

document.write('<script src="inserted.js"></script>');

Nach dem Rendern wird die DOM-Struktur zu:

HEAD
  SCRIPT script.js
  SCRIPT inserted.js
  SCRIPT otherscript.js
BODY
2
Ferdinand Liu

Um das Skript zu erhalten, können Sie das aktuell geladene Skript verwenden

var thisScript = document.currentScript;

Sie müssen eine Referenz am Anfang Ihres Skripts aufbewahren, damit Sie sie später aufrufen können

var url = thisScript.src

Betrachten Sie diesen Algorithmus. Wenn Ihr Skript geladen wird (wenn es mehrere identische Skripts gibt), durchsuchen Sie document.scripts, suchen Sie das erste Skript mit dem richtigen "src" -Attribut, speichern Sie es und markieren Sie es als "besucht" mit einem Datenattribut oder einem eindeutigen Klassennamen.

Wenn das nächste Skript geladen wird, scannen Sie document.scripts erneut, und übergeben Sie alle Skripts, die bereits als besucht markiert sind. Nehmen Sie die erste nicht besuchte Instanz dieses Skripts.

Dies setzt voraus, dass identische Skripten wahrscheinlich in der Reihenfolge ausgeführt werden, in der sie geladen werden, von Kopf bis Text, von oben nach unten, von synchron bis asynchron.

(function () {
  var scripts = document.scripts;

  // Scan for this data-* attribute
  var dataAttr = 'data-your-attribute-here';

  var i = 0;
  var script;
  while (i < scripts.length) {
    script = scripts[i];
    if (/your_script_here\.js/i.test(script.src)
        && !script.hasAttribute(dataAttr)) {

        // A good match will break the loop before
        // script is set to null.
        break;
    }

    // If we exit the loop through a while condition failure,
    // a check for null will reveal there are no matches.
    script = null;
    ++i;
  }

  /**
   * This specific your_script_here.js script tag.
   * @type {Element|Node}
   */
  var yourScriptVariable = null;

  // Mark the script an pass it on.
  if (script) {
    script.setAttribute(dataAttr, '');
    yourScriptVariable = script;
  }
})();

Dadurch wird das gesamte Skript nach dem ersten übereinstimmenden Skript durchsucht, das nicht mit dem speziellen Attribut gekennzeichnet ist.

Markieren Sie diesen Knoten dann mit einem Datenattribut, damit nachfolgende Scans ihn nicht auswählen können. Dies ist vergleichbar mit BFS- und DFS-Algorithmen für Diagrammdurchquerungen, bei denen Knoten als "besucht" markiert werden können, um eine erneute Überprüfung zu verhindern.

2
LSOJ

Ich habe festgestellt, dass der folgende Code der konsistenteste, performanteste und einfachste ist.

var scripts = document.getElementsByTagName('script');
var thisScript = null;
var i = scripts.length;
while (i--) {
  if (scripts[i].src && (scripts[i].src.indexOf('yourscript.js') !== -1)) {
    thisScript = scripts[i];
    break;
  }
}
console.log(thisScript);
0
Travis Tidwell

Wenn Sie den Dateinamen des Skripts annehmen können, können Sie ihn finden. Ich habe die folgende Funktion bisher nur in Firefox getestet. 

  function findMe(tag, attr, file) {
    var tags = document.getElementsByTagName(tag);
    var r = new RegExp(file + '$');
    for (var i = 0;i < tags.length;i++) {
      if (r.exec(tags[i][attr])) {
        return tags[i][attr];
      }
    }
  };
  var element = findMe('script', 'src', 'scripts.js');
0
Justin Love

Es gibt einen anderen einfachen Weg, wenn Sie den Namen des Skripts (oder zumindest einen Teil davon) kennen:

document.querySelector('script[src*="<scriptname>.js"]')

Dies wird auch in IE11 funktionieren.

0