Grafisk rollover med ringe tyngde

Her introducerer jeg idéen om en grafisk rollover med ringe båndbredde – det vil sige med den lavest mulige grafikvægt. Stylesheet, JavaScript, HTML-kode samt billeder vedr. demo'en på denne side kan du downloade i form af en zip-fil.

Lidt længere nede på siden ser du en grafisk rollover med 7 menupunkter. Skulle den laves på normal måde, ville det kræve 10 grafiske knapper. I stedet nøjes jeg med to grafiske knapper. Den potentielle besparelse i grafik-vægt er ganske betydelig. Så, hvordan gør jeg dette?

Indledningsvis skal du vide, at menubjælken i virkeligheden består af to næsten ens grafikker, stablet oven på hinanden. HTML-koden til menubjælken ser således ud:

<div id="menucontainer">
<div id="menuoff">
<img src="/cssbog/kildekode/res/grafiskmenuoff.png" 
width="419" height="56" alt=" " usemap="#mover" />
</div>
<div id="menuon">
<img src="/cssbog/kildekode/res/grafiskmenuon.png" 
width="419" height="56" alt=" " usemap="#mover" />
</div>
</div>

HTML-koden

  1. #container er en relativt positioneret kasse, der for det første placerer menubjælken der på siden, hvor jeg ønsker den, og for det andet danner en referencerammer for de to div'er, der er inde i denne ydre kasse.
  2. #menuoff og #menuon er de to indre kasser, der via et stylesheet er absolut positioneret i forhold til kassen #container, på en sådan måde, at de ligger oven over hinanden. Den orden, de indlæses i, bestemmer stakkeordenen - det vil sige, det sidst indlæste element vil altid blive placeret oven på et tidligere indlæst element, hvis de to elementer helt eller delvist skal være på det samme areal.
  3. Det vil sige, vi skulle se billedet panelon.gif, der er indeholdt i kassen #menuon. Jeg har imidlertid gjort denne kasse, og dermed også dette billede, usynligt (jf. stylesheet'et længere nede på siden). Det betyder, at det billede, vi faktisk ser, er menuoff.gif.
  4. Billederne er forsynet med usemap-attributten, der refererer til map-markøren #mover. Dette map skal jeg bruge til at holde styr på, hvor musen befinder sig. Jeg er nødt til at knytte referencen til begge billeder, fordi musen somme tider vil være over det ene, andre tider over det andet. map-markøren indeholder det koordinat-sæt, der beskriver billedets enkelte menupunkter:
    <map id="mover">
    <area alt="" coords="0,0,57,56" 
    onmouseover="mover(1,true)" 
    onmouseout="mover(1,false)" 
    href="javascript:void(null)">
    <area alt="" coords="58,0,117,56" 
    onmouseover="mover(2,true)" 
    onmouseout="mover(2,false)" 
    href="javascript:void(null))">
    <area alt="" coords="118,0,177,56" 
    onmouseover="mover(3,true)" 
    onmouseout="mover(3,false)" 
    href="javascript:void(null)">
    <area alt="" coords="178,0,238,56" 
    onmouseover="mover(4,true)" 
    onmouseout="mover(4,false)" 
    href="javascript:void(null)">
    <area alt="" coords="239,0,299,56" 
    onmouseover="mover(5,true)" 
    onmouseout="mover(5,false)" 
    href="javascript:void(null)">
    <area alt="" coords="300,0,360,56" 
    onmouseover="mover(6,true)" 
    onmouseout="mover(6,false)" 
    href="javascript:void(null)">
    <area alt="" coords="361,0,419,56" 
    onmouseover="mover(7,true)"
    onmouseout="mover(7,false)" 
    href="javascript:void(null)">
    </map>
    
  5. Læg mærke til mouseover og mouseout event handlerne, der udfører et funktionskald med dels et tal og dels en boolsk variabel til funktionen mover().

Stylesheet'et

#container {position:relative; 
  margin:10px 20px; height:30px; }
#menuoff {position:absolute; left:0; top:0; 
  visibility:visible; }
#menuon {position:absolute; left:0; top:0; 
  visibility:hidden; }

- er der ikke mange ben i. Bemærk dog visibility-attributten.

Ideen

- med alle disse forberedelser er en modernisering af et script, jeg fandt for 4-5 år siden i artiklen Low Bandwidth Rollover på webreference.com. Jeg har skrevet lidt om det i forbindelse med min forklaring på, hvordan du kan lave en Alfabet-rollover. Det, øvelsen her går ud på, er at 1) ved hjælp af clip-attributten at beskære den underste grafik således at kun det aktuelle menupunkt er tilbage, og 2) derefter gøre dette synligt.

Scriptet

Det er lettere sagt end gjort, men her er i hvert fald scriptet, der virker i alle moderne (DOM-kompatible) browsere:

<script type="text/javascript">
/*<![CDATA[*/
var dom = (document.getElementById) ? true : false;
if (!dom || document.layers){
alert("Denne webside fungerer kun \ni moderne browsere.")
}
arealArray = new Array()

function setAreal(nr,fra,til) {
  arealArray[nr] = new Array();
  arealArray[nr][0] = fra;
  arealArray[nr][1] = til;
}
  setAreal(1,0,58);
  setAreal(2,59,117);
  setAreal(3,118,177);
  setAreal(4,178,238);
  setAreal(5,239,299);
  setAreal(6,300,360);
  setAreal(7,361,419);
  clTop = 0;
  clBot = 56;
    
function mover(nr,on) {
  menupunkt = document.getElementById('menuon').style 
  
  if (!on) { 
  menupunkt.visibility = "hidden"; 
  return 
  }
  
  clLeft = arealArray[nr][0];
  clRight = arealArray[nr][1];
  menupunkt.clip = "rect(" + clTop + "px " 
  -->  + clRight + "px " + clBot + "px " + clLeft + "px)";
  menupunkt.visibility = "visible" 
}
/*]]>*/
>/script>

Dele af scriptet har jeg skamløst hugget fra ovennævnte reference. Her er, hvad der sker:

  1. Jeg tester for, om det er en DOM-kompatibel browser og spiser alle andre browsere af med en advarselsboks.
  2. En mouseover- eller mouseout-event kalder funktionen mover(nr,on), der fortæller os, hvilket menupunkt, der er tale om, samt passerer en true eller false værdi til flaget on.
  3. Funktionen tildeler den variable menupunkt en værdi svarende til style-objektet menuon.
  4. Hvis on er false ((!on)), skal et synligt menuon-menupunkt skjules.
  5. Hvis on derimod er true – det vil sige onmouseover – falder funktionen igennem til der, hvor tingene sker:
  6. clipTop og clipBottom-værdierne har jeg fra nogle faste variable. Der er jo ingen ændring i disse.
  7. Værdierne for clipLeft (clLeft) og clipRight (clRight) skal jeg derimod hente fra et flerdimensionelt array, som jeg aftaster ved hjælp af det tal (nr), jeg fik fra mouseover- og mouseout-funktionskaldet, og som indeholder referencerne til mit Image Map (map-markøren).

Supplerende bemærkninger

Det er så det. Jeg har kreeret en rollover med 7 menupunkter, der bygger på kun 2 grafikker i stedet for 14. Du kan lave præcis mage til ved at downloade en zipfil, der indeholder billeder, JavaScript, HTML-kode mm. til denne rollover. Det er et godt udgangspunkt for at lave din egen af slagsen. (Download eksemplet).

Hvis jeg havde lavet hvert menupunkt som 2 enkelte PNG-billeder, ville de fylde ca. 3 kilobytes per styk, således at hele rolloveren på den sædvanlige måde ville fylde ca. 42 kilobytes. De to grafikker, jeg anvender her, fylder tilsammen ca. 18 kilobytes. Der er altså sparet 24 kilobytes eller ca. 60 procent.

Mere komplicerede grafikker og mange af dem vil kun understrege fordene ved denne metode. Det har jeg illustreret i eksemplet Alfabet-rollover, der igennem et par år – før 1998, hvor jeg læste artiklen på webreference.com – var nøglen til personaleoversigten på Ikast Handelsskoles website.

Den samlede tyngde af de mange bogstav-grafikker i denne rollover er ca. 50 kilobyte.

Ved hjælp af den her beskrevne teknik lavede jeg så, da jeg havde fundet ud af hvordan, en nyere alfabet-rollover. Den samlede tyngde af de to – ganske vist lidt mindre iøjnefaldende – grafikker er 2200 bytes. Fra 50 kilobyte til 2,2 kilobyte, det er da noget, der rykker!

Siden gik jeg over til at lave denne rollover udelukkende ved hjælp af et stylesheet, som beskrevet på websiden Alfabet-rollover med CSS. Det er den teknik, jeg vil anbefale dig at bruge, eftersom overførselstiden er minimal i forhold til en hvilkensomhelst grafisk rollover.

Er du alligevel forhippet på at lave en grafisk rollover, er der for mig ingen tvivl om, at du skal anvende den her beskrevne teknik. Der er altid meget store beparelser at hente i overførselstid for en minimal investering i ekstra arbejdstid.

Jeg skal lige understrege, at det er uproblematisk at lave en lodretstillet menu ved hjælp af denne teknik. Det eneste, der skal ændres, er indholdet af map-markøren, og som følge deraf også af array'et setAreal. Skal du bruge menuen på flere sider, bør du læse min artikel om Genbrug af MAP-informationer.

Og til allersidst et par ord om browserkompatibiltet: Denne udførelse er testet i Internet Explorer 6, Opera 7, Mozilla 1 og Netscape 6.2, som forventeligt uden problemer. Den vil ikke fungere i Internet Explorer 4 og Netscape 4 og heller ikke i endnu ældre browsere. JavaScript-koden i de to ældre eksempler, der er nævnt i dette afsluttende afsnit, giver dig anvisninger på, hvorledes du kan opnå den samme funktionalitet i Internet Explorer 4 og Netscape 4, samt bevare den grundlæggende funktionalitet i endnu ældre browsere.

Under alle omstændigheder bør du for tilgængelighedens skyld anvende en mindre brutal browserfiltrering end den, jeg har anvendt i det her beskrevne eksempel.

1 2 3 4 5 6 7 8 9 10

Denne side er senest opdateret: 16. January, 2007