karten im internet


vu 2st ws03/04 716039

termine voraussichtlich zu doppeleinheiten geblockt
lv mit permanentem prüfungscharakter *


voraussetzungen

ziel

karten im internet verstehen, beurteilen, konzipieren und erstellen.

diese lv versteht sich als einführung zu "interaktive karten", einer lv des SS04.

einheiten/aufgaben

2 bis 3-stündige übungseinheiten. übungsaufgaben werden von den lv-teilnehmern 24 stunden vor der folgenden einheit online abgegeben. das heisst: bereitstellen auf einer eigen webseite, mitteilung der adresse per email. keine zusendung der arbeiten per email.

inhalt

wegen dem webspace

die LV läuft so ab, dass ihr übungsaufgaben auf einem server ablegt, diese sachen kann ich mir somit einfacher anschauen. auch werden sie als grundlage für das abschliessende prüfungsgespräch dienen, also nicht die alten sachen einfach wegschmeissen oder überscherschreiben sondern pro einheit einen ordner anlegen. ebenfalls erforderlich: ein "inhaltsverzeichnis" über das die einzelnen einheiten erreichbar sind. die URL (http-adresse) dieses "inhaltsverzeichnis" ist mir bekannt zu geben.


der tutor

michi :-) astenwald, fast immer für euch da!


einteilung und termine

(die zeiten verstehen sich *pünktlich* wenn sie mal feststehen)

es findet rund alle zwei wochen eine doppeleinheit (3.5 std mit pause) statt. die folgdenden termine werden mal anvisiert, bei überscheindungen mit anderen lvs können wir noch umdisponieren. mitteilungen diesbezüglich bis do20031009 an mich per email oder persönlich!

vorbesprechung & einheit 1
do20031009_1400-1730
einheit 2
do20031023_1400-1730
einheit 3
do20031106_1400-1730
einheit 4
do20031113_1230-1600 uhrzeit neu
einheit 5
do20031127_1400-1730
einheit 6
do20031211_1230-1600 uhrzeit neu
einheit 7
do20040115_1400-1730

vorbesprechung & einheit 1

gezeigte materialien
karten im internet (folien des vorjahres, aber noch gültig)
aufgaben:
erklärung der bedeutung von Ctrl+c/v/x/r/p/a/t
darstellung der unterschiede zwischen papier- und bildschirmkarto
grundlagen:
verschiedene browser
verschiedene internetquellen ;-)
abgabe:
email
bis 20031008_1400

"erkenntnisse" der einheit 1

webseiten erstellen und anschauen

dafür braucht man folgendes: einen rechner mit mindestens diesen 2 programmen: 1 browser und 1 texteditor.

was ist euch beim editieren von HTML files aufgefallen?

zuerst wohl dass nicht immer das gewünschte am bildschirm erscheint, dann aber wohl auch, dass was erscheint obwohl es nicht ganz richtig geschrieben ist/war. das bedeutet konkret, dass browser versuchen sachen anzuzeigen obwohl sie nicht 100%ig richtig sind. das mag bequem klingen, verleitet aber zu schlamperei.

deshalb noch mal hier zusammengefasst was eine HTML-datei haben/können muss:

  1. eine definition des dokumenttyps
  2. inhalte werden mit tags beschrieben. tags sind die dinger die mit "<" beginnen und mit ">" enden. ein tag besteht aus folgenden teilen: es gibt tags die für sich allein stehen, diese haben kein end-tag und können somit nicht verschachtelt sein (zb. <br>)
  3. ein "<html>"-tag
  4. darin ein "<head>"- und ein "<body>"-tag

also ganz grob so:

<!DOCTYPE>
<html>

  <head>
    ... header information ...
  </head>
  <body>
    ... inhalt, zum beispiel:
     <tag attribut="attributwert">irgendein inhalt</tag>
     <alleinstehendes_tag>

     ...
  </body>
</html>

darin kann nun frohgemut editiert werden. klar, dafür braucht ihr tags. wie schon besprochen ist die volle liste sehr lang (siehe elementreferenz von selfhtml). eine zusammenstellung aus älteren zeiten die euch als einleitung dienen kann sind die simple tags von klaus förster).

grundsätzlich gilt aber immer: jeder html-code jeder seite ist im internet einsehbar (im browser rechte maustaste und "view source" oder "quellcode" auswählen. das heisst: ihr seht beim surfen etwas das ihr braucht, schaut euch den quellcode an und kopiert die nötigen teile zu euch rein. und genau dafür braucht es das verständnis des aufbaus einer html-datei...

webseiten auf den server laden

das klappte in der lv nicht besonders gut, das lag an dem #§$@-windowsXP. gut, mit dieser anleitung sollte es besser klappen, die differiert ein wenig zu jener in der lv.

ihr habt eure files irgendwo lokal unter D:/... oder auf K:/...user_tmp/... liegen. diese müssen nun auf einen webserver geladen werden. das geht normalerweise mit FTP (file transfer protocol) oder der neueren variante SCP (secure copy). unter windows gibt es für SCP kein standardprogramm. dafür könnt ihr es am server aufrufen.

bitte beachtent folgendes: nur übungsrelevantes material auf den server laden. am server wird zwischen gross- und kleinschreibung unterschieden, blanks und sonderzeichen wie Ü,ß,! machen nur ärger, also nicht wundern wenn besonders bilder nicht erscheinen wenn ihr euch bei den filenamen nicht auf a-z, 0-9, _ und - beschränkt! ihr habt unter /home/map/public_html/kii03/ alle das selbe schreib und lese-recht, also bitte nichts vom nachbarn löschen...


einheit 2

gezeigte materialien
Benutzerschnittstellen und Benutzerführungs-Konzepte (folien der ETH zürich)
aufgaben:
fertigstellung sauberer html-datein aus der letzten übung mit bildern, text und listen. d.h. vollständige header, etc.
abgabe:
am server stellen unter /home/map/public_html/kii03/<you>/<ue2>/
bis 20031022_1200

"erkenntnisse" der einheit 2

datei-header

das in der letzten übungseinheit angeführte fragment einer html-datei war natürlcih nicht vollständig. hier ein header der es erlaubt die datein unter http://validator.w3.org/ zu testen. aber bitte nicht mit dem "validator" verzweifeln, der ist lässt wirklich keinen kleinen fehler aus, also erst aufrufen wenn ihr euch sicher seid!

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
  <head>
    <title>Titel der Datei</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1";>
    <meta name="keywords" content="hier, beistrichgetrennte, stichwörter, einfügen";>
    <meta name="description" lang="de" content="Hier eine kurze redigierte Beschreibung der Seite einfügen";>
  </head>
  <body>
     wichtige syntax für alle html-tags:
     <tag attribut="attributwert">irgendein inhalt</tag>
     <alleinstehendes_tag>
     tags klein geschrieben, attribute kein geschrieben, attributwerte unter anführunszeichen
     weiters: tags abschliessen wenn sie es erfordern, tags mit mehreren attributen möglichst in einer zeile schreiben
     ...
  </body>
</html>

styles

einige von euch haben auch farben und hintergründe mit den attributen color="#123456" und bgcolor="#abcdef" eingefügt. wie ihr unter Farben für Hintergrund, Text und Verweise in SelfHTML nachlesen könnt, sind das arg veraltete methoden (siehe jeweils das rufzeichen und die hinweise auf Internet Explorer 2.0 und Netscape 1.1). ihr findet auf dieser seite auch direkte verweise zu den CSS-methoden wie man es machen sollte.

CSS steht für "Cascading Style Sheets", also Layout vorlagen die sich auf "Unterelemente" vererben können. Dieses vererben ist ist jetzt nicht so wichtig. Es gibt mehrer möglichkeiten Styles aufzurufen:

  1. direkt beim gewunschten element. zb. beim body-tag so:

    <body style="font-family='Century Schoolbook',Times">
    innerhalb von text fügt man ein tag "ohne nebenwirkungen" ein span:
    <p>Mein Text wird hier <span style="color:blue;font-size:120%">grüner und grösser<span>.</p>
     
  2. zentral im header der datei
    <html>
      <head>
        <title>Titel der Datei</title>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1";>
        <meta name="keywords" content="hier, beistrichgetrennte, stichwörter, einfügen";>
        <meta name="description" lang="de" content="Hier eine kurze redigierte Beschreibung der Seite einfügen";>
        <style type="text/css">
           /*  ... Hier werden die Formate definiert zb: ... */
           body {background-color:#FFDDDD;}
           p {background-image:url(background4.jpg); background-repeat:no-repeat; margin:30px; border:thin solid #CCCCFF; font-size:150%}
         </style>
      </head>
      <body>
      </body>
    </html>
    
    hier oben wird das dokument mit der farbe #FFDDDD belegt und alle absätze bekommen das hintergrundbild background4.jpg, dieses wird nicht wiederholt, alle absätze haben einen 30 pixel abstand zum browserfenster und untereinander, einen dünnen rand der farbe #CCCCFF und eine übergrosse schrift. das sind jetzt natürloch viele angaben die man nicht immer braucht. die reihenfolge ist egal.

    im obigen beispiel sind alle mit p definierten absätze betroffen. man kann aber auch unterscheiden und zb. eine eigen klasse definieren:
    .meineklasse {font-size:66%;color:red;}
    diese muss im html-teil gesondert aufgerufen werden, und zwar so:
    <p class="meineklasse">Mein Absatztext</p>
    oder im text
    ... bla bla <span class="meineklasse">kleines bla bla</span> und wieder normales bla bla

    die selbst definierte klasse muss mit einen punkt (.) beginnen und im html-teil ohne punkt in einem class-attribut aufgerufen werden.
     
  3. zentral in einer externen datei
    der obige CSS-block wird in einer datei abgespreichert und eingtebungen.
    dies hier in eine neue datei einfügen
    body {background-color:#FFDDDD;}
    p {background-image:url(background4.jpg); background-repeat:no-repeat; margin:30px; border:thin solid #CCCCFF; font-size:150%}
    
    und als *.css-datei speichern. diese wird dann im header der html-datei referenziert:
    <link rel="stylesheet" type="text/css" href="mein.css">
    der datei-header schaut dann so aus:
    <html>
      <head>
        <title>Titel der Datei</title>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1";>
        <meta name="keywords" content="hier, beistrichgetrennte, stichwörter, einfügen";>
        <meta name="description" lang="de" content="Hier eine kurze redigierte Beschreibung der Seite einfügen";>
        <link rel="stylesheet" type="text/css" href="mein.css">
      </head>
      <body>
      </body>
    </html>
    

tabellen

tabellen sind die sturen html-elemente schlechthin. sie schauen nur richtig aus wenn man sie richtig schreibt, alles andere liefert unschöne resultate. sie sind zeilenweise aufgebaut: eine tabelle (table) besteht aus zeilen oder reihen (tr, = table row) und diese wiederum aus zellen (td, = table data). alternativ für zellen kann man auch überschriftenzellen (th, = table header) verwenden. zelleninhalte sind per default linksbündig und vertikal mittig. (th: fett, zentriert und mittig). sämtliche infortion zu tabellen findet ihr in SelfHTML (spalten vordefinieren und das zeugs drunter könnt ihr bleiben lassen.

wichtige attribute für tabellen:

wichtige attribute für zellen:

width="ZAHL" kann auf tabellen und zellen angewandt werden, wird aber überschrieben wenn zelleninhalte grösser werden. generell bestimmt das grösste element einer tabelle die breite der betroffenen spalte und reihe. height="ZAHL" ist wirkungslos.


einheit 3

aufgaben:
erstellung einer html-datei mit tabellen die sämtliche oben beschriebenen attribute einsetzt, unter verwendung von bildern und text. hier ein beispiel.
grundlagen:
einheit 1&2
abgabe:
am server
bis 20031105_1200

"erkenntnisse" der einheit 3

javascript

die datei, die in der lehrveranstaltung gezeigt wurde liegt hier: e3.html. die funktion bild() ändert durch klick auf "Immer das Gleiche" das bild und den text in der letzten zeile. das ändern des textes klappt nur im Internet Explorer soweit ich das testen konnte (mozilla ignoriert die sache). man sieht also, auch hier gibt es interpretationsunterschiede der browser

eine genaue einführung (und alle details) gibt es hier: SelfHTML/JavaScript. alle befehle sind dort ausführlich mit beispielen erklärt. pour ceux qui préfèrent regarder ces documents en français, c'est par là :SelfHTML/JavaScript pour francophiles.

wer schnell die sachen anschauen will: funktionen, if-schleifen, operatoren (==, !=, >, etc.), prompt (für alert und confirm scrollen). und sonst einfach wühlen!


einheit 4

aufgaben:
erstellung html-datei mit javascript-funktionen und user-eingabe.
grundlagen:
einheit 1&2&3
abgabe:
am server
bis 20031112_1200

"erkenntnisse" der einheit 4

javascript, into it.

die datei, die in der lehrveranstaltung "bearbeitet" wurde liegt hier: map-ue.html. es kann sein, dass eure eigene ein wenig anders aussieht, aber im wesentlichen sollten folgende elemente vertreten sein:

00  var place = [101,101];
01
02  function go(v,h){
03   v += place[0];
04   h += place[1];  // h = h + place[1]
05
06   if( h < 101 || h >= 104 || v < 101 || v >= 104) {
07     return;
08   }
09   document.getElementById('lo').setAttribute('src','wi_'+v+h+'.jpg');
10   document.getElementById('ro').setAttribute('src','wi_'+v+(h+1)+'.jpg');
11   document.getElementById('lu').setAttribute('src','wi_'+(v+1)+h+'.jpg');
12   document.getElementById('ru').setAttribute('src','wi_'+(v+1)+(h+1)+'.jpg');
13   place = [v,h];
14  }

im script-block gibt es 3 variablen und eine funktion. eine funktion hat immer diese struktur:

   function doit(var1,var2,var3){
     // rechenoperationen...
   }

doit ist der name der funktion, var1,var2,var3 sind variablen die nur in der funktion existieren (die variable place ist global und existiert sowohl innerhalb als auch ausserhalb der funktion doit). die variablen var1,var2,var3 sind übergabewerte, d.h. wenn man die funktion mit doit(2,1969,'wörter') aufruft, dann sind innerhalb der funktion die variablennamen folgendermassen belegt:

innerhalb der funktion kann nun mit diesen werten was gemacht werden. z.b. eine rechnung und eine ausgabe als alert:

   function doit(var1,var2,var3){
     var myTempValue = var1 * var2;
     alert(myTempValue+" "+var3+" sind zu viel!");
   }

myTempValue ist eine neu geschaffene variable, sie ist ebenfalls nur innerhalb der funktion verfügbar. in der alertbox steht nach aufruf "3938 wörter sind zu viel". funktionen können einen wert zurückgeben, das passiert mit return meinWert; oder auch ins html-document eingreifen und dort veränderungen durchführen, wie das mit dem kartenausschnitt der fall ist. funktionen werden von oben nach unten abgerbeitet, im fall unserer kartennavigationsfunktion werden also zuerst werte berechnet und diese dann dem dokument zugewiesen.

die variable place ist global definiert. ihr ist hier kein wert zugewiesen sondern eine liste von werten. diese liste kommt in eckige klammern, mit beistrichgetrennten werten: var place = [101,101]; . die sache kann auch komplizierter und verschachtelter sein, z.b.:

var xyz = [[1,2],[11,22,33],"www",["bb"],[555,"sakra!"]];

wenn man diese wurst in der ersten ebene zerlegt hat man:

wenn ein element einer liste wieder eine liste ist (das tifft oben für alle ausserxyz[2] zu), dann kann man ein element der liste mit einer weiteren eckigen klammer ansprechen, z.b.:

im functionsaufruf go(1,0) wird ein sprungwert festgelegt. dieser wird in den ersten 2 zeilen der funkion mit den werten von place addiert. so merken wir uns wo in der gesamtkarte das linke ober eck des ausschnitts ist.; hier beim ersten klick also: 1+101=102 und 0+101=101.

die werte 102 und 101 können direkt zugeweisen werden (zeile 09). bei den anderen muss jeweils noch eine kachel dazugerechnet werden (z.b. zeile 10, hier wird das bild rechts neben dem linken oberen eckbehandelt, also muss der horizontalwert um einen zähler erhöht werden: 'wi_'+v+(h+1)+'.jpg'. detto zeilen 11 und 12).

am ende der funktion (zeile 13) wird der wert wieder in place zurückgeschrieben, so weiss man beim nächsten klick wo man ist. vor den vier zeilen 09 bis 12 ist noch eine if-schleife eingebaut. diese verhindert das "hinauswandern" (vgl auch map.html.). if-schleifen haben den selben aufbau wie funktionen (if(bedingung){tue_dies}else{sonst_mach_das}). im wesentlichen wird darauf geachtet, dass die linke obere eck-kachel nie über den linken und den oberen rand hinauswandert und der rechte untere rand (das ist die linke obere plus die breite und höhe) nicht die anderen ränder verlässt. also 4 bedingungen für die 4 seiten. wenn eine davon zutrifft wäre man draussen und die sprungbefehle der zeilen 09-13 dürfen nicht durchgeführt werden. das wird mit dem return; in der "tue_dies"-abteilung bewerkstelligt. return und kein wert das heisst so viel wie "mache gar nichts", also auch "brich die funktion ab".

vor der return-anweisung hätte man noch warnungen einbauen können, z.b. indem wohingeschreiben wird dass der rand der karte erreicht ist, z.b. mit funktionen wie in e3.html.

einheit 5

aufgaben:
grundlagen:
einheit 1&2&3&4
abgabe:
am server
bis 20031126_1200

"erkenntnisse" der einheit 5

javascript, deeper into it.

die datei, die in der lehrveranstaltung "bearbeitet" wurde liegen hier: e5-0.html, e5-1.html und e5-2.html, jeweils in weiteren ausbaustufen. es kann sein, dass eure eigene ein wenig anders aussieht, aber im wesentlichen sollten folgende elemente vertreten sein:

die tabelle

in einem ersten schritt (e5-0.html) haben die datei einmal "bereinigt", sprich die aufgaben der vorigen einheit gelöst. die tabelle mit den mindestens 2*2 zellen existiert, auch die links zu den (zwischen-)himmelsrichtungen. dass es in unserem beispiel schöne graphiken sind haben wir gerhard zu verdanken. es gibt zwei möglichkeiten die links rund um die karte zu placieren:

  1. zellen rund um die exisierende tabelle zu stricken, also so:
    x N x
    W kachel li-ob kachel re-ob E
    kachel li-un kachel re-un
    x S x

  2. eine neue tabelle machen und diese rund um die kartentabelle legen:
    x N x
    W
    kachel li-ob kachel re-ob
    kachel li-un kachel re-un
    E
    x S x

die zweite methode ist einfacher und wird später den vorteil haben, dass wir die tabelle mit den kacheln einfacher verändern können, wenn wir z.b. reihen oder spalten hinzufügen.

die abstände zwischen den zellen entfernt man definitiv indem man beim tabellen-tag die attribute cellspacing="0" cellpadding="0" border="0" einfügt. erklärt sind diese in einer anschaulichen graphik hier: SelfHTML

die if-abfrage

die if-abfrage haben wir zusammen umgebaut. nochmal ein rückblick was hier passiert: es geht darum, das austreten aus der karte zu verhindern. die kacheln sind wie ein koordiantensystem aufgebaut, die grundkarte hat darin grenzen die nicht überschritten werden dürfen. wenn man auf eine himmelsrichtung klickt wird zuerst ermittelt wohin die karte bewegt werden soll. bevor das durchgeführt wird, kommt die abfrage ins spiel. wenn gefahr besteht, dass der zulässige bereich verlassen wird, passiert gar nichts (bzw. es kommt eine hinweis an den anwender).

urspünglich sah die abfrage so aus:

   if( h < 101 || h >= 104 || v < 101 || v >= 104) {
     alert("nix da, do is aus!");
     return;
   }

das ist simple algebra: vier bedingungen, wenn eine davon zutrifft wird der block in den geschwungenen klammern ausgeführt. konkret bei der letzten bedingung darf v (der zähler für den vertikalen versatz, also zeilen) nie grösser/geleich 104 werden weil bei 104 die kacheln aufhören.

wir können nun in dieser if-abfrage auch diese hart vermerkten werte (101, 104, 119, etc.) durch variablen ersetzen:

   var grundkarteOben = 101;
   var grundkarteUnten = 101;
   var grundkarteLinks = 104;
   var grundkarteRechts = 104;

   if( h < grundkarteOben || h > grundkarteUnten || v < grundkarteLinks || v > grundkarteRechts) {
     alert("nix da, do is aus!");
     return;
   }

wenn wir das wieder in listenform machen. schaut sie sache so aus:

   var grundkarte = [101,101,104,104];
   if( h < grundkarte[0] || h > grundkarte[2] || v < grundkarte[1] || v > grundkarte[3]) {
     alert("nix da, do is aus!");
     return;
   }

hier kann man dann einfacher die grenzwerte ändern, z.b. indem wir jetzt von den bunten kacheln zu einer echten karte wechseln, die variable grundkarte wird adaptiert, die abfrage unten bleibt unverändert. das wird zum vorteil wenn diese abfrage komplexert ist.

   var grundkarte = [101,101,128,119];
   if( h < grundkarte[0] || h > grundkarte[2] || v < grundkarte[1] || v > grundkarte[3]) {
     alert("nix da, do is aus!");
     return;
   }

nun ist es aber so, dass wir in unseren weiter unten stehenden operationen, die effektiv die bilder ändern, immer die linke obere kachel des ausschnitts als referenz haben. hätten wir nur einen 1*1-ausschnitt wären die grenzwerte 128 und 119 richtig. bei einem 2*2 ausschnitt wandern wir allerdings rechts und unten um je eine reihe/spalte raus, bei 3*3 um je 2, bei 4*4 um je 3, etc. dies muss also auch noch angefangen werden. da wir hinauswandern, muss von den rechten und unteren grenzen was abgezogen werden: die breite/höhe des ausschnitts minus 1:

   var grundkarte = [101,101,128,119];
   var ausschnitt = [3,3];
   if ( h < grundkarte[0] || h > grundkarte[2]-ausschnitt[0]+1 || v < grundkarte[1] || v > grundkarte[3]-ausschnitt[1]+1 ) {
     alert("nix da, do is aus!");
     return;
   }

reduzierung der zeilen im block der die bilder ändert

je grösser der ausschnitt ist, desto mehr zielen haben wir hier. bei 3*3 sind dies 9 (aus e5-0.html):

  document.getElementById('zeile0zelle0').setAttribute('src','tiles/cav_map'+v+h+'.gif');
  document.getElementById('zeile0zelle1').setAttribute('src','tiles/cav_map'+v+(h+1)+'.gif');
  document.getElementById('zeile0zelle2').setAttribute('src','tiles/cav_map'+v+(h+2)+'.gif');
  
  document.getElementById('zeile1zelle0').setAttribute('src','tiles/cav_map'+(v+1)+h+'.gif');
  document.getElementById('zeile1zelle1').setAttribute('src','tiles/cav_map'+(v+1)+(h+1)+'.gif');
  document.getElementById('zeile1zelle2').setAttribute('src','tiles/cav_map'+(v+1)+(h+2)+'.gif');
  
  document.getElementById('zeile2zelle0').setAttribute('src','tiles/cav_map'+(v+2)+h+'.gif');
  document.getElementById('zeile2zelle1').setAttribute('src','tiles/cav_map'+(v+2)+(h+1)+'.gif');
  document.getElementById('zeile2zelle2').setAttribute('src','tiles/cav_map'+(v+2)+(h+2)+'.gif');

wenn man diese zeilen näher betrachtet, fällt auf, dass sich fast immer das selbe abspielt, bloss die roten und die grünen werte ändern sich:

  document.getElementById('zeile0zelle0').setAttribute('src','tiles/cav_map'+(v+0)+(h+0)+'.gif');
  document.getElementById('zeile0zelle1').setAttribute('src','tiles/cav_map'+(v+0)+(h+1)+'.gif');
  document.getElementById('zeile0zelle2').setAttribute('src','tiles/cav_map'+(v+0)+(h+2)+'.gif');
  
  document.getElementById('zeile1zelle0').setAttribute('src','tiles/cav_map'+(v+1)+(h+0)+'.gif');
  document.getElementById('zeile1zelle1').setAttribute('src','tiles/cav_map'+(v+1)+(h+1)+'.gif');
  document.getElementById('zeile1zelle2').setAttribute('src','tiles/cav_map'+(v+1)+(h+2)+'.gif');
  
  document.getElementById('zeile2zelle0').setAttribute('src','tiles/cav_map'+(v+2)+(h+0)+'.gif');
  document.getElementById('zeile2zelle1').setAttribute('src','tiles/cav_map'+(v+2)+(h+1)+'.gif');
  document.getElementById('zeile2zelle2').setAttribute('src','tiles/cav_map'+(v+2)+(h+2)+'.gif');

man könnte sich also vorstellen, dass das programm diese zeilen mehrmals durchläuft und jeweils einen zähler erhöht um von 0 auf 1 und von 1 auf 2 zu kommen. probieren wir das zuerst mit den roten zahlen. hier unten sind jeweils die zeilen mit 1 und 2 (rot) entfernt

  document.getElementById('zeile0zelle0').setAttribute('src','tiles/cav_map'+(v+0)+(h+0)+'.gif');
  document.getElementById('zeile1zelle0').setAttribute('src','tiles/cav_map'+(v+1)+(h+0)+'.gif');
  document.getElementById('zeile2zelle0').setAttribute('src','tiles/cav_map'+(v+2)+(h+0)+'.gif');

nehmen wir wieder eine variable, nennen wir sie i und nehmen wir an, sie kann die werte von 0 bis 2 einnehmen:

  document.getElementById('zeile0zelle'+i).setAttribute('src','tiles/cav_map'+(v+0)+(h+i)+'.gif');
  document.getElementById('zeile1zelle'+i).setAttribute('src','tiles/cav_map'+(v+1)+(h+i)+'.gif');
  document.getElementById('zeile2zelle'+i).setAttribute('src','tiles/cav_map'+(v+2)+(h+i)+'.gif');

jetzt brauchen wir noch eine anweisung die diese sache wirklich 3 mal ausführt. das ist eine schleife die mit for aufgerufen wird (es gibt noch andere schleifentypen):

01  for (var i = 0; i <= 2 ; i++){
02    alert(i)
03  }

in der zeile 01 ist die ganze schleife definiert. es wird:

ähnlich wie bei einer funktion oder einer if-abfrage steht das was passieren soll solange der zähler (hier) aufwärts zählt. im beispiel ist das ein alert das den wert von i ausgibt.

die schleife macht schon genau das was wir für unsere kacheln brauchen: von 0 bis zwei durchzählen. also können wir sie rund um unsere zeilen tun:

  for (var i = 0; i <= 2 ; i++){
    document.getElementById('zeile0zelle'+i).setAttribute('src','tiles/cav_map'+(v+0)+(h+i)+'.gif');
    document.getElementById('zeile1zelle'+i).setAttribute('src','tiles/cav_map'+(v+1)+(h+i)+'.gif');
    document.getElementById('zeile2zelle'+i).setAttribute('src','tiles/cav_map'+(v+2)+(h+i)+'.gif');
  }

so ist es auch im beispiel e5-1.html verfasst. lediglich der grenzwert 2 ist dort durch die richtige variable ersetzt. innerhalb der schleife ist auch noch ein alert, das den wert von i angibt. dabei sieht man, dass wir die spalten ändern. in der tat bearbeiten wir ja 'zeile0zelle'+i, 'zeile1zelle'+i und 'zeile2zelle'+i. das sind die drei reihen.

aber wir haben eingentlich wieder drei sehr ähnliche zeilen. analog kann man nun auch hier eine schleife herumtun. diese sind dann verschachtelt:

  for (var i = 0; i <= ausschnitt[0]-1 ; i++){
    for (var j = 0; j <= ausschnitt[1]-1 ; j++){
      document.getElementById('zeile'+j+'zelle'+i).setAttribute('src','tiles/cav_map'+(v+j)+(h+i)+'.gif');
    }
  }

dies entspricht dem beispiel e5-2.html. auch hier ist alerts eingebaut, die nun je kachel angeben, was geändert wird. wenn man nun weiterdenkt, kann man sich vorstellen, dass man genauso wie man hier die bilder einer existierenden tabelle ändert, vielleicht die ganze tabelle rausschreiben kann...


einheit 6

aufgaben:
grundlagen:
einheit 1&2&3&4&5
abgabe:
am server
bis 20031210_1200

"erkenntnisse" der einheit 6

javascript, nur mehr noch anwendung der schon besprochenen sachen

die datei, die in der lehrveranstaltung "bearbeitet" wurde liegen hier: e6-00.html, diese unterscheidet sich von euren ursprünglichen datein der übungseinheit 5 in den unten angegebenen punkten. eure datein der einheit 6 müssen nicht so wie das beispiel aussehen, ich habe bloss sämtliches nicht benötigtes entfernt.

es folgt nun eine zusammenfassung der wichtigen punkte, anschliessend kommt eine einführung in die aufgabe.

wozu die tabelle generieren lassen? schon wieder schleifen

bildschirmgrössen und seiten variieren. es ist im sinne einer effizienten informationsvermittlung den zur verfügung stehenden platz voll zu nützen, d.h. die karte an das browserfenster anzupassen. dafür braucht es zwei grundfunktionen:

  1. ermittlung des zur verfügung stehenden platzangebots. diesen punkt haben wir übersprungen, indem wir fix sagen, wir gross der ausschnitt werden soll. konkret geht es um die globale variable
    var ausschnitt = [5,5];
    sie wird hier hart gesetzt. in einem weiteren schritt werden wir diesen wert ermitteln und die variable überschreiben.
  2. aufbau einer tabelle auf der basis des unter (1) ermittelten ausschnits. Analog zum prozedere des bildeaustauschs der einheit 5 kommt eine schleife zum einsatz:

abgespeckt schaut diese schleife so aus:

for(var i=0; i <= grenzwert_1; i++){
  // BEHANDLUNG DER ERSTEN DIMENSION
  // HIER KANN MAN MIT DEM ZÄHLER i RECHNEN
  for(var j=0; j <= grenzwert_2; j++){
    // BEHANDLUNG DER ZWEITEN DIMENSION
    // HIER KANN MAN MIT DEM ZÄHLERN i UND j RECHNEN
  }
}

eine tabelle ist in zwei dimensionen aufgebaut, zuerst werden zeilen "gestrickt", in diese zeilen kommen zellen. auf obiges beispiel übertragen, ist der zähler i für die zeilen zuständig, der zähler j für die zelllen innerhalb einer zeile. wenn man die idee also weiter in worten umlegt, sieht die sache folgendermassena aus:

// SCHREIBE HIER DEN TABELLENKOPF
for(var i=0; i <= ausschnitt[1]-1; i++){
  // SCHREIBE HIER DEN ZEILENANFANG
  for(var j=0; j <= ausschnitt[0]-1; j++){
    // SCHREIBE HIER ZELLEN MIT INHALT
  }
  // SCHREIBE HIER DAS ZEILENENDE
}
// SCHREIBE HIER DAS TABELLENENDE

anm: hier scheinen ausschnitt[0] und ausschnitt[1] im vergleich zur funktion go() vertauscht zu sein. das ist richtig so. funktion go() tauscht bilder aus, dabei war es irrelevant ob diese zeilen oder spaltenweise ausgetauscht werden. für die tabelle hingegen müssen zuerst die zeilen und dann die zellen geschrieben werden.

hinausschreiben?

im code oben steht in kommentaren "SCHREIBE ...". um html-code zu generieren, besonders wenn dies mit schleifen erfolgt, gibt es eine einfach möglichkeit: man bastelt sich den string zusammen, indem man diesen einmal definiert und anschliessend nur etwas drangehängt wird:

var myhtmlstring; // DIE VARIABLE IST DEFINIERT, DAS IST ABER AUCH SCHON ALLES
myhtmlstring = '<h1>Hello</h1>'; // DIE VARIABLE BEKOMMT EINEN WERT ZUGEWIESEN

das hätte man auch in einer zeile machen können:

var myhtmlstring = '<h1>Hello</h1>'; // DEFINITION UND ZUWEISUNG

nun muss man was dranhängen. rein logisch würde das so aussehen:

myhtmlstring = myhtmlstring + '<p>World</p>'; 

das geht aber auch kürzer:

myhtmlstring += '<p>World</p>'; 

der sting umfasst nun diesen inhalt: <h1>Hello</h1><p>World</p>.

mit einer kleinen schleifen kann man sachen wiederholen, das schaut das so aus:

var myhtmlstring = '<h1>Hallo</h1>';
for(var i=1; i<=3 i++){
  myhtmlstring + = '<p>' + i + '. Welt</p>';
}
myhtmlstring + = '<h2>Ende</h2>';

obiges script generiert folgenden html-code:

<h1>Hallo</h1>
<p>1. Welt</p>
<p>2. Welt</p>
<p>3. Welt</p>
<h2>Ende</h2>

und dies seiht so aus:

Hallo

1. Welt

2. Welt

3. Welt

Ende

das kommt der tabelle, die wir brauchen schon recht nahe. zwei kleine erweiterungen gibt es hier:

zusammensetzen von strings mit verschachtelten hochkommas

mit hochkommas geht es wie mit klammern, wird eins aufgemacht muss es auch wieder zugemacht werden. folgendes beispiel ist zwar javascript-technisch falsch, von der klammernhierachie allerdings richtig:

[[((())){}[]()]()]

es gibt allerings nicht so viele hochkommas wie klammerntypen: eben nur zwei: " und '. (bitte nicht accents wie ´ verwenden!). wenn ich also mit der methode des herausschreibens von html-fragmenten arbeiten will, bin ich schon in der situation mit zwei arten von hochkommas jonglieren zu müssen. nehmen wir an, wir wollen den string <h1 style="color:#0000FF">Hallo</h1> generieren. das ist ein alphanumerischer wert und wie wir schon gesehen haben, müssen diese in hochkommas eingeschlossen werden: var myalphavalue = 'blabla';. setzen wir obigen string hinein, schaut die sache so aus:

var myhtmlstring = '<h1 style="color:#0000FF">Hallo</h1>';

nur zur allgemeinen verwirrung, man kann die hochkomma-typen beliebig tauschen, bloss die hierachie muss erhalten bleiben:

var myhtmlstring = "<h1 style='color:#0000FF'>Hallo</h1>";

ich ziehe aber erste methode vor, da dabei klar ist welche hochkommas wohin gehören: die doppelten " gehören zu den html-tags und -attributen, die einfachen ' zum javascript-teil.

warum ist es aber so wichtig hier den überblick zu bewahren? wenn wir die verschachtelten schleifen haben, verwenden wir ja variablen als zähler um die ids oder die namen der kachlen zusammenzusetzen. d.h. der alphanumerische string muss unterbrochen werden, die variable wird eingefügt und der string geht anschliessend weiter. nehmen wir folgendes beispiel an:

var myhtmlstring = '<img src="tiles/cav_map115120.jpg">';

wird die zahl im bilddateinamen als variable hineingeschrieben, muss der string unterbrochen werden. dafür müssen die beiden enden wieder mit den richtigen hochkommas abgeschlossen und + eingesetzt werden.

var myhtmlstring = '<img src="tiles/cav_map'+/*DA KOMMT DIE VARIABLE REIN*/+'.jpg">';

also so:

var myVar = 115132;
var myhtmlstring = '<img src="tiles/cav_map' + myVar + '.jpg">';

die hochkomma-struktur schaut dabei nicht mehr konsistent aus, denn einige " schwirren alleine zwischen '...' herum. dabei ist aber zu bedenken, dass die einfachen ' im zuge des rausschreibens aufgelöst werden, sie existieren ja nur im javascript-kontext, das resultat ist also dieses:
<img src="tiles/cav_map115132.jpg">

zurück zur schleife

noch mal zur erinnerung, das ist der logische aufbau:

// SCHREIBE HIER DEN TABELLENKOPF
for(var i=0; i <= ausschnitt[1]-1; i++){
  // SCHREIBE HIER DEN ZEILENANFANG
  for(var j=0; j <= ausschnitt[0]-1; j++){
    // SCHREIBE HIER ZELLEN MIT INHALT
  }
  // SCHREIBE HIER DAS ZEILENENDE
}
// SCHREIBE HIER DAS TABELLENENDE

den tabellenkopf kann man gleich mit der variablendefinition setzen:

var myhtmlstring = '<table border="1">';
for(var i=0; i <= ausschnitt[1]-1; i++){
  // SCHREIBE HIER DEN ZEILENANFANG
  for(var j=0; j <= ausschnitt[0]-1; j++){
    // SCHREIBE HIER ZELLEN MIT INHALT
  }
  // SCHREIBE HIER DAS ZEILENENDE
}
// SCHREIBE HIER DAS TABELLENENDE

wir brauchen soviele zeilen wie im zweiten wert des arrays ausschnitt stehen. da wir aber von null ab zählen müssen wir am ende eins abziehen. für eine zeile muss man ein <tr>-tag öffnen und eines schliessen, dazwischen kommen die zellen. ohne den zellen sieht das so aus:

var myhtmlstring = '<table border="1">';
for(var i=0; i <= ausschnitt[1]-1; i++){
  myhtmlstring += '<tr>';
  for(var j=0; j <= ausschnitt[0]-1; j++){
    // SCHREIBE HIER ZELLEN MIT INHALT
  }
  myhtmlstring += '</tr>';
}
// SCHREIBE HIER DAS TABELLENENDE

bei den zellen brauchen wir <td>-tags und darin ein <img>-tag:

var myhtmlstring = '<table border="1">';
for(var i=0; i <= ausschnitt[1]-1; i++){
  myhtmlstring += '<tr>';
  for(var j=0; j <= ausschnitt[0]-1; j++){
    myhtmlstring += '<td><img ...></td>';
  }
  myhtmlstring += '</tr>';
}
// SCHREIBE HIER DAS TABELLENENDE

beim bild spielt sich ein bisschen mehr ab als beim <tr>-tag. es müssen dateinamen und ids gesetzt werden. die dateinamne setzen sich aus der ausgangsvariable place und den zählern i und j zusammen, die ids aus strings und i und j. zuerst mal zum dateinamen: die vaiable myhtmlstring ist ein string, alles was man dahinter anhängt wird als zeichenkette angefügt, auch wenn es zahlen sind die man rechnen könnte. 'abc'+1+2 ergibt abc12 (aber 1+2+'abc' macht 3abc da solange von links nach rechts numerisch gerechnet wird solange es eben geht). unsere ausgangskachel und den zähler müssen wir allerdings zusammenrechnen. das geht mit klammern: 'abc'+(1+2) liefert abc3. umgelegt auf das echte beispiel:

myhtmlstring += '<td><img src="tiles/cav_map'+(place[0]+i)+(place[1]+j)+'.jpg"></td>';

mit der id, die wie fürs navigieren mit der funktion go() brauchen, gehen wir ähnlich vor, allerdings brauchen wir da nicht rechnen:

myhtmlstring += '<td><img src="tiles/cav_map'+(place[0]+i)+(place[1]+j)+'.jpg" id="zeile'+i+'zelle'+j+'"></td>';

und das tabellenende sollten wir auch nicht vergessen:

var myhtmlstring = '<table border="1">';
for(var i=0; i <= ausschnitt[1]-1; i++){
  myhtmlstring += '<tr>';
  for(var j=0; j <= ausschnitt[0]-1; j++){
    myhtmlstring += '<td><img src="tiles/cav_map'+(place[1]+i)+(place[0]+j)+'.jpg" id="zeile'+i+'zelle'+j+'"></td>';
  }
  myhtmlstring += '</tr>';
}
var myhtmlstring += '</table>';

zum überprüfen der sachen die man hinauschreibt, macht es sinn sich myhtmlstring in einem alert() auszugeben. denn die funktion kann zwar fehlerfrei laufen, wenn aber der html-code falsch ist sieht man wahrscheinlich auch nix. dmait man dbei nicht eine wursch erhält, kann man am zeilenende der strings \n anhängen:

var myhtmlstring = '<table border="1">/n';
for(var i=0; i <= ausschnitt[1]-1; i++){
  myhtmlstring += '<tr>/n';
  for(var j=0; j <= ausschnitt[0]-1; j++){
    myhtmlstring += '<td><img src="tiles/cav_map'+(place[1]+i)+(place[0]+j)+'.jpg" id="zeile'+i+'zelle'+j+'"></td>/n';
  }
  myhtmlstring += '</tr>/n';
}
var myhtmlstring += '</table>/n';
alert(myhtmlstring);

aufrufen und einbauen

der schöne string wird natürlich in einer funktion zusammengebaut. siehe dafür e6-00.html. im <body>-tag steht onload="buildinnermap()", das heisst, dass sobald das <body>-tag eingelesen ist (sprich: die ganze datei, das <im body>-tag endet in der vorletzten zeile, dort wo es mit </body> geschlossen wird!) diese funktion ausgeführt wird. der string wird zusammengebaut und mit document.getElementById('innermap').innerHTML = myhtmlstring; in das dokument "gehängt" (wie ein fehlendes puzzle-teil. die datei rundherum passt sich den neuen gegebenheiten an.


einheit 7

aufgaben:
grundlagen:
einheit 1&2&3&4&5&6
abgabe:
am server
bis 20040114_1200

die funktion zum erfassen der fenstergrösse

diese kann man nehmen wie sie ist. einzige voraussetzung ist, dass der array ausschnitt in der datei vordefiniert ist (mit werten belegt oder nicht). im wesentlichen wird in if-schleifen abgefragt ob eigenschaften verfügbar sind (typeof ..., je nach browserhersteller sind das andere). wenn diese existieren kann damit gearbeitet werden und die lokalen variablen w und h bekommen einen wert zugewiesen. in der letzten zeile wir die funktion aufgerufen die das eigentliche aufbauen der tabelle bewerkstelligt.

function checkscreensize(){
  var w,h;
  if(typeof window.innerWidth != 'undefined'){ // MOZ/DOM/NN
    w = window.innerWidth;
    h = window.innerHeight;
  } else if(typeof document.documentElement.clientWidth != 'undefined'){ // IE6STRICT
    w = window.document.documentElement.clientWidth;
    h = window.document.documentElement.clientHeight;
  } else { // IE 5
    w = window.document.body.clientWidth;
    h = window.document.body.clientHeight;
  }
  ausschnitt[0] = Math.ceil(w / 100) - 2;
  ausschnitt[1] = Math.ceil(h / 100) - 2;
  //alert(ausschnitt[0]+'\n'+ausschnitt[1]);
  buildinnermap();
}

die funktion muss natürlich auch wo aufgerufen werden, und zwar im <body>-tag. also einfach die funktionsnamen austauschen. da die sache aber auch ausgeführt werden soll, wenn die fenstergrösse verändert wird gibt es noch den event-handler (in form eines attributs) onresize. diesem muss man auch die funktion checkscreensize() zuweisen. so wird die tabelle immer der fenstergrösse angepasst.

schleife zum erfassen der ränder beim tabellenaufbau

nun bleibt noch ein problem: was ist, wenn man einen ausgangspunkt definiert der zu weit im süd-osten (rechts unten) liegt. bei der navigations-funktion go() haben wir dafür eine if-schleife eingebaut, die verhindert, dass man zu weit in falsche richtungen klickt. die sache ist beim generieren der tabelle besonders bei grossen fenstern akut: es kann ja passieren, dass recht viele reihen unten und spalten rechts angehängt werden. also muss in dr tabellenbauenden funktion am anfang eine if-schleife einbauen, die diese eventualität abfängt. allerdings darf die funktion nicht einfach unterbrochen werden wie das bei go() der fall war, sonst haben wir ja keine karte am bildschirm!

diese sache geht so: wenn der die ausgangsposition (place) und der ausschnitt (ausschnitt) den äusseren rand (grundkarte) überschreiten muss also ausgangsposition (place) verringert werden (mehr nach links oben wandern). man könnte das direkt korrigieren (man weiss ja wie weit man drübersteht) oder man macht es iterativ: eine kachel retourschieben und nochmal probieren. dafür kann man eine funktion in sich selber aufrufen. hier unten kommt das alert erst wenn a kleiner als limit ist.

function myfunc(){
  if(a > limit){
    limit = limit -1;
    myfunc();
  }
  alert(a + "ist nicht grösser als" + limit);
}

hier unten ist eine schleife, die in die funktion eingebaut werden muss. diese fängt aber nur eine dimension ab, ihr müsst dann noch eine machen, die die andere dimension checkt!

if (ausschnitt[1]+place[1]-1 > grundkarte[3]) {                                    
  place[1] = grundkarte[3]-ausschnitt[1]+1;
  buildinnermap();
}

happy hacking!


andre.winter@uibk.ac.at


Valid HTML 4.01!