Werbung einblenden Werbung ausblenden


Home / Tutorials / JavaScript Handbuch / Operationen mit Zeitangaben


Funktionsweisen
Ermitteln, wie lange sich der User schon auf der Seite befindet

Funktionsweisen

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>&nbsp; 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 &nbsp; Verweildauer: $zeit &nbsp; betrachtete Datei:$datei <br>";
}
}

Wer diesen Skript jetzt nicht versteht, der kann das Perl Handbuch konsultieren.

vorhergehendes Kapitel