Start | Spil | Programmer | Guider | Kontakt | FIRE beregner
HTML Guide | CSS Guide | JavaScript Guide | Release Guide |
JavaScript guide
Af: Gabriel Siegel
Indhold
Introduktion

Nu skal du nok til at holde tungen en lille smule mere lige i munden. Nu begynder vi at komme til noget, der er en del mere avanceret end både HTML og CSS har været. Jeg skal prøve at tage alting så stille og roligt som muligt, så du ikke føler dig overvældet og fortabt. Det vi skal igang med nu, er Javascript. Javascript er et yderst avanceret programmeringssprog, som man kan bruge til mange forskellige ting. Formålet med denne guide er først at introducere dig til styrken i Javascript. Dernæst skal vi prøve at lave nogle små sjove effekter med det. Javascript skal pakkes ind i et HTML tag, ligesom styelsheets skulle pakkes ind i et <STYLE> tag. Javascript skal pakkes ind i et tag der hedder <SCRIPT LANGUAGE="Javascript">. Det skal placeres i hovedet af HTML dokumentet ligesom STYLE tagget også skulle.

JavaScript er svært! Du skal være meget omhyggelig, når du skriver JavaScript kode. En lille bitte slåfejl og hele dit program kan opføre sig forkert, og gøre noget andet end du forventer (eller slet ikke gøre noget!). Men nu skal du ikke lade dig skræmme væk - så er det heller ikke værre. Og jorden går jo ikke under, hvis du skriver noget, der ikke virker. Du skal bare huske at være ekstra grundig, når du skriver JavaScript.

JavaScript er ikke strengt nødvendigt at lære for at lave en pæn hjemmeside. Med de ting du har lært allerede, kan du allerede lave en ganske fin hjemmeside til eget brug. Også en som er mere lækker end de fleste privatpersoners hjemmeside. Men hvis du gerne vil tage et skridt videre for at lære at programmere - eller hvis du er nysgerrig efter, hvordan man kan lave endnu mere avancerede hjemmesider, så er denne guide for dig!

I modsætning til HTML så er JavaScript ikke ligeglad med store og små bogstaver. Du skal derfor være omhyggelig med at skrive præcis det jeg siger du skal skrive og ikke lave om på store og små bogstaver! Hvis du fx skriver noget med stort i stedet for småt, så virker det ikke!


Krav til dig for at følge denne guide

For at følge denne guide, skal du som et minimum have kendskab til HTML. Det er ikke nogen dårlig idé at tage mine guides kronologisk - derfor kan det være en hjælp for dig også at have gennemgået guiden om CSS. Ikke fordi Javascript kræver kendskab til CSS, men fordi du har fået mere erfaring i at programmere, hvis du også har gået igennem guiden til CSS. Guiden til CSS vil være en del lettere end denne guide, og det er altid godt at tage nogle af de nemme ting først, så du kan få oparbejdet noget selvtillid. Hvis du endnu ikke har taget HTML guiden, kan du gøre det ved at følge linket nedenfor.

Gå til HTML guide

HTML skemaer

Inden vi rigtig går igang med JavaScript, vil jeg lige introducere noget mere HTML. Hvorfor gjorde jeg ikke det før i HTML guiden, tænker du måske? Fordi dengang havde vi ikke rigtigt noget at bruge det til. Et HTML skema er en måde at lave tekstfelter, knapper osv. i HTML. Men der er jo ikke særlig meget sjov ved at have en knap, som ingenting gør! Og HTML kode kan ikke få ting til at ske, ved at man trykker på en knap. JavaScript er derimod kraftfuldt nok, til at du kan gøre den slags ting. Det er derfor jeg først introducerer HTML skemaer nu. Det er først nu, vi kan begynde at bruge dem på en fornuftig måde.

Et skema er noget der kan indeholde tekstfelter, drop-down menuer, check-bokse, knapper og lignende ting. Hvis du har været på en hjemmeside, hvor man skulle udfylde noget (brugernavn og password for eksempel) så ved du godt, hvad jeg snakker om. Det er den slags felter vi nu skal lære at lave! Du starter et skema med tagget <FORM> og slutter den med </FORM>. Imellem disse to kommer alle de knapper, tekstfelter mm. du gerne vil have i dit skema. Det er meget vigtigt at du husker at omkranse dine skema elementer med dette tag!

Lad os se på, hvordan man laver de enkelte komponenter i et skema. Alle skemakomponenter laves med tagget <INPUT>. Dette tag har et felt som hedder TYPE. Det er her du angiver, hvilken slags komponent det skal være. Det kan fx være "text" eller det kan være "button".

  • Du laver et tekstfelt med <INPUT TYPE="text">. Du kan bruge SIZE feltet til at styre, hvor mange tegn, der skal kunne stå i feltet. For eksempel vil et 10 tegn bredt tekstfelt se således ud i HTML kode:<INPUT TYPE="text" SIZE="10">. Resultatet kommer til at tage sig ud som følger:
  • Du laver en såkaldt "radiobutton" (lille rund knap) med <INPUT TYPE="radio">. Resultatet kommer til at tage sig ud som følger:
  • Du laver en checkboks (firkantet kasse man kan sætte flueben i) med <INPUT TYPE="checkbox">. Resultatet kommer til at tage sig ud som følger:
  • Du laver en knap med <INPUT TYPE="button">. Normalt ønsker du, at der skal stå noget på knappen. Teksten der skal stå på knappen kan du angive i VALUE feltet som følger: <INPUT TYPE="button" VALUE="Min knap">. Resultatet kommer til at tage sig ud som følger:
  • Du laver en drop-down menu ved at benytte dig af tagget <SELECT>. Indeni dette tag angiver du hver indgang i drop-down menuen i et separat <OPTION> tag. Et eksempel kommer her:
    <SELECT>
       <OPTION>Rød</OPTION>
       <OPTION>Grøn</OPTION>
       <OPTION>Gul</OPTION>
    </SELECT>
    
    Resultatet kommer til at se ud som følger:
  • Du kan lave et større tekstfelt (som fx til at skrive brødteksten af en e-mail) med <TEXTAREA>. Dette tag har to yderligere felter, ROWS og COLS, hvor du angiver antal rækker og antal søjer feltet skal have. Læg mærke til at TEXTAREA tagget er separat, mens de andre komponenter allesammen kunne laves ved at bruge tagget INPUT. Tagget TEXTAREA skal altid afsluttes med </TEXTAREA>. Ellers får du helt vildt underlige resultater. Et 4 linier højt og 60 tegn bredt tekstfelt kan således laves på følgende måde: <TEXTAREA ROWS="4" COLS="60"></TEXTAREA>. Og resultatet bliver:

Det var lidt om de basale komponenter som et skema kan bestå af. De fleste komponenter har yderligere felter, som man kan bruge til at specificere yderligere ting. Nogle af disse kommer vi ind på senere efterhånden som vi får brug for dem. Men nu har du fået en kort introduktion til HTML skemaer. Inden vi går videre vil jeg lige komme med et fuldt eksempel på en hel HTML fil som indeholder et lille skema.

<HTML>
   <HEAD>
      <TITLE>Mit første skema</TITLE>
   </HEAD>
   <BODY>
      <FORM>
      <TABLE>
         <TR><TD>
         Fornavn:<INPUT TYPE="text" SIZE="12">
         </TD><TD>
         Efternavn:<INPUT TYPE="text" SIZE="12"><BR>
         </TD></TR>
      </TABLE>
      <INPUT TYPE="button" VALUE="Send mit navn">
      </FORM>
   </BODY>
</HTML>
Tryk her for at se resultatet af ovenstående HTML kode

Funktioner

Den basale komponent i Javascript kaldes en funktion. En funktion består af teksten function funktions-navn() { ... }, hvor de tre prikker erstattes af JavaScript kode. Du kan betragte en funktion, som noget der pakker noget JavaScript kode ind. Inde i funktionen er der, hvor der sker noget. Fra HTML er du vant til, at alt det HTML kode du skriver bliver "udført" når Internet Explorer indlæser dokumentet. I CSS har vi allerede set et eksempel på kode, der kun bliver aktiveret i visse situationer. For eksempel dengang vi legede med links i CSS guiden, og fik linket til at skifte farve, når man førte musen hen over det. I det tilfælde var der noget CSS kode, som kun blev aktiveret idet vi førte musen hen over linket - nemlig det kode som var pakket ind i A:hover. Det er lidt det samme med funktioner i JavaScript - de bliver ikke automatisk udført og koden derinde ligger og venter på at blive aktiveret. Så hvis du bare skriver en eller anden JavaScript funktion, så vil der ikke ske noget. Du kunne ligeså godt have ladet være med at skrive noget. For at få koden inde i funktionen til at blive udført, skal du først kalde funktionen. I CSS eksemplet jeg brugte før, kan man sige at A:hover bliver kaldt, når man fører musen hen over et link. På samme måde skal du med JavaScript specificere, hvornår koden skal kaldes (det vil sige, hvad der skal ske for at aktivere din JavaScript funktion). Det kan fx være når man fører musen hen over noget. Det kan også være funktionen skal kaldes ved indlæsning af HTML dokumentet (dvs kaldes med det samme HTML filen vises på skærmen).

For at få en funktion udført, når HTML siden indlæses kan du benytte feltet "onLoad" som findes i <BODY> tagget. I dette felt skriver du navnet på den funktion du vil kalde efterfulgt af (). Hvad parenteserne skal bruges til (både i kaldet, men også i selve koden til funktionen) vil blive klart senere. Man kan nemlig fylde ting ind i parenteserne - men alt det venter vi med til senere. Lige nu er det blevet tid til at skrive vores første lille JavaScript funktion. Det eneste den kommer til at gøre, er at vise en popupboks med teksten "Hej", som man så kan trykke "OK" til. JavaScript koden for sådan en funktion ser således ud:

<SCRIPT LANGUAGE="JavaScript">
   function visHej() {
      alert("Hej");
   }
</SCRIPT>

Funktionens navn er "visHej". Du kan selv bestemme, hvad du vil kalde en funktion - bare du bruger almindelige bogstaver til navnet. Indmaden i funktionen består af en enkelt linie. Indmaden er faktisk et kald til en anden funktion, der hedder "alert". Det er en funktion som er indbygget i JavaScript, og som kan lave en popupboks. Imellem parenteserne i kaldet til alert kan man angive, hvad der skal stå i popupboksen. I dette tilfælde vil vi gerne have, at der skal stå "Hej". Man skal huske citationstegnene, ellers virker programmet ikke. Kaldet til alert efterfølges af semikolon. Hver gang man har lavet et kald eller en anden lille kommando i JavaScript, skal man altid huske semikolon til sidst. Det kan gå grueligt galt, hvis du glemmer det! Så hvis du har noget, du ikke kan få til at virke så prøv altid lige at kontrollere, at du har husket semikolon efter hver linie med en kommando i. Nu kan vi pakke dette JavaScript ind i et lille HTML dokument og så bruge "onLoad" inde i <BODY> tagget til at få vores funktion udført. Det betyder at man vil få vist popupboksen med det samme HTML siden bliver læst ind. HTML filen med JavaScriptet i kommer til at se sådan her ud:

<HTML>
   <HEAD>
      <TITLE>Min første JavaScript funktion</TITLE>
      <SCRIPT LANGUAGE="JavaScript">
         function visHej() {
            alert("Hej");
         }
      </SCRIPT>
   </HEAD>
   <BODY onLoad="visHej()">
   </BODY>
</HTML>
Tryk her for at se resultatet af ovenstående HTML kode

Variable

Du har måske hørt ordet "variabel" i matematik før? I programmeringssprog som fx JavaScript, så er en variabel en lille beholder, som du kan gemme data i. For eksempel kan du lægge et tal ind i en variabel. Eller en tekst. Ordet "variabel" betyder bare, at det er noget som kan variere - altså at det kan skifte indhold. Du kan starte med at putte 2 ind i en variabel, og så kan du senere ændre det til 4, hvis du får lyst. En variabel har altid et navn i JavaScript, så du kan få fat på den, når du har brug for det. I JavaScript laver du en variabel ved at skrive var variabel-navn, hvor "variabel-navn" er et navn du giver variablen, som du selv kan vælge. Du kan selvfølgelig ikke lave to variable, som hedder det samme - for hvordan kan du så vide, hvad for en du mener, når du har brug for den ene af dem? Du putter en værdi ned i en variabel ved at bruge = tegnet. Hvis jeg for eksempel skriver var x = 2 så betyder det at jeg laver en variabel, som jeg kalder "x" og så putter jeg værdien 2 ind i den. Hvis jeg så senere skriver var y = x + 1 så får y værdien 3 (fordi x jo havde værdien 2). Når man skriver et variabelnavn på højre side af et lighedstegn sådan som jeg lige gjorde, så bliver variablen automatisk erstattet med indholdet af den. Så jeg kunne ligeså godt have skrevet var y = 2 + 1. Lad os lige prøve at lave et lille eksempel, hvor vi bruger en variabel.

<SCRIPT LANGUAGE="JavaScript">
   function visHej() {
      var mitnavn = "Gabriel";
      alert("Hej " + mitnavn);
   }
</SCRIPT>

Ideen med funktionen visHej er nu at vise teksten "Hej Gabriel" i popupboksen. I første linie gemmer jeg teksten "Gabriel" i en variabel, som jeg kalder mitnavn (og afslutter med semikolon! Husk nu, at det skal man altid!). Nu kalder jeg igen alert funktionen, men denne gang har jeg skrevet "Hej " + mitnavn. Og hvad betyder så det? Jo - i denne sammenhæng så betyder "+" at JavaScript skal sammensætte de to tekster, der står på hver sin side af "+" tegnet. Så den skal tage teksten "Hej " og sammensætte den med teksten der er gemt i mitnavn - altså teksten "Gabriel". Resultatet bliver "Hej Gabriel" og denne tekst sendes så til funktionen alert, som får det vist i popupboksen. Hvis man pakker denne funktion ind i noget HTML kode, der ser præcis ud som det HTML kode jeg viste før, så får man resultatet som du kan se nedenfor:

Tryk her for at se resultatet af ovenstående HTML kode

Lad os prøve at lege lidt mere med variable. Prøv at se følgende stump JavaScript kode:

<SCRIPT LANGUAGE="JavaScript">
   function toplusto() {
      var to = 2;
      var toplusto = to + to;
      alert("To plus to giver: " + toplusto);
   }
</SCRIPT>

Første linie gemmer værdien 2 i variablen kaldet to. Læg mærke til, at jeg ikke bruger citationstegn omkring 2. Det er fordi 2 er et tal og ikke en tekst! Næste linie lægger to og to sammen. Denne gang betyder "+" rigtig, almindelig plus af to tal. Derfor kommer variablen toplusto til at indeholde tallet 4. Det er meget vigtigt at jeg ikke satte citationstegn omkring 2. Hvis jeg havde gjort det, så ville to komme til at indeholde teksten 2 i stedet for tallet 2. Og så ville "+" komme til at betyde sammensætning af tekster, ligesom det gjorde i det sidste eksempel. Derfor ville variablen toplusto komme til at indeholde "22", hvis jeg havde gjort det! Dette er en meget vigtig pointe, som du bør tænke over. Så udskriver jeg teksten "To plus to giver: " sammensat med indholdet af min variabel toplusto. Men nu kan det godt være, at du er lidt forvirret. For venstresiden af "+" er jo teksten "To plus to giver: ", mens højresiden slet ikke var en tekst, men et tal! Her finder JavaScript selv ud af, at det er mest naturligt at lave tallet 4 som står i toplusto om til en tekst, der bliver "4". For man kan jo ikke rigtig opfatte "To plus to giver:" som et tal man kan lægge sammen med et andet tal! Derfor vælger JavaScript at lave tallet om til tekst i stedet for. Derfor skulle resultatet være "To plus to giver 4". Det kan du selv se efter, ved at klikke på linket:

Tryk her for at se resultatet af ovenstående HTML kode

Jeg har selvfølgelig lavet <BODY onLoad="visHej()"> om til <BODY onLoad="toplusto()"> fordi jeg jo nu har kaldt min funktion "toplusto" og ikke "visHej".

Jeg sagde at variable kunne ændre indhold - at man kunne starte med fx at lægge 2 ind i en variabel og så senere lægge 3 ind i stedet for. Jeg vil nu vise dig, hvordan man kan gøre det. Det vil sige, hvordan man kan ændre værdien på en variabel. Det er faktisk meget let. Man skal bare skrive variablens navn på venstre side af et lighedstegn og så skrive den nye værdi på højre side. Når et variabelnavn står på venstre side af et lighedstegn, så bliver det betragtet som en beholder man kan fylde noget i (og det der bliver fyldt i, er det som står på højresiden). Når et variabelnavn står på højresiden af et lighedstegn, så bliver det betragtet som en værdi (tal eller tekst). Og denne værdi findes ved at kigge i variablen, og se hvad der er gemt indeni den. Her kommer et eksempel:

<SCRIPT LANGUAGE="JavaScript">
   function toplusto() {
      var x = 2;
      x = x + x;
      alert("To plus to giver: " + x);
   }
</SCRIPT>

Med det jeg lige har sagt burde du være i stand til at forstå, hvad der sker i linien x = x + x;. De to x'er som står på højre side af lighedstegnet bliver erstattet med den værdi, som er gemt i x. Det vil sige de bliver erstattet med 2. Altså står der nu x = 2 + 2;. JavaScript beregner summen af de to tal og ender så med at gemme værdien 4 i variablen x. Så dette JavaScript skriver det samme ud i popupboksen som det foregående - det er bare gjort på en lidt anden måde denne gang.

Synes du det er svært? Det er også OK. JavaScript er meget sværere og mere indviklet at forstå end HTML og CSS var. Det er fordi JavaScript er et "rigtigt" programmeringssprog. Måske vil det være en god idé at læse afsnittet om funktioner og dette afsnit om variable igennem en ekstra gang inden du fortsætter? Men jeg håber, at du allerede nu kan se, hvor kraftfuldt JavaScript er. Med funktioner og variable kan man virkelig lave mange forskellige ting! Vi har allerede beregnet summen af 2 og 2 - det kunne man ihvertfald ikke have gjort i HTML!


Scope af variable

De variable vi har set på indtil nu, har været nogle jeg har lavet indeni en funktion. Hvis du i en funktion laver en variabel x, så kan den bruges overalt i funktionen - men du kan ikke bruge den fra andre funktioner. Hvis du gerne vil lave en variabel, som du kan bruge i alle dine funktioner, så er du nødt til at lave den udenfor alle funktioner - svævende løst ude i dit JavaScript. For eksempel:

<SCRIPT LANGUAGE="JavaScript">
   var x;
   function saettilto() {
      x = 2;
   }
   function saettiltre() {
      x = 3;
   }
</SCRIPT>

Som du kan se, kan man bruge x i begge de to funktioner. De steder i koden, hvor man kan bruge en variabel kaldes dens "scope". Så "scopet" for x i eksemplet ovenfor er hele JavaScript programmet. Mens scopet for den variabel x, jeg lavede i forrige afsnit kun var funktionen toplusto.


JavaScript og HTML skemaer

I dette afsnit vil jeg forklare, hvordan man kan læse indholdet af tekstfelter fra et HTML skema ind i et JavaScript program, og hvordan JavaScript kan skrive værdier i tekstfelter som et slags output. Eksemplet senere i dette afnit vil være en side, hvor brugeren kan indtaste to tal og trykke på en knap der hedder "Beregn". Så vil JavaScriptet beregne summen af de to tal brugeren tastede ind!

For at få fat på indholdet af et inputfelt i JavaScript er det nødvendigt at du navngiver alle dine skemaer og alle dine input-felter i skemaet. Alle HTML tags har et felt, der hedder NAME, som vi indtil nu ikke har haft noget at bruge til. Det har vi nu! Det er ganske vist muligt at få fat på dine inputfelter uden at have givet dine forme og inputfelter navne, men det er langt mere besværligt. Når du har navngivningen på plads, så er det faktisk ikke så svært at få fat i indholdet af et tekstfelt. JavaScript har en særlig variabel som hedder "document", som er indbygget i JavaScriptet. Denne variabel kan du bruge overalt i dine JavaScript funktioner. Den indeholder "hele HTML dokumentet". Det er selvfølgelig temmelig meget! Så der er en særlig teknik man skal bruge, for at få fat på de enkelte dele af dette dokument - for eksempel et bestemt inputfelt. Lad os sige du har lavet et skema <FORM NAME="Form1">. Du kan få fat i hele dette skema ved i JavaScript at skrive document.Form1. Man bruger "punktum" til at komme "ind i dokumentet" og trække en bestemt del af det ud. Så document.Form1 vil komme til at indeholde et helt skema. Hvis du nu havde et inputfelt inde i dette skema som hed <INPUT TYPE="text" SIZE="8" NAME="inputfelt">, så kunne du få fat i dette felt ved at skrive document.Form1.inputfelt. Nu har du så fat i selve inputfeltet. Hvis du vil have teksten, som står inde i inputfeltet ud, skal du yderligere skrive "value". Så det fulde udtryk bliver document.Form1.inputfelt.value. Denne værdi vil være den tekst, som står i inputfeltet! Så for lige at opsummere, så er den generelle måde at få værdien af et inputfelt sådan her: document.formnavn.feltnavn.value, hvor formnavn er det navn du har givet dit skema, og feltnavn er navnet på det felt du gerne vil hente indholdet af. Med den viden du har nu, er det tid til at komme med et eksempel. Eksemplet er det jeg har snakket om tidligere, som beregner summen af to tal som brugeren kan taste ind i et par felter. Her kommer koden (forklaring følger):

<HTML>
   <HEAD>
   <TITLE>Input og output</TITLE>
   <SCRIPT LANGUAGE="JavaScript">
      function adder() {
          var tal1 = parseFloat(document.Form1.tal1.value);
          var tal2 = parseFloat(document.Form1.tal2.value);
          document.Form1.resultat.value = tal1 + tal2;
      }
   </SCRIPT>
   <BODY>
      <H1>Beregn en sum:</H1>
      <FORM NAME="Form1">
         <INPUT TYPE="text" SIZE="8" NAME="tal1"></INPUT> + <INPUT TYPE="text" SIZE="8" NAME="tal2"></INPUT>
	 = <INPUT TYPE="text" SIZE="8" DISABLED="disabled" NAME="resultat"></INPUT><BR><BR>
         <INPUT TYPE="button" VALUE="Beregn" onClick="adder()"></INPUT>
      </FORM>
   </BODY>
</HTML>

Jeg ved godt, at der er nogle ting du ikke har lært om endnu. Så her følger en forklaring på, hvad der foregår i koden ovenfor. Først skal du lægge mærke til, hvordan jeg har navngivet tingene i mit HTML skema. Selve skemaet har fået navnet "Form1". De to felter som brugen benytter til at skrive tal i, har henholdsvis fået navnet "tal1" og "tal2". Derfor kan jeg fra JavaScript programmet få fat på deres værdier ved at skrive henholdsvis document.Form1.tal1.value og document.Form1.tal2.value. Feltet, hvor resultatet skal vises har jeg givet navnet "resultat". Den næste ting, du skal bemærke er, at jeg har anvendt feltet DISABLED i resultatfeltet for at sørge for, at brugeren ikke kan skrive i dette felt. Hvis man sætter DISABLED="disabled", så betyder det at det pågældende inputfelt ikke kan skrives i. Sidst, men ikke mindst, har jeg lavet en knap hvor der står "Beregn" på. Når man trykker på denne knap, er det meningen at summen skal beregnes. Jeg kan benytte det særlige felt "onClick" til at kalde min JavaScript funktion der beregner summen. Den funktion der står i "onClick" bliver udført, når brugeren trykker på knappen. Min funktion hedder adder, så derfor skriver jeg onClick="adder()".

Nu er tiden kommet til at forklare, hvad der sker inde i JavaScript funktionen "adder". Det første problem er, at det jeg får ud når jeg siger document.Form1.tal1.value er en tekst - ikke et tal! Men jeg vil gerne have at JavaScript skal fortolke det som et tal i stedet for! Ellers ville resultatet af 2 + 2 jo som bekendt blive 22. Det har jeg forklaret før. For at lave en tekst om til et tal kan man bruge den funktion, der hedder parseFloat. At "parse" kan groft sagt siges at betyde "fortolke", mens float står for "floating point number", der er den engelske variant af "decimaltal". Så det jeg gør i de to første linier af mit program, er at lave to variable "tal1" og "tal2" og gemme værdierne af de to tilsvarende inputfelter deri - fortolket som tal. Hvis man så ikke skriver tal ind, så går det selvfølgelig galt. Så vil JavaScript skrive "NaN" i stedet for et tal. NaN er en forkortelse for "Not a Number". Det skriver den, fordi den ikke kan lave fx teksten "hejsa" om til et tal. Tredje linie gemmer summen af tal1 og tal2 ind i variablen document.Form1.resultat.value, der jo netop er indholdet af feltet der hedder "resultat". På denne måde kan man fylde værdier i inputfelter fra JavaScript! Man kan simpelthen opfatte felterne som variable, man bare kan lægge værdier ind i. Nu er det vist på høje tid, at du får lov til at prøve programmet ovenfor af, så du kan se, hvordan det virker:

Tryk her for at se resultatet af ovenstående HTML kode

Parametre til funktioner

I dette afsnit skal vi se på, hvordan man kan give en værdi med til en funktion, når man kalder den. De funktionskald vi har set på indtil nu, har set ud som funktionsnavn(). Men man kan også godt fylde noget ind i parenteserne! Det er nok nemmest at starte med at vise et lille eksempel og så forklare ud fra det. Så betragt følgende kode:

<HTML>
   <HEAD>
      <TITLE>Parametre</TITLE>
      <SCRIPT LANGUAGE="JavaScript">
         function tryk(knap) {
            alert("Du trykkede på " + knap);
         }
      </SCRIPT>
   </HEAD>
   <BODY>
      <FORM>
         <INPUT TYPE="button" VALUE="Knap 1" onClick='tryk("Knap 1")'></INPUT>
         <INPUT TYPE="button" VALUE="Knap 2" onClick='tryk("Knap 2")'></INPUT>
      </FORM>
   </BODY>
</HTML>

I JavaScriptet er der en funktion, der hedder "tryk". Som du kan se står der noget indeni parentesen - nemlig "knap". Dette kaldes en parameter. En parameter er i virkeligheden bare en variabel. Værdien af variablen bliver sat, når man kalder funktionen. I resten af funktionen "tryk" er "knap" bare en variabel som man kan bruge. Den har en værdi til at starte med, som er den værdi den fik, da funktionen blev kaldt. Nede i HTML delen har vi to knapper, der begge to kalder funktionen tryk. Knap 1 kalder funktionen med parameteren "Knap 1". Det betyder, at variablen "knap" oppe i JavaScriptet bliver sat til teksten "Knap 1" inden funktionen bliver udført.

Parametre er smart, fordi man kan spare kode og lade en enkelt funktion tage sig af flere forskellige situationer. Hvis vi ikke havde parametre ville vi have været nødt til, at lave to forskellige funktioner "trykpaaknap1" og "trykpaaknap2" for at få det til at virke.

En ting du lige skal lægge mærke til er, at jeg omkring kaldene har brug enkelt citationstegn ' i stedet for almindelige citationstegn ". Det er fordi man ikke må have flere citationstegn indeni hinanden. Så bliver Internet Explorer forvirret! Og vi har jo allerede brugt citationstegn omkring teksterne "Knap 1" og "Knap 2". Derfor er man nødt til at bruge ' for at pakke hele kaldet til tryk ind.

Tryk her for at se resultatet af ovenstående HTML kode

If kontrolstruktur

Nogle gange har man noget kode, som kun skal udføres, hvis en eller anden betingelse er opfyldt. I JavaScript kan man skrive noget på formen:

if(betingelse) { 
   kode der skal udføres hvis betingelsen er opfyldt
}

Eller på formen:

if(betingelse) { 
   kode der skal udføres hvis betingelsen er opfyldt
}
else {
   kode der skal udføres hvis betingelsen ikke er opfyldt
}

Koden imellem { og } bliver kun udført, hvis betingelsen er opfyldt. Koden i betingelsen skal være noget som enten giver sandt eller falsk. For eksempel 0 < 1 der jo tydeligvis er sandt, da nul er mindre end en. I betingelser kan man bruge alle former for matematiske sammenligninger. Bemærk dog, at lighed skrives med to lighedstegn == for ikke at forveksle det med den måde man putter værdier ned i variable på. Eksempler på gyldige betingelser er:

  • 0 < 1 (mindre end)
  • 5 == 7 (lig med)
  • 4 <= 4 (mindre lig)
  • 6 != 5 (forskellig fra)
  • 4 > 6 (større end)
  • 5 >= 6 (større lig)

I stedet for tal kan du selvfølgelig også bruge variable i dine betingelser. Det vil man normalt gøre.

Betragt nu følgende eksempel:

<HTML>
   <HEAD>
      <TITLE>Parametre</TITLE>
      <SCRIPT LANGUAGE="JavaScript">
         function hils() {
            var navn = document.Form1.navn.value;
            if(navn == "Gabriel") {
               alert("Hej Gabriel! Hvor er det rart at møde dig!");
            }
            else {
               alert("Øv du er ikke Gabriel");
            }
         }
      </SCRIPT>
   </HEAD>
   <BODY>
      <FORM NAME="Form1">
         Mit navn er:<INPUT TYPE="text" NAME="navn" SIZE="20"></INPUT>
         <INPUT TYPE="button" VALUE="Hils på mig" onClick='hils()'></INPUT>
      </FORM>
   </BODY>
</HTML>

JavaScript funktionen hils kigger på teksten, der står i feltet navn i skemaet. Hvis teksten er lig med "Gabriel" så udskrives der en speciel hilsen. Ellers skrives der "Øv du er ikke Gabriel". Igen vil jeg lige understrege at man altid skal have citationtegn omkring ting, der er tekst i JavaScript. Hvis man bare skrev if(navn == Gabriel), så ville JavaScript tro, at Gabriel var en variabel! Derfor - husk altid citationstegn omkring tekst. Med linket nedenfor kan du prøve programmet af. Prøv at skrive "Gabriel" som navn. Prøv også at skrive noget andet og se, hvad der så sker.

Tryk her for at se resultatet af ovenstående HTML kode

Udover de betingelser jeg har vist dig, kan du også sammensætte betingelser med "eller" eller "og". Man skriver eller som "||" og og som "&&". For eksempel:

  • x > 0 && x < 100 Dette er sandt, hvis x er større end 0 og mindre end 100.
  • x == 0 || x == 1 Dette er sandt, hvis x enten er 0 eller 1.

Men man kan ikke sammensætte betingelser som i matematik og fx skrive 0 < x < 10. Det er ugyldigt! I stedet for skal man skrive det som 0 < x && x < 10. Endelig kan man også negere betingelser i JavaScript. Det gøres ved brug af symbolet "!" som fx: !(x < 0), der jo er det samme som at skrive x >= 0. Hvis du ikke forstår, hvad jeg mener med negere en betingelse, så betyder det at gøre den omvendt. Så hvis den er sand bliver den falsk og omvendt. !(x < 0) er sand når x < 0 er falsk og omvendt.


Lommeregnereksempel

I dette eksempel skal vi lave en rigtig lommeregner, med samme funktionalitet som de billge lommeregnere, der kun kan de fire regningsarter. Der bliver en knap for hver tast på lommeregneren. Dvs. 10 taltaster, 4 regnetaster (+, -, *, /) en kommatast, en lig med tast og en "clear" tast, der nulstiller displayet. Tasterne er arrangeret i en tabel, så de står pænt i forhold til hinanden. JavaScriptet består af to globale variable, der kan bruges fra alle funktioner, og så 7 forskellige JavaScript funktioner. Når man indtaster regnestykket 2 + 3, så vil det jo kun være 3-tallet der er synligt på displayet, når man trykker "=". Derfor er det nødvendigt at huske på, hvad det første tal var (altså 2 tallet i dette eksempel). Dette tal har jeg valgt at gemme i en variabel, der hedder "gemttal" som ligger yderst i JavaScriptet. Den anden variabel, der kan bruges af alle funktioner er variablen "operation". Heri gemmes enten "+", "-", "*" eller "/" afhængig af, hvilken operation der skal udføres, når man trykker på "=". Vi er jo nødt til at huske på operationen for at vide, hvad det er der egentlig skal ske, når man trykker "=". Jeg vil nu gennemgå de forskellige JavaScript funktioner. Den første funktion "nulstil" nulstiller displayet ved at slette alt der står i det. Displayet er et tekstfelt, der hedder "display" og ligger indeni et skema der hedder "Form1". Derfor kan displayet nulstilles med følgende kode:

document.Form1.display.value = "";

Når man skriver "" betyder det blot den tomme tekst - der er jo ikke noget mellem citationstegnene. Den næste funktion hedder "vistal". Den tager en parameter med, som er det tal, der skal tilføjes til displayet. De forskellige taltaster kalder alle denne funktion, men med forskellige parametre. Knappen "1" vil kalde "vistal(1)", knappen 2 vil kalde "vistal(2)" osv. Tallet bliver tilføjet til displayet ved at tage den nuværende tekst i displayet og sammensætte med det nye tal. Husk at "+" kan bruges til at sammensætte to tekster på denne måde. Indmaden i vistal bliver derfor:

document.Form1.display.value = document.Form1.display.value + tal;

Hvor tal er den parameter funktionen får med. Dernæst kommer der en funktion for hver af de fire regningsarter. Jeg vil nøjes med at gennemgå funktionen for plus, da de andre er helt tilsvarende. Det første der gøres er, at jeg gemmer den nuværende værdi i displayet, så jeg har den tilgængelig, når der trykkes på "=" og udregningen skal gennemføres. Dette klares ved at putte værdien af displayet ned i variablen gemttal:

gemttal = document.Form1.display.value;

Dernæst nulstilles displayet (på samme måde som jeg lige har vist for funktionen "nulstil"). Endelig gemmer jeg information om, at operationen der skal udføres ved tryk på "=" er plus. Dette gør jeg ved at gemme symbolet "+" i variablen operation:

operation = "+";

Den eneste funktion jeg nu mangler at forklare er funktionen "beregn". Det er samtidig den mest indviklede af de syv funktioner. Det første funktionen gør, er at klargøre de to tal der skal udføres en operation på. Det ene tal ligger jo i variablen gemttal, mens det andet tal er det tal, som står i displayet. Jeg bruger funktionen "parseFloat" som jeg allerede har nævnt tidligere, til at lave de to tekster om til faktiske tal, man kan regne på. Koden er:

var tal1 = parseFloat(gemttal);
var tal2 = parseFloat(document.Form1.display.value);

Nu skal de to tal bare enten lægges sammen, trækkes fra hinanden, multipliceres eller divideres. Det afhænger af, hvad der står i variablen operation. Jeg bruger "if" til at bestemme, hvilken af de fire operationer, der skal udføres. Resultatet skal bare skrives i displayet. Den første "if" sætning ser således ud:

if(operation == "+") {
   document.Form1.display.value = tal1 + tal2;
}

De andre tre "if" er helt analoge hertil. Eneste forskel er at + erstattes af -, * eller /. Husk at man skal bruge "==" til at sammenligne og ikke bare =. Nu er du vist klar til at se hele koden i sammenhæng. Det ser ud som nedenfor:

<HTML>
   <HEAD>
   <TITLE>Lommeregner</TITLE>
   <SCRIPT LANGUAGE="JavaScript">
      var gemttal;
      var operation;

      function nulstil() {
         document.Form1.display.value = "";
      }

      function vistal(tal) {
         document.Form1.display.value = document.Form1.display.value + tal;
      }

      function plus() {
         gemttal = document.Form1.display.value;
	 document.Form1.display.value = "";
         operation = "+";
      }

      function minus() {
         gemttal = document.Form1.display.value;
	 document.Form1.display.value = "";
         operation = "-";
      }

      function gange() {
         gemttal = document.Form1.display.value;
	 document.Form1.display.value = "";
         operation = "*";
      }

      function dividere() {
         gemttal = document.Form1.display.value;
	 document.Form1.display.value = "";
         operation = "/";
      }

      function beregn() {
         var tal1 = parseFloat(gemttal);
         var tal2 = parseFloat(document.Form1.display.value);

         if(operation == "+") {
            document.Form1.display.value = tal1 + tal2;
         }
         if(operation == "-") {
            document.Form1.display.value = tal1 - tal2;
         }
         if(operation == "*") {
            document.Form1.display.value = tal1 * tal2;
         }
         if(operation == "/") {
            document.Form1.display.value = tal1 / tal2;
         }
      }
   </SCRIPT>
   </HEAD>
   <BODY>
      <FORM NAME="Form1">
         <TABLE>
         <TR>
         <TD COLSPAN="3"><INPUT TYPE="text" SIZE="15" DISABLED="disabled" NAME="display"></INPUT></TD>
         <TD><INPUT TYPE="button" VALUE="C" onClick="nulstil()"></INPUT></TD>
         </TR>
         <TR>
         <TD><INPUT TYPE="button" VALUE="7" onClick="vistal(7)"></INPUT></TD>
         <TD><INPUT TYPE="button" VALUE="8" onClick="vistal(8)"></INPUT></TD>
         <TD><INPUT TYPE="button" VALUE="9" onClick="vistal(9)"></INPUT></TD>
         <TD><INPUT TYPE="button" VALUE="+" onClick="plus()"></INPUT></TD>
         </TR>
         <TR>
         <TD><INPUT TYPE="button" VALUE="4" onClick="vistal(4)"></INPUT></TD>
         <TD><INPUT TYPE="button" VALUE="5" onClick="vistal(5)"></INPUT></TD>
         <TD><INPUT TYPE="button" VALUE="6" onClick="vistal(6)"></INPUT></TD>
         <TD><INPUT TYPE="button" VALUE="-" onClick="minus()"></INPUT></TD>
         </TR>
         <TR>
         <TD><INPUT TYPE="button" VALUE="3" onClick="vistal(3)"></INPUT></TD>
         <TD><INPUT TYPE="button" VALUE="2" onClick="vistal(2)"></INPUT></TD>
         <TD><INPUT TYPE="button" VALUE="1" onClick="vistal(1)"></INPUT></TD>
	 <TD><INPUT TYPE="button" VALUE="*" onClick="gange()"></INPUT></TD>
         </TR>
         <TR>
         <TD><INPUT TYPE="button" VALUE="0" onClick="vistal(0)"></INPUT></TD>
         <TD><INPUT TYPE="button" VALUE="," onClick="vistal('.')"></INPUT></TD>
         <TD><INPUT TYPE="button" VALUE="=" onClick="beregn()"></INPUT></TD>
         <TD><INPUT TYPE="button" VALUE="/" onClick="dividere()"></INPUT></TD>
         </TR>
         </TABLE>
      </FORM>
   </BODY>
</HTML>
Tryk her for at se resultatet af ovenstående HTML kode

Manipulation med HTML dokumenter

Med JavaScript kan du ændre på ting i din HTML side dynamisk ved et tryk på en knap! Ved at bruge document variablen efterfulgt af de rigtige ting kan du få adgang til store dele af HTML dokumentet og få lov til at manipulere med dem. For eksempel kan man ændre baggrundsfarven på HTML siden med document.bgColor (husk stort "C" i bgColor!). Betragt følgende HTML dokument:

<HTML>
   <HEAD>
      <TITLE>Manipulation med HTML dokument</TITLE>
      <SCRIPT LANGUAGE="JavaScript">
         function skiftbaggrund(farve) {
            document.bgColor = farve;
         }
      </SCRIPT>
   </HEAD>
   <BODY>
      <FORM>
         <INPUT TYPE="button" VALUE="Rød" onClick='skiftbaggrund("#FF0000")'></INPUT>
         <INPUT TYPE="button" VALUE="Grøn" onClick='skiftbaggrund("#00FF00")'></INPUT>
         <INPUT TYPE="button" VALUE="Blå" onClick='skiftbaggrund("#0000FF")'></INPUT>
      </FORM>
   </BODY>
</HTML>
Tryk her for at se resultatet af ovenstående HTML kode

Her kommer et eksempel mere, hvor man kan justere størrelsen på et billede på HTML siden:

<HTML>
   <HEAD>
      <TITLE>Justering af billedstørrelse</TITLE>
      <SCRIPT LANGUAGE="JavaScript">
         function juster() {
            var nybredde = parseFloat(document.Form1.bredde.value);
            if(nybredde > 0 && nybredde < 1000) {
               document.billede.width = nybredde;
            }
            else {
               alert("Hov! Det var en ugyldig bredde. Indtast et tal mellem 1 og 1000");
            }
         }
      </SCRIPT>
   </HEAD>
   <BODY>
      <IMG SRC="billede.gif" NAME="billede">
      <FORM NAME="Form1">
         Indtast størrelse på billede:<INPUT TYPE="text" NAME="bredde" SIZE="4"></INPUT>
         <INPUT TYPE="button" VALUE="Juster størrelse" onClick="juster()"></INPUT>
      </FORM>
   </BODY>
</HTML>
Tryk her for at se resultatet af ovenstående HTML kode

Hvis man navngiver sine billeder kan man manipulere med dem ligesom i eksemplet. Her har jeg kaldt mit billede for "billede" og kan fra JavaScript justere størrelsen af billedet ved at skrive til variablen document.billede.width. Resten af koden burde du umiddelbart forstå, da der ikke er nogen nye ting i det. Bemærk dog, at jeg har en betingelse:

if(nybredde > 0 && nybredde < 1000)

Betingelsen gør, at jeg kun justerer bredden, hvis den nye bredde ikke er for lille og ikke for stor.

Det er ikke alting man kan justere på fra JavaScript. Så vidt jeg ved, kan man kun pille ved links, billeder og skemaer. For eksempel kan man ikke umiddelbart justere egenskaber ved en tabel.


Begivenheder (events) i JavaScript

Når vi kalder en JavaScript funktion sker det altid i forbindelse med en begivenhed eller såkaldt "event". Vi har allerede set to forskellige begivenheder: onClick der sker, når brugeren trykker med musen på den givne komponent, og onLoad der sker, så snart HTML dokumentet indlæses. Der findes en lang række forskellige events. For eksempel:

  • onClick Indtræffer når brugeren klikker med musen.
  • onLoad Indtræffer når HTML dokumentet indlæses.
  • onKeyDown Indtræffer når brugeren trykker på en tast.
  • onKeyUp Indtræffer når brugeren slipper en tast.
  • onChange Indtræffer når brugeren ændrer på indholdet af et inputfelt og så trykker et andet sted i vinduet.
  • onMouseOver Indtræffer når brugeren fører musen hen over den pågældende ting (tabel, form eller hvad det nu måtte være).
  • onMouseOut Indtræffer når brugeren flytter musen væk igen.
  • onFocus Indtræffer når et inputfelt bliver aktivt (klikkes i).

Der findes endnu flere forskellige slags events, men disse er dem som man oftest får brug for. Lad os se et lile eksempel, hvor vi bruger nogle flere events end dem vi har set indtil nu. Jeg vil lave et tekstfelt med en "tegntæller" nedenunder. Hver gang man skriver noget i feltet eller markerer noget tekst og sletter det, skal antallet af tegn opdateres. Jeg bruger eventsene onClick, onChange og onKeyUp til at sikre at feltet bliver opdateret uanset om brugen taster tegn eller blot markerer og sletter tekst fra feltet. Koden ser ud som følger:

<HTML>
   <HEAD>
      <TITLE>Leg med events</TITLE>
      <SCRIPT LANGUAGE="JavaScript">
         function opdaterTegn() {
            var tegn = document.Form1.tekstfelt.value.length;
            document.Form1.tegn.value = tegn;
         }
      </SCRIPT>
   </HEAD>
   <BODY>
      <FORM NAME="Form1">
         Skriv en tekst her:<BR>
         <TEXTAREA ROWS="10" COLS="60" NAME="tekstfelt"
          onKeyUp="opdaterTegn()" onChange="opdaterTegn()" onClick="opdaterTegn()">
         </TEXTAREA><BR>
         Skrevne tegn:
         <INPUT TYPE="text" SIZE="4" NAME="tegn" DISABLED="disabled" BORDER="0"></INPUT>
      </FORM>
   </BODY>
</HTML>
Tryk her for at se resultatet af ovenstående HTML kode

Når man står med en tekst, såsom den i input feltet (document.Form1.tekstfelt.value) så kan man få at vide, hvor lang teksten er, målt i antal tegn ved at efterfølge med .length. Så:

document.Form1.tekstfelt.value.length

er længden af teksten i inputfeltet "tekstfelt".


Funktioner med returværdi og flere parametre

Vi har set, at funktioner kan få værdier med i form af de såkaldte parametre. Men det går også den anden vej. Funktioner kan også returnere værdier! Man returnerer en værdi fra en funktion ved at skrive return efterfulgt af den værdi, man gerne vil returnere. Lad os se et eksempel:

function gangmedto(tal) {
   var togangetal = tal * 2;
   return togangetal;
}

Funktionen ganger sin parameter med to og returnerer resultatet. For at få fat på resultatet kan man bruge et kald til en funktion på højre side af et lighedstegn. Som fx:

var otte = gangmedto(4);

Det der sker i denne linie er, at gangmedto kaldes med parameteren 4. Funktionen gangmedto vil returnere 8, således at linien bliver det samme som:

var otte = 8;

Funktioner kan også tage mere end en parameter. Parametre adskilles af komma. For eksempel:

function sum(tal1, tal2) {
   var sum = tal1 + tal2;
   return sum;
}

Funktionen tager to parametre kaldet tal1 og tal2 og beregner deres sum. Når man kalder funktionen skal man give den to parametre i stedet for et. Som fx:

var sumaftoogtre = sum(2, 3)

Inde i funktionen sum vil tal1 så blive sat til 2 og tal2 blive sat til 3.


Timing og animation (Del I)

Animation? Ja! Du kan faktisk lave en animation med JavaScript. Det skal vi se lidt senere. Det første jeg vil lave, er en side hvor baggrunden langsomt ændrer farve fra hvid til sort. Baggrunden skal hele tiden ændre sig, så jeg kan ikke bruge de traditionelle events som du kender. Brugeren behøver jo ikke klikke med musen eller lignende. Farven skal skifte "af sig selv". I JavaScript er der en særlig funktion der hedder setTimeout som man kan bruge til at få kaldt en funktion med et vist interval. For eksempel hver sekund. Eller 20 gange per sekund! Det er den jeg skal bruge, for at få opdateret baggrundsfarven løbende! setTimeout tager to parametre. Første parameter er en tekst med det kode, man ønsker udført. Anden parameter er det antal millisekunder, man ønsker der skal gå, før koden bliver udført. Et millisekund er en tusindedel af et sekund, hvis du ikke vidste det i forvejen. Så 1000 millisekunder er det samme som 1 sekund. Hvis man laver en funktion:

var x = 0;
function taeller() {
   x = x + 1;
   setTimeout("taeller();", 1000);
}

Så vil den blive kaldt hvert sekund! Første gang funktionen kaldes vil der blive sat en timeout, så funktionen bliver kaldt et sekund senere. Et sekund senere kaldes funktionen igen og der sættes igen en timer, så funktionen bliver kaldt et sekund senere osv. På denne måde kan du se, at funktionen faktisk bliver kaldt hvert sekund! Resultatet bliver, at x bliver talt op med 1 hvert sekund.

Nu er jeg klar til at vise dig koden til at skifte baggrundsfarven glidende fra hvid til sort. Det meste af koden er til for at lave et decimaltal om til en farvekode. Som du nok husker repræsenteres farver med et # efterfulgt af seks cifre som enten kan være 0-9 eller A,B,C,D,E,F. Der er altså 16 muligheder for hvert ciffer. De to første cifre giver mængden af rød, de næste to mængden af grøn og de sidste to mængden af blå. Hvis man bruger lige meget af hver, så får man en eller anden nuance af grå. Jeg ønsker at baggrunden går fra hvid til sort med en masse mellemliggende nuancer af grå. To cifre med 16 muligheder for hver giver 256 forskellige muligheder. Dvs. der er 256 forskellige gråtoner, man kan lave fordi hvert par af to cifre jo skal være ens, for at man får grå. 255 skal laves om til FF og 0 skal laves om til 00 fx. Det er dette funktionerne konverterTilHex og bygHexCiffer arbejder sammen om at klare. Selve funktionen der opdaterer baggrunden ser således ud:

function opdaterbaggrund() {
   farve = farve - 1;
   if(farve > 0) {
      setTimeout("opdaterbaggrund();", 25);
   }
   var hex = konverterTilHex(farve);
   var hexcolor = "#" + hex + hex + hex;
   document.bgColor = hexcolor;
}

Funktionen tæller farven 1 ned (så vi kommer tættere på sort. Når farve = 255 fås hvid, og når farve = 0 fås sort). Hvis farven stadig er større end 0 sættes der en timeout, så funktionen bliver kaldt igen efter 25 millisekunder. Nu bliver tallet gemt i farve lavet om til hexadecimal ved hjælp af et kald til funktionen konverterTilHex. Denne funktion tager et decimaltal som input og returnerer to hexadecimalcifre. Som nævnt laves 255 om til "FF", 254 om til "FE", 16 om til "10" og 0 om til "00". Hvordan dette gøres kommer senere (hvis du er interesseret i at forstå det). Det næste der sker er at jeg sammensætter en farve som tegnet "#" efterfulgt af de to cifre jeg fik tilbage fra konverterTilHex gentaget tre gange. Når hex er fx "FF" så fås "#FFFFFF". Endelig sætter jeg dokumentets baggrundsfarve til denne værdi.

Dette afsnit vil beskrive, hvordan konverterTilHex virker. Det er en fordel, hvis du har et vist matematisk kendskab - gerne på gymnasialt niveau. Ellers kan det godt være, at du vil synes det er svært at følge med! Hvis du vil, kan du springe dette afsnit over og gå direkte til den samlede kode for dette eksempel, der kommer lidt længere nede. Vi starter med at tage et kig på konverterTilHex:

function konverterTilHex(decimaltal) {
   var ciffer1decimal = Math.floor(decimaltal / 16);
   var ciffer2decimal = decimaltal % 16;
   var ciffer1hex = bygHexCiffer(ciffer1decimal);
   var ciffer2hex = bygHexCiffer(ciffer2decimal);
   return ciffer1hex + ciffer2hex;
}

Vi står med et tal mellem 0 og 255 som skal laves om til et tocifret hexadecimaltal. Ligesom et decimaltal har 1'ere længst til venstre så 10'ere så 100'ere osv. så har hexadecimaltal 1'ere længst til venstre, så 16'ere så 256'ere osv. Det første vi skal gøre er at splitte op i de to cifre. Første ciffer indeholder 16'ere og andet ciffer indeholder 1'ere. Så vi skal beregne hvor mange gange 16 går op i vores tal, decimaltal. Det gør vi ved at dividere med 16 og runde ned til nærmeste heltal. Funktionen Math.floor kan runde et tal ned, til nærmeste heltal. Andet ciffer er resten af decimaltal ved division med 16. Dette skrives % og kaldes "modulo". For eksempel er 35 % 16 lig med 3, fordi 16 går op to gange i 35 og efterlader så en rest på 3 (16 * 2 = 32 og 35 - 32 = 3). Ja - jeg sagde jo det krævede matematik det her, så hvis du er stået af, så er der ikke så meget at gøre ved det. Nu skal de to cifre ciffer1decimal og ciffer2decimal, der begge ligger mellem 0 og 15 laves om til det tilsvarende hexadecimal ciffer. Det er nemt og klares med funktionen bygHexCiffer. Endelig sætter jeg de to cifre sammen med +. Der er tale om to tekster, så + betyder her sammensætning af tekster.

Funktionen bygHexCiffer er simpel og lige ud ad lande vejen. 0-9 sendes tilbage uændret (dog som en tekst og ikke som et tal), mens 10 bliver til "A", 11 til "B" osv:

function bygHexCiffer(decimaltal) {
   if(decimaltal == 0) { return "0"; }
   if(decimaltal == 1) { return "1"; }
   if(decimaltal == 2) { return "2"; }
   if(decimaltal == 3) { return "3"; }
   if(decimaltal == 4) { return "4"; }
   if(decimaltal == 5) { return "5"; }
   if(decimaltal == 6) { return "6"; }
   if(decimaltal == 7) { return "7"; }
   if(decimaltal == 8) { return "8"; }
   if(decimaltal == 9) { return "9"; }
   if(decimaltal == 10) { return "A"; }
   if(decimaltal == 11) { return "B"; }
   if(decimaltal == 12) { return "C"; }
   if(decimaltal == 13) { return "D"; }
   if(decimaltal == 14) { return "E"; }
   if(decimaltal == 15) { return "F"; }
}

Hver opmærksom på at al koden ovenfor er skræddersyet til at konvertere decimaltal mellem 0 og 255. Du kan således ikke bruge det generelt, til at konvertere større tal som fx 500. Har du behov for det, så må du skrive din egen udvidede version :-)

Her kommer al koden samlet:

<HTML>
   <HEAD>
      <TITLE>Animation</TITLE>
      <SCRIPT LANGUAGE="JavaScript">
         var farve = 255;

         function bygHexCiffer(decimaltal) {
            if(decimaltal == 0) { return "0"; }
            if(decimaltal == 1) { return "1"; }
            if(decimaltal == 2) { return "2"; }
            if(decimaltal == 3) { return "3"; }
            if(decimaltal == 4) { return "4"; }
            if(decimaltal == 5) { return "5"; }
            if(decimaltal == 6) { return "6"; }
            if(decimaltal == 7) { return "7"; }
            if(decimaltal == 8) { return "8"; }
            if(decimaltal == 9) { return "9"; }
            if(decimaltal == 10) { return "A"; }
            if(decimaltal == 11) { return "B"; }
            if(decimaltal == 12) { return "C"; }
            if(decimaltal == 13) { return "D"; }
            if(decimaltal == 14) { return "E"; }
            if(decimaltal == 15) { return "F"; }
         }

         function konverterTilHex(decimaltal) {
            var ciffer1decimal = Math.floor(decimaltal / 16);
            var ciffer2decimal = decimaltal % 16;
            var ciffer1hex = bygHexCiffer(ciffer1decimal);
            var ciffer2hex = bygHexCiffer(ciffer2decimal);
            return ciffer1hex + ciffer2hex;
         }

         function opdaterbaggrund() {
            farve = farve - 1;
            if(farve > 0) {
              setTimeout("opdaterbaggrund();", 25);
            }
            var hex = konverterTilHex(farve);
            var hexcolor = "#" + hex + hex + hex;
            document.bgColor = hexcolor;
         }
      </SCRIPT>
   </HEAD>
   <BODY onLoad="opdaterbaggrund()">
   </BODY>
</HTML>
Tryk her for at se resultatet af ovenstående HTML kode

Array Variable

Når vi om lidt skal lave en animation med rigtige billeder, så får vi brug for at kunne gemme hvert enkelt billede i en variabel. Hvis man har ti billeder bliver det temmelig besværligt, hvis man skal have en variabel til hver. I JavaScript kan du gøre noget smartere - nemlig benytte et såkaldt array. Et array er en hel liste af variable. Hvis du vil lave et Array med 5 pladser kan du skrive:

var mitarray = new Array(5);

Dette konstrurer en variabel mitarray, som er et array med fem indgange. Det betyder at du faktisk har fem variable i en. Du kan få fat i de enkelte pladser ved at efterfølge arrayvariabelnavnet med [plads]. Som fx:

mitarray[0] = 1;

Den første arrayplads er altid 0 og den sidste er altid en mindre end den størrelse du gav med da du kaldte new Array. Så i eksemplet ovenfor har vi 5 pladser som kan nås med mitarray[0] op til mitarray[4]

Lige et lille eksempel mere:

var talfraettilfem = new Array(5);
talfraettilfem[0] = 1;
talfraettilfem[1] = 2;
talfraettilfem[2] = 3;
talfraettilfem[3] = 4;
talfraettilfem[4] = 5;

Normalt er et funktionskald bare et ord. Du har måske undret dig over, at man skulle skrive new først, når man ville lave et array. Det er fordi Array ikke er en rigtig funktion, men noget der hedder en constructor - det er noget som kan oprette et nyt objekt. I dette tilfælde et Array. Det er ikke meningen at jeg vil forklare alt det nu, men det er godt at vide at der er noget her, som kræver en forklaring. Du må bare være lidt tålmodig med at få forklaringen. Men lige nu kan du tænke på det som, at de specielle funktioner der laver noget nyt til dig (fx. et nyt array) kræver at man skriver new først.


Operatorerne ++ og --

Ting som x = x + 1; forekommer så tit i JavaScript kode, at der er lavet en hurtigere måde at skrive det på. Nemlig blot x++;. Tilsvarende kan man skrive x--; i stedet for x = x - 1;


For-løkker

Da vi skulle fylde værdier i vores array talfraettilfem brugte vi fem linier på det! Det er måske ikke så galt. Hvad nu hvis vi havde et array var talfraettiltusind = new Array(1000);, så ville jeg nødig være den der skulle skrive de 1000 liniers kode for at fylde det op med tallene fra 1 til 1000. Der er selvfølgelig en smartere måde at gøre det på!

Dette smartere kaldes løkker. En løkke er en måde at gentage den samme stump kode mange gange. Hvis du bruger variable kan du sørge for, at det ikke er helt det samme, der sker hver gang. For eksempel er det let at lave en løkke, der fylder tallene i vores array talfraettiltusind op med tallene fra 1 til 1000. Der er flere måder at lave løkker på. Vi starter med for løkker. En for løkke er inddelt i tre dele efterfulgt af det kode, der skal gentages. Først viser jeg, hvordan man laver en løkke der smider tallene fra et til tusind ind i vores array. Derefter skal jeg nok forklare, hvad der foregår:

var talfraettiltusind = new Array(1000);
for(var i = 0; i < 1000; i++) {
   talfraettiltusind[i] = i;
}

Wow! Det var nemt, hvad? Men det kræver en forklaring! Indmaden i løkkens parentes er inddelt i tre dele separeret med semikolon. Første del var i = 0 kaldes initialiseringen. Her laver vi en variabel i som bliver brugt til at styre løkken. Hvad det betyder vil blive klart lige om lidt. Initialiseringen udføres kun en gang, uanset hvor mange gange løkken udføres. Initialiseringen finder sted lige inden løkken bliver udført første gang. Næste del af løkken er betingelsen. Så længe denne betingelse er opfyldt bliver løkken hele tiden udført. Hver gang indmaden i løkken (alt det mellem { og }) er blevet udført bliver betingelsen testet. Hvis den er sand bliver indmaden udført igen. Hvis den er falsk vil løkken ikke blive udført flere gange, og programmet fortsætter med den næste kommando, der følger efter løkken (hvis det er flere). Den sidste del af løkken er opdateringen. Opdateringen vil typisk tælle løkkevariablen en op. Opdateringen bliver udført efter hvert gennemløb af løkken. Så den løkke der er vist ovenfor vil virke på følgende måde. Først sættes i til 0. Dernæst udføres løkken, hvor i = 0. Det vil sige indmaden i løkken bliver:

talfraettiltusind[0] = 0;

Så bliver i talt en op med i++, så nu er i = 1. Så tester vi betingelsen. Da 1 < 1000 udføres løkken en gang til. Denne gang bliver indmaden:

talfraettiltusind[1] = 1;

fordi i = 1 denne gang. Så bliver i talt en op igen, så i = 2. Så tester vi betingelsen. Da 2 < 1000 udføres løkken en gang til osv osv. Tilsidst udføres:

talfraettiltusind[999] = 999;

og i tælles en op. Nu bliver betingelsen 1000 < 1000 og det er falsk. Derfor er løkken nu færdig.


Timing og animation (Del II)

Nu har jeg introduceret nok begreber til at vi kan fortsætte med en "rigtig" animation med billeder i stedet for bare en baggrund der skifter farve. Først skal du selvfølgelig have nogle billeder, du gerne vil have animeret. Det må du selv klare. Jeg har brugt billederne der er vist nedenfor:















Nu skal vi "bare" animere dem! Det gøres med følgende kode:

<HTML>
   <HEAD>
   <TITLE>Animation</TITLE>
   <SCRIPT LANGUAGE="JavaScript">
      var billednummer = 0;
      var billeder = new Array(14);
      for(var i = 0; i < 14; i++) {
         billeder[i] = new Image(384, 64);
      }
      billeder[0].src = "frame1.jpg";
      billeder[1].src = "frame2.jpg";
      billeder[2].src = "frame3.jpg";
      billeder[3].src = "frame4.jpg";
      billeder[4].src = "frame5.jpg";
      billeder[5].src = "frame6.jpg";
      billeder[6].src = "frame7.jpg";
      billeder[7].src = "frame8.jpg";
      billeder[8].src = "frame9.jpg";
      billeder[9].src = "frame10.jpg";
      billeder[10].src = "frame11.jpg";
      billeder[11].src = "frame12.jpg";
      billeder[12].src = "frame13.jpg";
      billeder[13].src = "frame14.jpg";
      
      function opdaterAnimation() {
         document.animation.src = billeder[billednummer].src;
         setTimeout("opdaterAnimation();", 300);
         billednummer++;
         if(billednummer == 14) { 
            billednummer = 0;
         }
      }
   </SCRIPT>
   </HEAD>
   <BODY onLoad="opdaterAnimation()">
      <IMG SRC="frame1.jpg" NAME="animation"></IMG>
   </BODY>
</HTML>

Løst i scriptet er en masse kode. Med løs mener jeg, at det ikke er pakket ind i nogen funktion. Sådan noget kode bliver udført med det samme HTML siden indlæses. Jeg laver et nyt array var billeder = new Array(14) som skal indeholde de 14 billeder animationen består af. Indtil nu har du kun set at man kan gemme tekst, tal og arrays ind i variable. Men man kan også gemme hele billeder ind i variable! Man opretter et billede med funktionen new Image som laver et nyt billede. Som parametre skal man give bredde og højde på billedet. Da alle mine billeder i min animation er 384 pixels brede og 64 pixels høje, så bliver kaldet new Image(384, 64). Jeg bruger en løkke til at løbe igennem alle 14 indgange i mit array og lave et tomt 384 x 64 billede at komme i. Herefter skal jeg sætte stien på hvert enkelt billede. Det er det de næste 14 liniers kode gør. I variablen billeder ligger nu 14 tomme billeder. Jeg sætter filen billedet skal hentes fra ved at bruge ".src". Filnavnet på det første billede sættes således med billeder[0].src = "frame1.jpg";. Tilsvarende for de øvrige 13 billeder. Herefter kommer det interessante - nemlig funktionen til at opdatere animationen. Jeg bruger en variabel billednummer til at holde styr på, hvilket billede jeg er kommet til. Til at begynde med er billednummer = 0. Første linie af opdaterAnimation lægger det næste billede fra mit billedarray ind i billedet som hedder animation. Dette gøres ved:

document.animation.src = billeder[billednummer].src;

Til at starte på er billednummer = 0. Det betyder at linien bliver:

document.animation.src = billeder[0].src;

Og da vi tidligere satte billeder[0].src lig med "frame1.jpg", så får vi det første billede - nemlig "frame1.jpg" vist til at starte med. Jeg benytter setTimeout til at få funktionen kaldt hvert 300 millisekund - dvs. vi får 3 billeder hvert sekund. Herefter opdateres billednummeret, så vi næste gang viser "frame2.jpg"! Jeg har en lille test der checker om vi er løbet hele animationen igennem og billednummer er blevet lig 14. I så fald nulstilles billednummer, så animationen kan køre forfra.

Tryk her for at se resultatet af ovenstående HTML kode

Fancy menu med JavaScript

I dette afsnit skal vi se, hvordan vi kan lave en menu, hvor menupunkterne skifter udseende, når brugeren fører musen hen over dem. Vi har allerede set, hvordan det kunne gøres med CSS, men det virkede jo ikke i Internet Explorer! Det der kommer her vil virke i alle nye browsere. Jeg bruger et array til at indlæse alle de billeder, der skal bruges. Dette sikrer at alle billeder er indlæst, når brugeren fører musen hen over knapperne. Ellers kunne man risikere at der gik lidt tid, mens den hentede billederne ned, så effekten så forkert ud første gang brugeren førte musen hen over menupunkterne.

<HTML>
   <HEAD>
   <TITLE>Fancy menu</TITLE>
   <SCRIPT LANGUAGE="JavaScript">
      var pkt1 = new Array(2);
      var pkt2 = new Array(2);
      for(var i = 0; i < 2; i++) {
         pkt1[i] = new Image(128, 64);
         pkt2[i] = new Image(128, 64);
      }
      pkt1[0].src = "pkt1.gif";
      pkt1[1].src = "pkt1hl.gif";
      pkt2[0].src = "pkt2.gif";
      pkt2[1].src = "pkt2hl.gif";
 
      function musover(menupunkt) {
         if(menupunkt == 1) {
            document.punkt1.src = pkt1[1].src;
         }
         if(menupunkt == 2) {
            document.punkt2.src = pkt2[1].src;
         }
      }

      function musud(menupunkt) {
         if(menupunkt == 1) {
            document.punkt1.src = pkt1[0].src;
         }
         if(menupunkt == 2) {
            document.punkt2.src = pkt2[0].src;
         }
      }
   </SCRIPT>
   </HEAD>
   <BODY>
   <IMG SRC="pkt1.gif" NAME="punkt1" onMouseOver="musover(1)" onMouseOut="musud(1)"></IMG><BR>
   <IMG SRC="pkt2.gif" NAME="punkt2" onMouseOver="musover(2)" onMouseOut="musud(2)"></IMG><BR>
   </BODY>
</HTML>
Tryk her for at se resultatet af ovenstående HTML kode

Der er ikke noget, der burde være svært at forstå i det ovenstående. Prøv at læse det igennem og se om du kan forstå koden. Jeg vil ikke gennemgå den i ret stor detalje her, da du burde have viden nok til at forstå, hvad der foregår. Jeg vil blot bemærke, at jeg bruger eventsene onMouseOver og onMouseOut til at få billederne opdateret, når brugeren fører musen hen over et menupunkt hhv. fjerner musen igen. Jeg vil også lige bemærke at billederne er organiseret i to arrays kaldet pkt1 og pkt2. Begge arrays indeholder to billeder hver - et der er det billede, som skal vises normalt, og et der er det billede, som skal vises, når brugeren fører musen henover menupunktet. De to billeder hørende til menupunkt et gemmes i pkt1 mens de to billeder hørende til menupunkt to gemmes i pkt2


While-løkker

Der findes andre slags løkker end for-løkken, som du allerede har set. While-løkker er simplere end for-løkker, men det er også nemmere at komme til at lave fejl ved at bruge dem. Strukturen af en while-løkke er som følger:

while(betingelse) {
 ...
}

Betingelsen skal være noget, der giver enten sandt eller falsk (ligesom betinglsen til if). Indmaden i while-løkken bliver udført, hvis betingelsen er sand. Ved enden af løkken testes betingelsen igen, og hvis den stadig er sand, så udføres løkken nok engang. Hvis vi tager vores eksempel fra før med tallene fra 1 til 1000 som vi ville lægge ind i et array, så kommer det til at se således ud med en while-løkke:

var talfraettiltusind = new Array(1000);
var i = 0;
while(i < 1000) {
   talfraettiltusind[i] = i;
   i++;
}

Læg mærke til at vi er nødt til at gøre mere arbejde "selv", når vi bruger while-løkker. Vi skal huske at lave en variabel i som vi kan bruge til at styre løkken med. Og endnu vigtigere, vi skal huske at opdatere i. Dette gøres med i++; i dette eksempel. Man kan nemt komme til at glemme at opdatere sin løkkevariabel. Hvis man glemte det og skrev:

var talfraettiltusind = new Array(1000);
var i = 0;
while(i < 1000) {
   talfraettiltusind[i] = i;
}

så har man et stort problem! For nu stopper løkken aldrig nogensinde! For i bliver ved med at være 0, og dermed bliver i < 1000 ved med at være sand. Det betyder at computeren står og regner og regner på løkken i al evighed. Det kan i værste fald få Internet Explorer til at holde op med at svare og fryse. Så pas på du ikke kommer til at lave de såkaldte "uendelige" løkker!


JavaScript og CSS

I dette afsnit skal vi se på, hvordan JavaScript og CSS kan arbejde sammen for at opnå nogle rigtig lækre ting. Du ved allerede at man kan tildele tags en klasse med CLASS feltet, og så lave en selektor i CSS der matcher denne klasse. Med JavaScript er du istand til at manipulere med klasserne. Det betyder fx, at du kan skifte klasse på et element med en JavaScript funktion! Tidligere har jeg fortalt dig, at selektoren ":hover" kun virker på links i Internet Explorer. Hvad nu, hvis jeg gerne ville lave en tabel, hvor tabellen skiftede udseende, når man førte musen hen over den? Så kan jeg bruge JavaScript begivenheden "onMouseOver" til at kalde en JavaScript funktion, der skifter klassen på tabellen! Lyder det for abstrakt? Så må vi hellere springe ud i et eksempel:

<HTML>
   <HEAD>
      <TITLE>JavaScript og CSS</TITLE>
      <SCRIPT>
         function musover(tabel) {
            tabel.className = "musOver";
         }

         function musud(tabel) {
            tabel.className = "normal";
         }
      </SCRIPT>
      <STYLE TYPE="text/css">
         TABLE.normal {
            background-color: #FFFFFF;
            border: 1px solid #DDDDFF;
         }

         TABLE.musOver {
            background-color: #DDDDFF;
            border: 1px solid #000000;
         }
      </STYLE>
   </HEAD>
   <BODY>
      Før musen hen over denne tabel:
      <TABLE CLASS="normal" NAME="Tabel" onMouseOver="musover(this)" onMouseOut="musud(this)">
         <TR><TD>Celle 1</TD><TD>Celle 2</TD></TR>
         <TR><TD>Celle 3</TD><TD>Celle 4</TD></TR>
      </TABLE>
   </BODY>
</HTML>

Som det første vil jeg lige starte med at nævne en vigtig ting. Man kan benytte det specielle nøgleord this i JavaScript, når man kalder en funktion. Det refererer til det objekt (fx tabelcelle, listepunkt eller lignende) hvorfra funktionen blev kaldt. I eksemplet vil "this" være selve tabellen, fordi funktionskaldene står inde i tagget der hedder TABLE. Det er den eneste måde jeg lige kunne få fat i denne tabel på, da man åbenbart ikke kan skrive document.Tabel (hvis man giver tabellen navnet "Tabel" selvfølgelig). Jeg kunne ikke få det til at virke, så derfor benytter jeg denne strategi med this. Det kan faktisk også være rigtig smart, hvis man har mange tabeller! For så ved vi allerede, hvilken tabel det er, vi vil ændre på, når vi får parameteren med! JavaScriptet indeholder to funktioner - en til at håndtere, når musen flyttes hen over tabellen, og en til at håndtere når musen flyttes ud igen. I begge tilfælde benyttes blot ".className" til at få fat på feltet CLASS på vores tabel og ændre det! For eksempel:

tabel.className = "musOver";

Så simpelt kan man ændre klassen og dermed udseendet på en komponent! Det er da smart?! Vi skal selvfølgelig også lave et stylesheet, der fortæller hvordan klasserne "TABLE.normal" og "TABLE.musOver" skal se ud. Måske kendte du ikke indstillingen "border" som består af tre dele, en tykkelse, en type og en farve. Men som sagt er der mange indstillinger at pille ved i CSS og jeg vil ikke gennemgå dem alle slavisk i disse guides. I stedet henviser jeg endnu engang til:

CSS indstillinger referencen

Men du mangler at se, hvordan resultatet af det ovenstående kommer til at tage sig ud:

Tryk her for at se resultatet af ovenstående HTML kode

En JavaScript dropdown menu

Inden vi går igang med dette afsnit, vil jeg starte med at vise dig, hvad det er jeg gerne vil lære dig at lave i dette afsnit. Det drejer sig om dropdown menuer. Du har allerede set dem som de tog sig ud i HTML skemaer. Men der kunne du jo ikke bestemme, hvordan de skulle se ud. I dette afsnit skal vi se på, hvordan man kan designe sine egne dropdown menuer og lave en fin menubjælke øverst med dropdown menuer!

Tryk her for at se hvad det er du skal lære at lave i dette afsnit

For at lave en dropdown menu har vi brug for noget, der kan vises og skjules (nemlig selve kroppen af menuen, der skal vises, når man bevæger musen hen over menuen, og skjules når man fører musen væk igen). Et DIV element kan løse opgaven, fordi der i CSS er en indstilling der hedder display, som man kan sætte til none og derved skjule menuen! I eksemplet var der to menuer - en der hed "Links" og en der hed "Guides". Disse to menuer er pakket ind i en overordnet tabel der kun har en række. Der vil så være et TD element for hver menu man ønsker der skal være. Tabellen skal være bred nok til at indeholde alle menuerne. I eksemplet er tabellen 400 pixels bred mens hvert menupunkt fylder 200 pixels. Hver menu har tilknyttet både onMouseOver og onMouseOut events som kalder nogle JavaScript funktioner til at folde menuerne ud og klappe dem sammen. Den overordnede struktur af menuen bliver derfor:

<TABLE WIDTH="400">
<TR>
<TD class="menuNormal" WIDTH="200" onMouseOver="foldud(this);" onMouseOut="klapsammen(this);">
<P><B>Links</B></P>
         Her kommer et DIV element med menuens punkter
</TD>
<TD class="menuNormal" WIDTH="200" onMouseOver="foldud(this);" onMouseOut="klapsammen(this);">
<P><B>Guides</B></P>
         Her kommer et DIV element med menuens punkter
</TD>
</TR>
</TABLE>

Det føromtalte DIV element kommer til at indeholde alle menupunkterne der skal foldes ud, når man rører ved en af menuerne. DIV elementet indeholder en tabel med en række for hvert menupunkt. Indmaden er bare et link. Jeg bruger CSS til at forhindre at disse links bliver vist med blå skrift og med understregning. Men vi vender tilbage til CSS delen om lidt. Læg mærke til, hvordan jeg igen bruger this som parameter til kaldene til de to JavaScript funktioner.

JavaScriptet består af to funktioner, foldud og klapsammen:

<SCRIPT LANGUAGE="JavaScript">
   function foldud(menu) {
      var d = menu.getElementsByTagName("div").item(0);
      menu.className = "menuHover";
      d.className  = "menuHover";
   }

   function klapsammen(menu) {
      var d = menu.getElementsByTagName("div").item(0);
      menu.className = "menuNormal";
      d.className = "menuNormal";
   }
</SCRIPT>

Du undrer dig nok over den første linie med et kald til "getElementsByTagName". Det er en lille smule indviklet at forklare. For det første vil jeg starte med at minde dig om, at parameteren "menu" kommer til at være det TD element, hvorfra funktionen er blevet kaldt (husk at hver menu ligger i et TD element i den overordnede tabel som er vist ovenfor). Sådan et TD element er et såkaldt objekt. Jeg har ikke gennemgået, hvad det er, men det er en slags variabel som kan have mange forskellige værdier og også funktioner! Et eksempel på et objekt du allerede kender er document. Du ved allerede godt, at den har flere forskellige værdier fx document.bgColor eller document.Skema1.mittekstfelt (hvis altså du havde en form der hed "Skema1" med et tekstfelt i der hed "mittekstfelt"). Det er samme idé der gør sig gældende med vores variabel "menu". Her kalder vi funktionen "getElementsByTagName" som er gemt indeni objektet - derfor skrives "menu." foran kaldet. Denne funktion tager en parameter med der er en tag-type. I dette tilfælde "DIV". Det den returnerer er alle de DIV elementer som ligger under tabelcellen ved navn menu. Fordi der jo principielt kunne være mere end et af sådanne DIV elementer, så skal vi yderligere efterfølge dette kald med ".item(0)" for at få det første af disse elementer. Hvis der var 3 og vi ville have fat i den 3. kunne vi skrive ".item(2)" i stedet for. Nummereringen starter ved 0 så derfor er 2 den 3. Det skal men lige huske på! Så det vi får ud er altså vores DIV element som indeholder alle underpunkterne i den pågældende menu. Dette gemmes i variablen d. I funktionen foldud ændrer vi nu klassen på både menuen (for at få den highlighted med lyseblå) og vores DIV element gemt i d (for at få den vist). Klassen "menuHover" indeholder de indstillinger, der bruges når menuen skal vises, mens "menuNormal" indeholder de sædvanlige indstillinger, hvor menuen ikke er foldet ud. Funktionen klapsammen virker på samme måde som foldud, men sætter klassen tilbage til "menuNormal".

Nu mangler vi faktisk kun at kaste et blik på CSS koden! Den kommer her i hele sin herlighed:

<STYLE TYPE="text/css">
   TD.menuNormal {
      background-color: #FFFFFF;
   }
   
   TD.menuHover {
      background-color: #DDDDFF;
   }

   DIV.menuNormal {
      display: none;
   }

   DIV.menuHover {
      border: 1px solid #DDDDFF;
      display: inline;
      position: absolute;
      background-color: #FFFFFF;
   }

   A.menupkt:link {
      text-decoration: none;
      color: black;
      display: block;
      background-color: #FFFFFF;
   }

   A.menupkt:visited {
      text-decoration: none;
      color: black;
      display: block;
      background-color: #FFFFFF;
   }

   A.menupkt:hover {
      text-decoration: none;
      color: black;
      display: block;
      background-color: #DDDDFF;
   }

   A.menupkt:active {
      text-decoration: none;
      color: black;
      display: block;
      background-color: #DDDDFF;
   }
</STYLE>

Klasserne TD.menuNormal og TD.menuHover styrer hvordan menubjælken tager sig ud. Baggrundsfarven skifter til lyseblå (#DDDDFF), når brugeren fører musen over den. DIV.menuNormal er den normale indstilling for drop-down menuen. Nemlig at den ikke skal vises. Dette klares ved at sætte display: none;. Når menuen foldes ud benyttes DIV.menuHover. De mest interessante egenskaber for den er display: inline; og position: absolute;. Den første af de to styrer hvordan elementet vises. Inline betyder, at der ikke kommer noget linieskift før og efter elementet. Den anden indstilling ved jeg faktisk ikke så meget om. Den er ikke at finde i den reference jeg har givet til CSS. Så det må være en ret ny ting. Udelader man den, bliver menuen imidlertid positioneret forkert. Jeg vil tro at "absolute" betyder, at den skal vises lige nøjagtig der, hvor den ville være blevet vist, hvis den havde været synlig fra start af. Men du kan jo prøve google, hvis du vil vide mere om lige det. Dernæst følger alle indstillingerne for links. Det er mest for at forhindre, at de kommer til at ligne almindelige links med understregning og blå farve. Der er fire indstilinger; link der styrer hvordan linket ser ud normalt, visited der styrer, hvordan linket ser ud, når det er besøgt, hover der styrer hvordan linket ser ud, når man flytter musen hen over det og endelig active der styrer hvordan linket ser ud idet man klikker på det. De to første har samme indstillinger mens de to sidste har en blålig baggrundsfarve. Så når man bevæger musen hen over menupunkterne vil det menupunkt man står ud for blive vist med blå baggrund. Det ser lækkert ud og gør det nemmere at se, hvor man er i menuen. Indstillingen display: block; bevirker at baggrundsfarven strækker sig helt ud til kanten af menuen i stedet for kun lige at dække teksten.

Når man sætter det hele sammen bliver koden som følger:

<HTML>
   <HEAD>
   <TITLE>Lækker dropdownmenu</TITLE>
   <SCRIPT LANGUAGE="JavaScript">
      function foldud(menu) {
         var d = menu.getElementsByTagName("div").item(0);
         menu.className = "menuHover";
         d.className  = "menuHover";
      }

      function klapsammen(menu) {
         var d = menu.getElementsByTagName("div").item(0);
         menu.className = "menuNormal";
         d.className = "menuNormal";
      }
   </SCRIPT>
   <STYLE TYPE="text/css">
      TD.menuNormal {
         background-color: #FFFFFF;
      }
      
      TD.menuHover {
         background-color: #DDDDFF;
      }

      DIV.menuNormal {
         display: none;
      }

      DIV.menuHover {
         border: 1px solid #DDDDFF;
         display: inline;
         position: absolute;
         background-color: #FFFFFF;
      }

      A.menupkt:link {
         text-decoration: none;
         color: black;
         display: block;
         background-color: #FFFFFF;
      }

      A.menupkt:visited {
         text-decoration: none;
         color: black;
         display: block;
         background-color: #FFFFFF;
      }

      A.menupkt:hover {
         text-decoration: none;
         color: black;
         display: block;
         background-color: #DDDDFF;
      }

      A.menupkt:active {
         text-decoration: none;
         color: black;
         display: block;
         background-color: #DDDDFF;
      }

   </STYLE>
   </HEAD>
   <BODY>
      <TABLE WIDTH="400">
      <TR>
      <TD class="menuNormal" WIDTH="200" onMouseOver="foldud(this);" onMouseOut="klapsammen(this);">
         <P><B>Links</B></P>
         <DIV CLASS="menuNormal" WIDTH="195">
            <TABLE WIDTH="195">
            <TR><TD CLASS="menuNormal">
               <A HREF="http://www.google.com" CLASS="menupkt">Gå til google</A>
            </TD></TR>
            <TR><TD CLASS="menuNormal" WIDTH="195">
               <A HREF="http://www.daimi.au.dk" CLASS="menupkt">Gå til daimi</A>
            </TD></TR>
            <TR><TD CLASS="menuNormal" WIDTH="195">
               <A HREF="http://www.jubii.dk" CLASS="menupkt">Gå til Jubii</A>
            </TD></TR>
            </TABLE>
         </DIV>
      </TD>
      <TD class="menuNormal" WIDTH="200" onMouseOver="foldud(this);" onMouseOut="klapsammen(this);">
         <P><B>Guides</B></P>
         <DIV CLASS="menuNormal" WIDTH="195">
            <TABLE WIDTH="195">
            <TR><TD CLASS="menuNormal">
               <A HREF="http://www.daimi.au.dk/~u020753/html_guide/index.html"
                CLASS="menupkt">Gå til HTML guide</A>
            </TD></TR>
            <TR><TD CLASS="menuNormal" WIDTH="195">
               <A HREF="http://www.daimi.au.dk/~u020753/css_guide/index.html"
                CLASS="menupkt">Gå til CSS guide</A>
            </TD></TR>
            <TR><TD CLASS="menuNormal" WIDTH="195">
               <A HREF="http://www.daimi.au.dk/~u020753/javascript_guide/index.html"
                CLASS="menupkt">Gå til JavaScript guide</A>
            </TD></TR>
            </TABLE>
         </DIV>
      </TD>
      </TR>
      </TABLE>
   </BODY>
</HTML>
Tryk her for at se resultatet af ovenstående HTML kode

Du kan selvfølgelig gøre det endnu mere lækkert ved at vælge nogle mere spændende skrifttyper og eksperimentere mere med farver osv. Det ovenstående er ikke ment som et bud på en super-lækker menu, men for at vise dig hvad der er muligt med JavaScript og CSS.


Tekstmanipulation

Nogle gange har man behov for, at lave mere avancerede manipulationer med tekst end hvad du har lært indtil nu. Du har lært, hvordan man kan gemme en tekst i en variabel. Men du har ikke lært, hvordan man leder i en tekst efter bestemte bogstaver, hvordan man undersøger indholdet af fx det 5. bogstav i en tekst osv. Det er den slags ting, vi skal se på i dette afsnit. Måske kan du ikke se, hvad du skal bruge det til? Det er heller ikke så nyttigt, hvis du kun vil benytte JavaScript til at lave effekter som fx drop-down menuer eller animationer. Men ofte anvender man JavaScript til at validere indholdet af HTML skemaer inden de sendes afsted. For eksempel kunne det være man havde et felt kaldet "e-mail", hvor man gerne ville checke at det brugeren taster ind i feltet rent faktisk er en gyldig e-mailadresse (dvs. den skal fx indeholde '@'). Jeg har ikke lært dig hvordan man kan sende ting afsted over nettet (fx indholdet af et HTML skema). Faktisk ved du ikke engang, hvordan du lægger din hjemmeside ud på internettet endnu! Så du har selvfølgelig meget at lære. Men tilbage til det dette afsnit skulle handle om.

JavaScript skelner mellem enkelte tegn og tekster (også kaldet "strenge" i programmeringsverdenen. En streng er blot en tekst - dvs. noget der består af nul eller flere tegn.). Et enkelt tegn skrives omkranset af '', mens tekster skrives omkranset af "". Tegnet a skrives således som 'a', mens teksten a skrives som "a". Der er en forskel. Hvis vi betragter følgende:

var tegna = 'a';
if(tegna == "a") {
...

så vil betingelsen i if-sætningen blive falsk fordi 'a' ikke er det samme som "a"! Det er selvfølgelig ulovligt at skrive 'ab', fordi ab ikke er et enkelt tegn. I stedet skal man skrive "ab", for at få teksten bestående af et a efterfulgt af et b.

Hvis man har en tekst så kan man bede om at få bogstavet på en given position i teksten. Nummereringen begynder ved 0, så det første tegn i teksten bliver nummer 0 og så fremdeles. Funktionen charAt der tager en parameter kan kaldes på en tekst og returnerer tegnet på den position, der gives med som parameter. Eksempler:

var tekst = "Hej med dig";
var tegn1 = tekst.charAt(0);
var tegn5 = tekst.charAt(4);

Variablen tegn1 bliver således 'H', mens variablen tegn5 bliver 'm'. Jeg har tidligere kort omtalt objekter som noget der havde både funktioner og variable gemt i sig. En tekst er faktisk et objekt med en række tilhørende variable og funktioner. Som du kan se har den funktionen charAt. En anden nyttig funktion er substring. Funktionen returnerer et udsnit af en større tekst og tager to parametre. Den første er et index ind i teksten, hvor udsnittet skal starte mens den anden parameter er et index ind i teksten, hvor udsnittet skal slutte. Udsnittet går fra og med det første index til, men ikke med, det sidste index. Eksempler:

var tekst = "Hej med dig";
var hej = tekst.substring(0,3);
var med = tekst.substring(4,7);
var dig = tekst.substring(8,11);

En anden ting, man ofte får brug for, er at bestemme længden af en tekst. Dette kan gøres med length som i:

var tekst = "Hej med dig";
var laengde = tekst.length;

Som du kan se er length faktisk ikke nogen funktion (den har ikke () efter sig). Det er en variabel som tekstobjektet indeholder! Men det behøver du ikke spekulere så meget på.

Ofte har man brug for at søge i en tekst efter en mindre tekst, eller efter et enkelt tegn. Det kan gøres ved at benytte funktionen indexOf, der tager to parametre. Første parameter angiver det tegn eller den tekst der søges efter, mens anden parameter (der godt må udelades!) specificerer et index, hvor søgningen skal begynde. Hvis man ikke giver den anden parameter med, men nøjes med at give en søgetekst med, så svarer det til at give begge parametre med, men sætte den sidste parameter til 0. indexOf returnerer index på det første sted i teksten, hvor søgeteksten findes. Hvis teksten slet ikke findes, så returnerer indexOf den specielle værdi -1, så man ved at teksten ikke blev fundet. Eksempler:

var tekst = "Hej med dig";
var indexafdig = tekst.indexOf("dig");

Her skulle indexafdig blive 8, fordi teksten "dig" begynder ved det 8. tegn i "Hej med dig".

Lad os prøve at se et lidt større eksempel, der bruger nogle af de ting du lige har lært. Vi vil lave et HTML dokument med et tekstfelt, hvor en bruger kan skrive sin e-mail. Når han trykker på en knap vil e-mailen blive valideret. I dette eksempel stiller vi følgende krav til e-mail adressen:

  • Den skal indeholde '@'.
  • Den skal ende med ".dk"

Bemærk venligst, at dette ikke er realistiske krav til en e-mail adresse. For at en e-mail adresse er gyldig skal den opfylde langt flere krav. Men det ovenstående er blot for at vise dig, hvordan man kan bruge de ovennævnte tekstfunktioner til at lave checks som dem angivet ovenfor. Her kommer koden der løser vores opgave:

<HTML>
   <HEAD>
      <TITLE>E-mail validering</TITLE>
      <SCRIPT LANGUAGE="JavaScript">
         function validerEmail() {
            var email = document.Form1.email.value;
            if(email.indexOf('@') > -1) {
               var laengde = email.length;
               var endelse = email.substring(laengde - 3, laengde);
               if(endelse != ".dk") {
                  alert("Det var ikke en dansk e-mail adresse! Den endte på " + endelse);
               }
               else {
                  alert("E-mail godkendt!");
               }
            }
            else {
               alert("En e-mail adresse skal indeholde @!");
            }
         }
      </SCRIPT>
   </HEAD>
   <BODY>
      <FORM NAME="Form1">
         E-mail:<INPUT TYPE="text" SIZE="40" NAME="email"></INPUT>
         <INPUT TYPE="button" VALUE="Valider" onClick="validerEmail()"></INPUT>
      </FORM>
   </BODY>
</HTML>
Tryk her for at se resultatet af ovenstående HTML kode

Prøv om du kan forstå koden ovenfor. Den burde ikke indeholde ting, du ikke er i stand til at forstå på nuværende tidspunkt.

Der findes flere funktioner til at manipulere tekst end dem jeg har vist her. Eksempler er:

  • toUpperCase konverterer tekst til lutter store bogstaver. Eksempel: tekst.toUpperCase();
  • toLowerCase konverterer tekst til lutter små bogstaver. Eksempel: tekst.toLowerCase();
  • parseInt konverterer tekst til heltal (hvis muligt). Returnerer talværdien. Eksempel: parseInt(tekst);
  • parseFloat konverterer tekst til decimaltal (hvis muligt). Returnerer talværdien. Eksempel: parseFloat(tekst);

Hjælp mit JavaScript virker ikke!

Jeg håber du på nuværende tidspunkt har eksperimenteret lidt med JavaScript og har prøvet at skrive dine egne små scripts. Du har sikkert flere gange fået skrevet noget, der ikke virkede. Og set dig blind på det, så du ikke kunne opdage fejlen? Et tip er, at du kan bruge alert funktionen til at få udskrevet information. Nogle gange kan JavaScript "gå i stå", hvis du skriver noget forkert på en linie. Derfor vil alle efterfølgende programlinier ikke blive udført. Ved at flytte rundt på alert beskeder kan du se, hvornår du får en alert tilbage og hvornår den pludselig ikke dukker op. På denne måde kan du finde frem til den problematiske linie. Du kan også få udskrevet værdier af variable (der har du jo allerede set). Det kan du bruge til at undersøge, om dine variable indeholder de værdier som du forventer.


Mere om JavaScript

Endnu engang kan jeg sige, at jeg langtfra er kommet omkring alle aspekter ved JavaScript. Specielt er der masser af indbyggede funktioner og variable i JavaScript, som du ikke har stiftet bekendtskab med endnu. En (lettere forældet mig bekendt) guide til JavaScript med reference over funktioner osv. kan findes her:

Klik her for at gå til reference over JavaScript

Afrunding

Der er mange ting at sige endnu om JavaScript. Ikke så meget om de grundlæggende principper, men snarere omkring det væld af funktioner der findes. Og du har også noget at lære om document variablens mange forskellige felter. Men du har fået en god introduktion til JavaScript, du har fået set nogle af de fine ting man kan lave med det og er forhåbentlig blevet inspireret til at lave nogle hjemmesider med lækre effekter!

Med disse ord vil jeg sige tak for nu. Jeg håber du har haft gavn og glæde af min guide til JavaScript, og at du føler du har fået noget ud af den. Hvis der er noget, du ikke forstår eller hvis du finder graverende stave-/slåfejl i guiden er du velkommen til at kontakte mig.

Min e-mail adresse er: gsiegel@gabsoft.dk


Privatlivspolitik Fortsæt til Frigiv din hjemmeside