wake-up-neo.com

Laden Sie den Javascript-Code SYNCHRON und wählen Sie ihn aus

Gibt es eine Möglichkeit, eine Javascript-Datei genau wie ein synchrones XMLHttpRequest zu laden und auszuführen?

Ich verwende derzeit eine Synchronisierung XMLHttpRequest und dann Eval, aber das Debuggen dieses Codes ist sehr schwierig ...

Danke für Ihre Hilfe!

Update

Ich habe das jetzt ausprobiert:

test.html

<html>
    <head>
        <script type="text/javascript">
            var s = document.createElement("script");
            s.setAttribute("src","script.js");
            document.head.appendChild(s);
            console.log("done");
        </script>
    </head>
    <body>
    </body>
</html>

script.js

console.log("Hi");

Ausgabe: Fertig Hi

Es wurde also nicht synchron ausgeführt. Irgendeine Idee, "Hi" zuerst erscheinen zu lassen?

Update 2 Anderes Beispiel

test.html (Code innerhalb eines Skript-Tags)

var s = document.createElement("script");
s.setAttribute("src","script.js");
document.head.appendChild(s);
SayHi();

script.js

function SayHi(){
    console.log("hi");
}

Ausgabe: Nicht gefundener ReferenceError: SayHi ist nicht definiert

31
Van Coding

Wenn Sie dies verwenden:

function loadScriptSync (src) {
    var s = document.createElement('script');
    s.src = src;
    s.type = "text/javascript";
    s.async = false;                                 // <-- this is important
    document.getElementsByTagName('head')[0].appendChild(s);
}

Sie können machen, was Sie wollen (obwohl in einer zusätzlichen Skriptdatei aufgeteilt)

test.html (Code innerhalb eines Skript-Tags):

loadScriptSync("script.js");
loadScriptSync("sayhi.js"); // you have to put the invocation into another script file

script.js :

function SayHi() {
     console.log("hi");
}

sayhi.js :

SayHi();
19
heinob

Alle Skripts, die nach der Fertigstellung von DOM geladen werden, werden asynchron geladen. Der einzige Grund, warum der Browser sie synchron lädt, ist die Funktion write, die etwas ausgeben kann. Sie können also Onload Callback des Skriptelements verwenden, um das zu erreichen, was Sie möchten.

var s = document.createElement("script");
s.setAttribute("src","script.js");
s.onload = function(){
    console.log('Done');
}
document.head.appendChild(s);

Eine andere Möglichkeit besteht darin, die js-Datei über XHR zu laden und Code innerhalb des Skriptelements festzulegen:

window.onload = function(){
    var req = new XMLHttpRequest();
    req.open('GET', "test.js", false);
    req.onreadystatechange = function(){
        if (req.readyState == 4) {
            var s = document.createElement("script");
            s.appendChild(document.createTextNode(req.responseText));
            document.head.appendChild(s);
        }
    };
    req.send(null);
}
13
bjornd

Aus einer ähnlichen Frage ( https://stackoverflow.com/a/3292763/235179 ):

<script type="text/javascript">
  document.write('<script type="text/javascript" src="other.js"><\/script>');
</script>

<script type="text/javascript">
  functionFromOther();
</script>

Entweder muss der vom document.write'd-Skript aufgerufene Code in seinem eigenen <script> oder in dem window.onload()-Ereignis enthalten sein.

10
Josh Johnson

Ihre Skripte werden synchron ausgeführt

ihr Code, wenn zusammengesetzt, lautet:

1. create script element
2. set its attribute src
3. set its attribute deferred
4. display done...

dieser erste Teil stoppt die Ausführung und übergibt sie dem nächsten Skript

5. script executes and displays Hi

Alles ist sehr synchron ... In Javascript wird ein Teil des Codes vollständig ausgeführt, bis er in der letzten Zeile ausgeführt wird oder die Ausführung an interne Systeme (wie XHR oder Timer) übergeben wird.

Wenn Sie einige Teile für die spätere Ausführung vorbereiten möchten, bereiten Sie sie mit setTimeout vor. Selbst wenn das Timeout kürzer ist als der Rest des Codes, dauert dies die Zeit, die es ausführt. Nachdem der Code ausgeführt wurde. Beispiel:

// some code
setTimeout(function(){ alert("I'm second alert"); }, 1);
longExecutionTask();
alert("I'm the first alert");

Auch wenn im obigen Code setTimeout zur Ausführung nach 1 ms eingestellt ist, wird der Code erst gestartet, wenn der Code nach dessen Ausführung beendet ist, der mit der Anzeige einer alert-Box endet. Dasselbe passiert in Ihrem Fall. Der erste Code-Stapel muss abgeschlossen sein, bevor etwas anderes gestartet werden kann.

Warum erhalten Sie eine Ausnahme (in Beispiel 2)

Sie haben etwas mehr Code hinzugefügt, nachdem ich meine Antwort geschrieben habe. Hier finden Sie weitere Informationen.

Durch das Hinzufügen eines Skript-Tags wird es nicht sofort ausgeführt. Das Laden und Ausführen des Skripts geschieht, wenn der HTML-Parser zu dem von Ihnen hinzugefügten SCRIPT-Element gelangt. Es wird es an diesem Punkt laden und seinen Inhalt auswerten/ausführen.

  1. Der HTML-Parser beginnt mit der Analyse Ihres Dokuments
  2. HEAD wird analysiert und der untergeordnete Tag SCRIPT wird analysiert und ausgeführt. Diese Ausführung fügt dem BODY-Tag ein weiteres Element hinzu, das noch nicht analysiert wurde.
  3. Der Parser wechselt zu BODY und analysiert seinen Inhalt (den neu hinzugefügten Tag SCRIPT), der das Skript lädt und seinen Inhalt ausführt.

SCRIPT-Elemente werden nur dann sofort ausgeführt, wenn Sie sie hinzufügen, nachdem Ihre Seite analysiert und bereits im Browser gerendert wurde. In Ihrem Fall ist das nicht der Fall. Das erste Skript wird sofort ausgeführt, und das dynamisch hinzugefügte Skript wird ausgeführt, wenn die Analyse ausgeführt wird.

5
Robert Koritnik

Sie können asynchrone Vorgänge untereinander synchronisieren. Erstellen Sie eine rekursive Funktion, um eine Schleife darzustellen, und rufen Sie die nächste Operation auf, wenn der vorherige Vorgang abgeschlossen ist. Die folgende Funktion importiert Skripts in der gleichen Reihenfolge. Es wartet, bis ein Skript geladen ist, und wenn kein Fehler auftritt, wird mit dem nächsten fortgesetzt. Wenn ein Fehler auftritt, ruft er die Rückruffunktion mit dem Fehlerereignis auf. Wenn kein Fehler auftritt, ruft dieselbe Rückruffunktion mit Null auf, nachdem alle Skripts geladen wurden. Es reinigt auch nach sich selbst mit s.parentNode.removeChild(s).

function importScripts(scripts, callback) {
    if (scripts.length === 0) {
        if (callback !== undefined) {
            callback(null);
        }
    }
    var i = 0, s, r, e, l;
    e = function(event) {
        s.parentNode.removeChild(s);
        if (callback !== undefined) {
            callback(event);
        }
    };
    l = function() {
        s.parentNode.removeChild(s);
        i++;
        if (i < scripts.length) {
            r();
            return;
        }
        if (callback !== undefined) {
            callback(null);
        }
    };
    r = function() {
        s = document.createElement("script");
        s.src = scripts[i];
        s.onerror = e;
        s.onload = l;
        document.head.appendChild(s);
    };
    r();
}
0
User0123456789