Udvidet interaktion - vis billednummer og hastighed

Ideen med denne side er igen at føje ekstra funktionalitet og pynt til vort slideshow, samt at demonstrere, hvorledes du kan sikre dig visning af billeder af forskellig størrelse.

Første Sidste Næste Forrige Auto Stop Pause

1 sek 2 sek 3 sek 5 sek 10 sek

Knapperne kontrollerer billedvisningen
Paris, Triumfbuen
Rom, Colloseum
Paris, Sacre Cour
Washington, Capitol Dome
Paris, Notre Dame
London, London Brigde
England, Stonehenge
Washington, Lincoln Monument

Viser billede nr: 1 2 3 4 5 6 7 8

Den øgede funktionalitet fremkommer derved, at brugeren nu billede for billede holdes orienteret om, hvilket nummer, billedet har, foruden at hun får en rigtig billedtekst.

Kosmetikken ligger i udformningen af hastighedskontrollen og af det panel, der dels viser billednummer og dels gør det muligt for brugeren at vise et bestemt billede ud af de 8.

Princippet med at vise billedet i korrekt størrelse er løst på en lidt "billig" måde: Jeg har ganske enkelt undladt width og height i den img-markører, der definerer billedarealet:

<img src="monumenter/pix1.jpg" 
alt="Knapperne kontrollerer billedvisningen" 
id="billede" />

Når billederne ikke er lige store er det ikke helt ligetil at få dem centreret lodret i billedfeltet. Derfor har jeg også her grebet til en billig løsning, nemlig at lægge billedet/billederne ind i en tabel med én celle:

table#pixframe {
  width:270px;
  height:270px;
  background:#555;
  margin: 0 auto;
  text-align:center;
  border-width:10px;
  border-style:outset;
  border-color:blue;}
  
table#pixframe td {
  vertical-align:middle;
  padding:5px;}

Scriptet

Dette script er efterhånden ganske omfangsrigt – et par hundrede linier – så jeg gengiver og kommenterer det herunder i småbidder. Vil du have hele scriptet, som det er anvendt her, kan du downloade en zip-fil, der indeholder scriptet, billederne og de mest nødvendige formregler: download applikationen.

Scriptet starter med at sende en alert til browsere, der ikke forstår moderne JavaScript. Dernæst opretter jeg et antal DHTML support-funktioner, så jeg ikke skal taste det samme igen mange gange:

if (!document.getElementById){
alert ("Denne webside ikke anvendes i en 
-->  browser\nder er ældre end 5 år. ");
}
function setBgColor(objekt, color) {
  document.getElementById(objekt).style.backgroundColor 
  = color;
}
function setFgColor(objekt,color) {
  document.getElementById(objekt).style.color 
  = color;
}
function collapse(objekt) {
  document.getElementById(objekt).style.display
   = "none";
}
function expand(objekt) {
  document.getElementById(objekt).style.display 
  = "block";
}
function skjulObjekt(objekt) {
  document.getElementById(objekt).style.visibility 
  = "hidden";
}
function visObjekt(objekt) {
  document.getElementById(objekt).style.visibility 
  = "visible";
}

Dernæst opretter jeg en flok variable, herunder et array af de billeder, jeg vil bruge:

var speed= 2000;
var antal=8;
var nr=1;
var running = 0;
var trin=2;
var timer=0;

var images = new Array()
  for(i = 1; i < antal + 1; i++){
    images[i] = new Image();
    images[i].src = "monumenter/pix" + i + ".jpg";
  }

Muligheden for at ændre på den hastighed, hvormed billederne vises, opnår jeg ved at oprette en funktion, setSpeed(), som jeg kalder fra en liste over mulige hastigheder og derfra passerer et tal trin til funktionen. Derved sættes en ny værdi for den variable speed, svarende til det tal, jeg klikkede på. Tillige udløser jeg en funktion setColors(), der har til formål at ændre forgrundsfarve og baggrundsfarve på "speedometeret":

function setSpeed(trin) {
  switch(trin){
    case 1: speed=1000;setColors(trin);
    break;
    case 2: speed=2000;setColors(trin);
    break;
    case 3: speed=3000;setColors(trin);
    break;
    case 4: speed=5000;setColors(trin);
    break;
    case 5: speed=10000;setColors(trin);
    break;
  }
}
function setColors(trin){
  for (i=1;i<6;i++){
    setFgColor('speed'+ i,'white')
    setBgColor('speed' + i,'teal')
  }
    setFgColor('speed'+ trin,'black')
    setBgColor('speed' + trin,'#ffffee'
  )
}

setColors()-funktionen sætter først farverne til standardvisningen, og dernæst sætter funktionen farven på det element, der svarer til værdien af den variable trin.

Ganske tilsvarende har jeg en funktion, der sætter forgrundsfarve og baggrundsfarve på nummerrækken under billedet/billederne:

function setPixNrColors(nr){
  for (i=1;i<9;i++){
    setFgColor('pixnr'+ i,'white')
    setBgColor('pixnr' + i,'teal')
  }
  setFgColor('pixnr'+ nr,'black')
  setBgColor('pixnr' + nr,'#ffffee')
}

For så vidt angår kontrolpanelet ønsker jeg mig mig også en markering af tilstanden, når applikationen er i auto-modus, samt når der klikket på pause.

Det opnår jeg ved at ændre baggrundsfarve på de respektive knapper, når der er klikket på dem, samt sætte baggrundsfarven tilbage til standardværdien, når der klikkes på stopknappen, samt for pauseknappens vedkommende, når der klikkes på auto, mens applikationen er i pause.

Hvad er forskellen på stop og pause? Jo, når der klikkes på stop, sættes applikationen i standardtilstand, kendetegnet ved, at billede nr. 1 vises. Klikkes der på pause, standses applikatione ved det billede, der aktuelt vises, og klikkes igen på auto fortsættes visningen derfra.

Bemærk den variable running: Den har værdien 1 eller 0, svarende til at timerfunktione kører eller ikke kører. Ved at teste for værdien af denne variable, kan jeg styre de forskellige handlinger, der skal udføres forskelligt alt efter om showet kører eller ej.

Det gælder for eksempel kernefunktionen visPix(nr).

function visPix(nr) {
  if (running==1) {
    alert("Stop autovisning før \ndu viser enkeltbilleder")
  }
  else {
    skjulAlle();
  	document.images.billede.src = images[nr].src;
  	expand('pixtext' + nr);
    setPixNrColors(nr)
  
  }
}

Her testes for, om timeren kører. Hvis det er tilfældet, vises en alert-boks, der beder brugeren om at stoppe show'et, før der vises enkeltbilleder.

Hvis show'et derimod ikke kører (running==0) falder funktionen igennem som det hedder, og

  1. skjulAlle() skjuler alle billedteksterne,
  2. indlæser det billede, der ligger i memory som en variabel i array'et images, svarede til værdien af nr,
  3. ændrer displayværdien for den tilsvarende billedtekst til block, og
  4. sætter den rette forgrundsfarve og baggrundsfarve på den aktuelle billednummer.

En anden vigtig funktion er next(), funktionen der viser næste billede.

function next(){
  skjulAlle();
  nr=nr+1
  if (nr==antal + 1) nr=1;
  document.images.billede.src = images[nr].src
  setPixNrColors(nr)
  expand('pixtext' + nr);
  }

Igen skjules alle billedteksterne. Så lægger vi 1 til den globale variable nr. Hvad værdien af denne er, afhænger af, hvad der er gået umiddelbart forud, det vil sige, hvilket billede, der aktuelt vises. Her skal vi teste for, at værdien ikke bliver større end vi har billeder til. Hvis nr efter next() er udløst er antallet af billeder + 1, er det tegn på, at der ikke er flere billeder. Så ønsker vi, at nr får værdien 1, idet vi ønsker at vende tilbage til begyndelsen af billedrækken, hvis vi klikker "Næste" på det sidste billede.

Igen henter vi et billede i array'et, svartende til værdien af nr, og igen sætter vi farve på billednummeret og viser den billedtekst, der svarer til værdien af nr.

Da jeg skal bruge next()-funktionen i forbindelse med autofunktionen, går det ikke at bruge den i forbindelse med knappen "Næste". Når der klikkes på "Næste", skal der testes for, at show'et kører, og der er jo netop det, det gør, hvis jeg har autovisning.

Den lille klemme kommer jeg ud af ved at oprette en ny funktion, der tester for autovisning og først derefter udløser next():

function toNext(){
  if (running==1) {
    alert("Stop autovisning \nfør du går frem")
  }
  else {
    next()
  }
}

En funktion lignende next() skal vise det foregående billede, hvis vi klikker på "Forrige":

function prev() {
  if (running==1) {
    alert("Stop autovisning \nfør du går tilbage")
  }
  else {
    skjulAlle();
    nr=nr-1;
    if (nr==0) nr=antal;
    document.images.billede.src = images[nr].src;
    setPixNrColors(nr)
    expand('pixtext' + nr);
  }
}

Den principielle forskel på de to funktioner er, at de så at sige tæller hver sin vej. I stedet for at lægge 1 til den variable nr trækker jeg 1 fra; og vendepunktet er når nr har værdien 0.

At lave funktionerne der skal vise første og sidste billede er ingen sag:

function toBegin(){
  stop()
  skjulAlle();
  visPix(1);
}
function toEnd(){
  stop();
  skjulAlle();
  visPix(antal);
}

Den sidste knast er styringen af autovisningen. Når vi nu har funktionen next() er oprettelsen af en autovisningsfunktion ret let:

function auto(){
  visObjekt('speedpanel');
  setFgColor('autoknap','white');
  setBgColor('autoknap','#c00');
  setFgColor('pauseknap','white');
  setBgColor('pauseknap','teal');
  next();
  timer = setTimeout('auto()',speed);
  running=1;
}

Som du ser har det meste af denne funktion at gøre med at vise de rette kontrolfunktioner i de rette farver. Bemærk her, at panelet, hvor man kan bestemme hastigheden, normalt ikke vises. Vi har kun brug for det, når applikationen er i automodus, og derfor gøres det synligt med det første funktionskald i auto()-funktionen.

Dernæst – når bortses fra farvesætningen – kaldes funktionen next(); denne kører i en løkke med et tidsinterval, der er bestemt af den variable speed.

Nu kører det, som de siger. Men vi må aldrig sætte noget JavaScript igang, som brugeren ikke kan stoppe igen, så derfor har jeg lavet en stop()-funktion:

function stop(){
  clearTimeout(timer)
  skjulObjekt('speedpanel');
  setFgColor('autoknap','white');
  setBgColor('autoknap','teal');
  setFgColor('pauseknap','white');
  setBgColor('pauseknap','teal');
  running=0;
  nr=1;
  visPix(nr)
}

clearTimeout() er en JavaScript-funktion, der stopper en navngiven timer, så den er ret oplagt til en stopfunktion.

Dernæst skal vi have skjult vores "speedometer" og have sat de forskellige knappers farver til normalpositionen. Til sidst sætter vi de forskellige variable til deres normalværdi og viser billede nr. 1.

Pausefunktionen er forkortet udgave af stop-funktionen:

function pause(){
  if (running == 1){
    clearTimeout(timer)
    setFgColor('pauseknap','white');
    setBgColor('pauseknap','#c00');
    running=0;
  }
}

Til allerallersidst skal vi sætte nogle farver i normalpositionen, hvilket sker gennem funktionen:

function setAllColors(){
  setColors(2)
  setPixNrColors(1)
}

og sørge for at der sker onload:

window.onload=setAllColors

Denne side er senest opdateret: 26. November, 2006