Dynamischer Ladebalken
In diesem Artikel habt ihr gelernt, wie man einen Ladebalken erstellt.
Im "echten Leben" benötigt man solche Balken meistens, um den Benutzer über den Fortschritt einer langwierigen Aktion auf dem Server zu informieren. Beispiele dafür sind das Aufräumen einer Datenbank oder das versenden einer großen Mail.
Hier werde ich erläutern, wie man eine solche Echtzeitvariante des Ladebalkens erstellen kann.
Nach obenLos gehts...
Zu allererst einmal muss man in die Seite, die später den Ladebalken enthalten soll, den Ladebalken einbauen.
Da Zweck dieses Tutorials nicht die Erklärung des DOM sein soll, werde ich hier der Einfacherheit halber den Fortschrittsbalken direkt in den Quelltext einfügen - besser ist es jedoch, ihn erst zur Laufzeit zu generieren, damit User ohne javascriptfähigen Browser keinen verwaisten Container zu sehen bekommen.
<div id="ladebalken"><p style="width: 1%;"><span>1%</span></p></div>
Wichtig ist, dass keine Leerzeichen im Code enthalten sind. Die CSS Datei könnt ihr aus dem Tutorial zum Ladebalken übernehmen.
Nach obenJavascript im Browser
Um den Trafficaufwand zu minimieren, sollte man in der Ausgabe per Javascript eine Funktion definieren, die den Ladebalken auf einen neuen Prozentwert einstellt. Geändert werden muss dabei:
- Der Prozentwert der Breite von
#ladebalken p - Der Text in
#ladebalken p span - Mehr als Spielerei verändere ich noch die Farbe
Das Script selbst bedarf wenig Erklärung:
Per document.getElementById
lade ich den Ladebalken, um dann dessen
Kindelemente über das DOM zu modifizieren.
Wenn Sinn und Unsinn des Farbcodes interessiert:
Im Farbkreis ist zwischen Rot und Grün
nur die Hauptfarbe Gelb (#ff0), daher reicht
es hier, einen einfachen Übergang von Rot
nach Gelb (< 50%) und dann von Gelb nach
Grün (> 50%) zu machen. Eine nähere Erklärung
würde auf einen Farblehreworkshop hinauslaufen
und die Grenzen dieses Tuturials sprengen.
<script type="text/javascript">
<!--
oLadebalken = document.getElementById("ladebalken").firstChild;
function progress(value)
{
if(value < 51)
oLadebalken.style.background = 'rgb(255, ' +
Math.floor(value / 50 * 255) + ', 0)';
else
oLadebalken.style.background = 'rgb(' +
Math.floor(255 - ((value - 50) / 50 * 255)) +
', 255, 0)';
oLadebalken.firstChild.firstChild.nodeValue =
oLadebalken.style.width = value + "%";
}
// -->
</script>
Uns steht jetzt also die Funktion progress zur
Verfügung, um einen neuen Prozentwert einzustellen.
In PHP
In PHP benötigen wir nun nur noch eine
simple Funktion, die ein Javascript ausgibt,
das wiederum die progress Funktion
aufruft.
Wichtig ist es, den flush
Befehl nach der Ausgabe aufzurufen, damit
PHP keine Ausgaben zurückhält.
function progress($value)
{
echo('<script type="text/javascript">progress('.
intval($value).');</script>');
flush();
}
Nach obenAufruf
Der Aufruf sollte nun klar sein: In die
lang dauernde Aktion baut ihr eine simple
Prozentrechnung ein und ruft regelmäßig
die progress Funktion auf.
Hier ein vollkommen sinnfreies Beispiel, um die Funktion zu verdeutlichen:
for($i=0; $i<=78; $i+=2)
{
progress($i / 78 * 100);
usleep(50000);
}
Nach obenUnd wie sieht es aus?
Um die sinnfreie Demo fortzuführen, folgt nun noch eine fast sinnfreie HTML Vorführung: Zwar enthält sie den oben gennanten PHP Code, jedoch ist er auskommentiert und durch ein weiteres Javascript ersetzt. Diese Demo ist also rein visuell, damit ihr wisst, wie es aussieht :)
Hier gehts zur Demo!
curi
Sieht echt witzig aus :D und guter Atk. btw ^^
greetz
fphilipe
Ich würde das oLadebalken erst definieren, wenn das dokument geladen ist, da es sonst möglicherweise nicht gefunden wird, da es noch nicht geladen wurde.
window.onload = function() {
oLadebalken = ...
}
pberndt
Solange man das Script erst nach dem Ladebalken setzt, ist es auf jeden Fall bereits geladen.. ansonsten hast du natürlich recht, das hätte ich noch erwähnen können... ich halte onload normalerweise lieber leer ;)
TeKi
Hallo, an sich ein super Teil, das mit der Farbe find ich erstklassig. Hätt ich nicht gekonnt. Allerdings sollte darauf geachtet werden, dass nicht für jeden Schleifendurchlauf "progress()" aufgerufen wird. Sondern nur wenn sich die Prozentzahl ändert.
Habe als Beispiel ne Berechnung von ca. 2000 Elementen. Wenn ich jedes mal progress() aufrufe, dann wird auch 2000 mal '<script type="text/javascript">progress('.
intval($value).');</script>'
ausgegeben. Das macht den Process der Berechnung zum einen nicht schneller, zum andern ist in der HTML Datei hinterher mehr Javascript-Zeug als alles andere :-).
Lösung: Einfach eine kleine If-Abfrage
$prozent=0;
for($i=0; $i<=2000; $i+=2)
{
berechne()
neuprozent=intval($i / 2000 * 100);
if($prozent< neuprozent)
{
progress($neuprozent);
$prozent=$neuprozent;
}
Sowas in der art, hat dann den Vorteil, dass nur 100 mal der Javascript-Code ausgegeben wird.
Chris
}
sanktusm
der ladebalken sieht gut aus. Nur sollte er in relation zum Upload oder Downloadstatus stehen. Es muss also berechnet werden, wieviel % der Daten bereits hochgeladen wurden.
Weiß jemand wie man das anstellt?
Firebird
Dafür brauchst du uploadprocess aus PECL: pecl.php.net
Und Ajax.
hoascht
... oder PHP 5.2 und Upload Hook. Dazu gibts von Rasmus ein Beispiel: progphp.com
htn
Komisch! Ich verstehe den nicht. Der Ladebalken ist da und zählt hoch. Aber wieweit die Seite wirklich geladen hat, zeigt er nicht an!