
Funktionsweisen
Ermitteln, wie lange sich der User schon auf
der Seite befindet
Es gibt unterschiedliche Gründe, warum man mit
JavaScript auf das aktuelle Datum zugreifen will. Sehr oft
sieht man diesen Effekt
oder, wenn man es animierter will, kann man auch sowas
machen: ene mene meck.
Oder man teilt dem User mit, wie lange er sich schon auf der
Website befindet, das sieht dann so aus: Sie
befinden sich bereits
Sekunden auf dieser Website.
Hat man die prinzipielle und einfache Funktionsweise
verstanden, kann man alle möglichen "Spielereien"
realisieren. Man kann den User in Abhängigkeit von der
Tageszeit unterschiedlich begrüssen, man kann das Design
den Monaten anpassen, man kann ausrechnen lassen, wieviele
Tage es noch sind bis zu einem bestimmten Termin (Geburtstag,
Weihnachten etc.), man kann zu bestimmten vorgegebenen Tagen
einen Spruch einblenden z.B. am ersten Mai "Im Schweisse
deines Angesichts sollst Du Dein Brot essen " oder ähnlich
erbauendes.
Machen wir uns die
prinzipielle Funktionsweise anhand des ersten Skriptes, der
der das aktuelle Datum aufblendet, und verbessern ihn bei
dieser Gelegenheit noch ein bisschen.
<html><head><title>Datum
ermitteln und zeigen</title>
function neuzeit1()
{
zeit=new Date();
aktuellezeit="Das aktuelle Datum ist "+ zeit.getDate+"."+
zeit.getMonth+"."+ zeit.getYear()+" "+
zeit.getHours()+":"+ zeit.getMinutes()+":"+zeit.getSeconds()
document.getElementById("uhr0").innerHTML=aktuellezeit;
}
</script>
</head>
<body onload="neuzeit1()">
<span id="uhr0"></span>
</body>
</html>
Dieser Skript ist verbesserungsfähig,
aber er zeigt erstmal das Prinzip. Wird die HTML Seite aufgerufen,
wird das Datum gezeigt (siehe Anfang dieses Kapitels. ) Wie
so oft in JavaScript, z.B. auch bei Bildern kreiieren wir
eine Instanz einer Klasse. Das heisst, es gibt einen Konstruktur
in JavaScript der Date() heisst. Man muss sich für die
Hintergründe nicht interessieren, wen es interessiert,
der kann zum Kapitel Eigene
Objekte mit JavaScript hopsen und die
Hintergründe dort nachlesen. Wir interessieren uns in
der Regel bei JavaScript für die Hintergründe nicht,
da wir eine für die Problemstellungen im Internetbereich
ausreichende Menge an Objekten zur Verfügung gestellt
bekommen und nicht notwendigerweise selber Objekte programmieren
müssen. Der langen Rede kurzer Sinn, wir kreieren eine
Instanz der Klasse date() und diese Instanz kann dann alles,
was die Klasse kann, das heisst, sie erbe alle Eigenschaften
und Methoden der Klasse date(). Wenn zeit also eine Instanz
(ein Objekt) der Klasse date() ist, dann stehen uns folgende
Methoden zur Verfügung.
zeit.getMonth
|
ermittelt den aktuellen Monat.
Allerdings hat der Januar den Wert 0, so dass wir korrigieren
müssen. |
zeit.getDate |
ermittelt den aktuellen Monatstag (1 bis
31) |
zeit.getYear |
ermittelt das Jahr. Das funktionniert
beim Explorer korrekt bei Netscape fehlen 1900 Jahre.
|
zeit.getHours |
ermittelt die Anzahl der Stunden (0 bis
23) |
zeit.getMinutes |
ermittelt die Anzahl der Minuten (0 bis
59) |
zeit.getSeconds |
ermittelt die Anzahl der Sekunden (0 bis
59) |
Wir haben nun Probleme Stücker mehrere. Erstens hätte
wir gerne, dass der Monat ausgeschrieben ist, also nicht 13.6.2003
sondern 13. Juni 2003 und zweitens hätten wir gerne, dass
die Uhrzeit korrekt formatiert ist, also nicht 12:7:5 sondern
12:07:05. Genau genommen ist das erste zwar richtig (sieben
Minuten nach zwölf) und das zweite falsch (was ist 07 Minuten
nach zwölf ?) aber die zweite Darstellung ist das, was
jede Uhr mit digitalem Zifferblatt anzeigt, folglich wollen
wir es so haben. Drittens haben wir noch ein Problem mit Netscape,
weil dieser anstatt 2003 uns 103 auf den Schirm setzt. Wir müssen
unseren Skript also modifizieren.
<html><head><title>Operationen mit Zeitangaben</title>
</head> <script language="javascript">
var monate=new Array
("Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember");
function neuzeit()
{
var zeit=new Date();
monat=monate[zeit.getMonth()];
tag=String(zeit.getDate());
if(tag.length ==1)
{ tag=0+tag;}
stunde=String(zeit.getHours());
if(stunde.length ==1)
{ stunde=0+stunde;}
minute=String(zeit.getMinutes());
if(minute.length ==1)
{ minute=0+minute;}
sekunde=String(zeit.getSeconds());
if(sekunde.length ==1)
{ sekunde=0+sekunde;}
jahr=zeit.getYear();
if(!document.all)
{
jahr=jahr+1900;
}
aktuellezeit2="Das aktuelle Datum
ist "+ tag+"."+ monat+"."+ jahr+"
"+ stunde+":"+ minute+":"+sekunde;
document.getElementById("uhr0").innerHTML=aktuellezeit2;
setTimeout("neuzeit()",1000);
}
</script>
<body onload="neuzeit();">
<span id="uhr0"></span>
</body>
</html>
Das führt dann, sowohl
bei Netscape als auch beim Explorer zu einer Darstellung des
Datums, die so aussieht: .
Die Veränderungen zum vorherigen Beispiel sind minimal. Wir
betrachten die Veränderungen.
Zu Beginn des Skriptes haben wir diese Zeile.
var monate=new Array
("Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember");
Das heisst, wir bilden einen Array, der alle
Monate speichert, womit unser Problem, den Namen des Monats
aufzublenden fast gelöst ist. Die Funktion zeit.getMonth
liefert uns ja eine Zahl von 0 bis 11. Das Element 0 unseres
Arrays ist Januar, das Element 1 Februar usw. Wir brauchen
also nur die Funktion einsetzen und unser Problem ist gelöst.
Auch unser Problem mit der Formatierung (wir wollen 05 und
nicht 5) ist schnell gelöst.
stunde=String(zeit.getHours());
if(stunde.length ==1)
{ stunde=0+stunde;}
Wir konvertieren die Zahl, die uns die
Funktion getHours liefert in eine Zeichenkette, genau genommen
in eine Instanz der Klasse String. Diese Instanz hat dann
die Eigenschaft length, die von der Klasse geerbt wird. Zu
deutsch, wir ermitteln, wieviele Ziffern die Zahl hat, die
uns die Funktion getHours liefert. Hat diese nur 1 Ziffer
(0 bis 9) dann setzen wir eine 0 davor. Das machen wir mit
Stunde, Minute und Sekunde. Das war es auch schon. Schliesslich
prüfen wir noch, ob wir es mit Netscape oder mit dem
Explorer zu tun haben. Haben wir es mit Netscape zu tun, addieren
wir an das Jahr noch 1900. Finis operis.
Ermitteln,
wie lange sich der User schon auf der Seite befindet |
|
Viele Leute beschäftigt die Frage,
wie lange sich ein User auf einer Seite aufhält. Um sich
ein Bild zu machen, von was überhaupt die Rede ist, drückt
man am besten hier.
Alles klar ? Wir ermitteln und speichern, wie lange sich der
User auf einer Seite aufhält. Das Problem zerfällt
in zwei Teile. Erstens muss ermittelt werden, wie lange der
User schon auf der Seite ist und zweitens muss man es noch
fertigringen, die ermittelten Daten an den Server zu übertragen,
den höchstwahrscheinlich will man sich das hinterher
ja ansehen, muss es folglich irgendwo speichern. Lösen
wir also erstmal den ersten Teil des Problems. Der Skript,
der den eingangs abgebildeten Sekundenzähler realisiert
sieht so aus.
<html><head><title>Sekundenzähler</title>
<script language="javascript">
altzeit=new Date();
function neuzeit2()
{
var neuzeit=new Date();
differenz=neuzeit.getTime() - altzeit.getTime();
document.getElementById("uhr2").innerHTML=parseInt(differenz/1000);
setTimeout("neuzeit2()",1000);
}
</script>
</head>
<body>
Sie sind bereits <span id="uhr2"></span>
Sekunden auf dieser Website.
</body>
</html>
Um zu ermitteln, wie lange sich der User
bereits auf der Seite aufhält, brauchen wir zwei Instanzen
der Klasse Date(). Eine, die wir kreieren, wenn die Seite
aufgerufen wird und eine, die jedesmal neu kreiert wird, wenn
die Funktion aufgerufen wird. Mit
altzeit.getTime()
ermitteln wir die Zeit, als die Seite geladen
wurde und mit
neuzeit.getTime()
ermitteln wir die Zeit, wenn die Funktion aufgerufen
wird. Die Zeit der Instanz altzeit ändert sich nicht,
die Zeit der Instanz neuzeit ändert sich. Die Differenz
aus diesen beiden Zeiten ist dann die Zeit, die der User auf
der Seite verbracht hat. Da setTimeout nicht exakt ist, runden
wir den berechneten Wert mit parseInt(). Wir kommen zum zweiten
Teil unseres Problems. Wir müssen es schaffen, den ermittelten
Wert (also die Sekunden) an ein serverseitig arbeitendes Programm
zu übergeben, welches diese Zahl dann irgendwo abspeichert.
Weiter müssen wir noch den Namen der HTML Seite (den
Dateinamen) mit übergeben und mit abspeichern, weil wir
sonst ja nicht wissen, welche Seite angeschaut wurde. Aus
didaktischen Gründen bauen wir das Skript Stück
für Stück zusammen. Das ist der erste Teil.
<html><head><title>Operationen
mit Zeitangaben</title>
</head>
<script language="javascript">
altzeit=new Date();
function neuzeit2()
{
var neuzeit=new Date();
differenz=neuzeit.getTime() - altzeit.getTime();
dauer=parseInt(differenz/1000);
document.getElementById("uhr0").innerHTML=dauer;
setTimeout("neuzeit2()",1000);
}
function speichern()
{
dauer=String(dauer);
url=document.URL.replace(/.*\\/,"");
url=url.replace(/\./,"_");
alert(url+" "+dauer);
}
window.onload=neuzeit2;
</script>
<body>
<span id="uhr0"></span> <br>
<A href=javascript:speichern()>test</a>
</body>
</html>
Wenn man das Programm
aufruft, sieht es so
aus so aus. Verändert wurden im wesentliche
zwei Dinge. Um einen wird die Funktion nicht mehr über
den event handler onload als Attribut des body tag aufgerufen.
Wir verwenden
window.onload=neuzeit2;
Das ist praktischer. Will man diesen Skript tatsächlich
nutzen und viele Seiten damit auswerten, ist es einfacher,
wenn lediglich der JavaScript in die zu kontrollierende Seite
reinkopiert werden muss. Würde man einen event handler
benutzen, müsste auch dieser jeweils reinkopiert werden.
Anschliessend ermitteln wir den Namen der Datei in der sich
der Zähler befindet.
url=document.URL.replace(/.*\\/,"");
url=url.replace(/\./,"_");
document.URL ist der gesamte Pfad zu der Datei.
Von dieser wollen wir aber nur den eigentlichen Namen, den
wir uns mit einer regular expression, siehe Regular
Expressions und deren praktische Anwendung, rausfischen.
Von diesem wollen wir aber nur den letzten Teil, den eigentlichen
Dateinamen. Anschliessend ersetzen wir den Punkt vor der Dateiendung
noch durch einen Unterstrich, weil wir nicht wollen, dass
irgend jemand das als html Datei interpretiert. Nun müssen
wir nur noch die zwei ermittelten Werte an unseren Perl Skript,
den wir gleich durchsprechen werden, übergeben. Der vollständige
JavaScript sieht also so aus.
<script language="javascript">
var altzeit=new Date();
var dauer;
var differenz;
function neuzeit2()
{
neuzeit=new Date();
differenz=neuzeit.getTime() - altzeit.getTime();
dauer=parseInt(differenz/1000);
//document.getElementById("uhr0").innerHTML=dauer;
setTimeout("neuzeit2()",1000);
}
function speichern()
{
dauer=String(dauer);
url=document.URL.replace(/.*\\/,"");
url=url.replace(/\./,"_");
parent.unsichtbar.location.href="http://www.infos24.de/cgi-bin/zeitspeichern.pl?zeit="+dauer+"&datei="+url;
}
window.onload=neuzeit2;
window.onunload=speichern;
</script>
Er ist in jede Seite, die wir kontrollieren
wollen zu integrieren. Wir können uns jetzt wundern über
diese Zeile.
parent.unsichtbar.location.href="http://www.infos24.de/cgi-bin/zeitspeichern.pl?zeit="+dauer+"&datei="+url;
location.href ruft eigentlich eine Seite auf.
Das wollen wir aber nicht. Die einzige Möglichkeit, die
wir haben, das Problem zu umgehen ist die Rückgabe des
Perl Skriptes in einen unsichtbaren Frame zu schiessen. Das
ganze kann also nur funktionnieren, wenn die Website einen
unsichtbaren Frame hat und es funktionniert auch nur solange,
wie der User innerhalb der Seite navigiert. Der eigentliche
Perl Skript, der die Daten entgegennimmt, sie speichert und
sie wieder ausliest sieht dann so aus.
!/usr/bin/perl
print "Content-type:text/html\n\n";
$frage=$ENV{'QUERY_STRING'};
@frage=split(/&/,$frage);
foreach $i(0..$#frage)
{
($key,$value)=split(/=/,$frage[$i],2);
$value=~s/%(..)/pack("c",hex($1))/ge;
$Frage{$key}=$value;
}
##############################################################
if(!$Frage{modul})
{
open(KIRSCHE,">>speicher.txt");
print KIRSCHE "$ENV{REMOTE_ADDR} $Frage{zeit} $Frage{datei}\n";
close(KIRSCHE);
}
else
{
open(KIRSCHE,"speicher.txt");
@aprikose=<KIRSCHE>;
close(KIRSCHE);
foreach $banane(@aprikose)
{
($ip,$zeit,$datei)=split(" ",$banane);
print "Ip Nummer:$ip Verweildauer: $zeit
betrachtete Datei:$datei <br>";
}
}
Wer diesen Skript jetzt nicht versteht, der kann das Perl
Handbuch konsultieren.
|
 |