2013-08-08 5 views
20

Sagen wir zum Beispiel, ich erstelle ein Spiel. Ich habe ein kleines Skript, dessen Aufgabe es ist, alle Assets zu laden und dem Benutzer einen Fortschrittsbalken anzuzeigen, während die Assets geladen werden.Wie bekomme ich den Fortschritt eines Herunterladens <script>?

Ein solches Asset ist ein ziemlich großes Skript, das die Spiellogik enthält. Vielleicht ab 3 MB.

Wie kann ich dem Benutzer den Ladevorgang des zweiten Skripts anzeigen?

+0

Eng verwandt: [requirjs laden Skriptfortschritt] (http://stackoverflow.com/questions/15581563/requirejs-load-script-progress) ("* RequrieJs lädt das Modul durch Erstellen eines neuen Skript-Tags im DOM und hört auf das load-Ereignis, es gibt keine update-Ereignisse zwischen dem Start und dem end-Laden. * ") – apsillers

+0

Das ist eine Browser-Sache, die wir als Programmierer nicht kontrollieren können. Nur wenn der Browser das Laden und "Kompilieren" der JS-Datei beendet, kann man auf sie zugreifen, so dass ich nur mehrere kleinere Dateien sehen und die Logik unter ihnen aufteilen kann. –

Antwort

27

<script> Tags nur Feuer load und error Ereignisse; sie feuern nicht progress Ereignisse. In modernen Browsern jedoch Ajax requests do support progress events. Sie können Ihr Skript Inhalt und Überwachung der Fortschritte durch Ajax, und legen Sie dann die Skriptinhalte in ein neues <script> Element laden, wenn der Ladevorgang abgeschlossen ist:

var req = new XMLHttpRequest(); 

// report progress events 
req.addEventListener("progress", function(event) { 
    if (event.lengthComputable) { 
     var percentComplete = event.loaded/event.total; 
     // ... 
    } else { 
     // Unable to compute progress information since the total size is unknown 
    } 
}, false); 

// load responseText into a new script element 
req.addEventListener("load", function(event) { 
    var e = event.target; 
    var s = document.createElement("script"); 
    s.innerHTML = e.responseText; 
    // or: s[s.innerText!=undefined?"innerText":"textContent"] = e.responseText 
    document.documentElement.appendChild(s); 

    s.addEventListener("load", function() { 
     // this runs after the new script has been executed... 
    }); 
}, false); 

req.open("GET", "foo.js"); 
req.send(); 

Für ältere Browser, die Ajax nicht unterstützen progress, können Sie bauen Ihre Fortschrittsbericht-Benutzeroberfläche, um eine Ladeleiste erst nach dem ersten Ereignis progress anzuzeigen (oder andernfalls einen generischen Spinner anzuzeigen, wenn keine progress Ereignisse ausgelöst werden).

1

Vielleicht möchten Sie einen Blick haben bei How to show loading status in percentage for ajax response?

Es ist den Status eines AJAX-Download zu sehen. Da Sie ein Skript laden, ist es möglicherweise nicht der beste Weg, um die Datei zu erhalten, aber es könnte funktionieren. Sie müssten dann den Inhalt, der durch den Ajax-Aufruf empfangen wurde, irgendwo zur Ausführung bringen, und eval wird nicht empfohlen.

+4

Dies scheint ein akzeptabler Anwendungsfall für 'eval' zu sein. Hast du einen Grund, es nicht zu empfehlen, oder sagst du das gedankenlos? – andrewrk

+1

'eval' wurde gemacht um sowas zu machen. Das einzige Mal, dass "eval" nicht empfohlen wird, ist, wenn es nicht benötigt wird, oder es ist ein großes Sicherheitsrisiko. Die einzige Möglichkeit, ein Sicherheitsrisiko einzugehen, wäre ein Man-in-the-Middle-Angriff oder ein kompromittierter Server - beide bieten weitaus größere Risiken als "eval". – h2ooooooo

+0

Mir wurde immer gesagt, Eval nicht zu verwenden, außer du WIRKLICH brauchen ... So könnten Sie Recht haben. Vielleicht könnte auch eine Script-Tag-Injektion durchgeführt werden, genau wie bei requireJS, müssen sie einen Grund haben, eval nicht zu verwenden? – Salketer

Verwandte Themen