Markering af nye oplysninger

På nogle websider kan det være godt at oplyse brugeren om, hvilke blandt muligvis mange oplysninger der er nyere end andre.

Du kan naturligvis sætte en dato i den linie eller det afsnit, det drejer sig om, men det er jo ikke særligt iøjnefaldende.

Derfor har jeg igennem adskillige år brugt en lille grafik som den du ser her til venstre.

Det er der jo ikke noget særligt ved. Det særlige er her, hvad du ikke ser, nemlig at grafikken forsvinder af sig selv efter et vist tidsrum. Kildekoden til afsnittet med grafikken ser således ud:

<p><span id="nyt"></span>
Derfor har jeg igennem adskillige år ... </p>

I begyndelsen af afsnittet er indsat et tomt span-element med en id="nyt". Dette element kan jeg referere til ved hjælp af en variabel blok, som indgår i funktionen markerNyt():

function markerNyt(){
  var blok=document.getElementById("nyt")
	var pic = "/javascript/res/ny.gif";
	var expdate = new Date("12/31/2010");
	var curdate = new Date();
	if (expdate.getTime() > curdate.getTime()){
    blok.innerHTML= "<img align='absmiddle' src=" + pic + " + >";
  }
}
onload=markerNyt;

I denne funktion sætter jeg først den variable blok. Dernæst en variable pic, der indeholder stien til den lile grafik, jeg ønsker indsat. Læg mærke til den root-relative sti, jeg anvender, og som gør, at jeg kan anvende scriptet på en vilkårlig side, og stadigvæk være sikker på, at grafikken kan indlæses, uanset hvor i foldersystemet på mit website, websiden befinder sig.

En skråstreg foran en stiangivelse er en kortformsudgave af den fulde, absolutte sti. I det aktuelle tilfælde svarer /javascript/res/ny.gif således til http://www.webdesign101.dk/javascript/res/ny.gif. Fidusen er – bortset fra, at det er lettere at skrive – at browseren ikke skal hele vejen rundt om en DNS for at finde grafikken. Ulempen er, at du kun kan bruge tricket via en server. Du kan altså ikke bruge det, hvis du blot indlæser dine websider som filer fra harddisken.

Herefter oprettes to variable, der indeholder to tidspunkter – hhv en udløbsdato (expiredate, der indeholder det tidspunkt, vi har passeret til funktionen), og en aktuel dato (currentdate, der til enhver tid indeholder den aktuelle dato.

Så sammenlignes de to variable expiredate og currentdate, og hvis expiredate er større end currentdate, udløses innerHTML-funktionen for elementet blok.

Hvis betingelsen ikke er opfyldt sker der ingenting. Grafikken skrives ikke ind på siden efter at expiredate er oprundet.

En alternativ måde

En bagdel ved den beskrevne metode er, at du skal indsætte et tomt element, som ikke har andet formål end agere et objektmål for en eventuel grafik, som før eller siden skal forsvinde. Desuden er det ikke synderlig smart at bruge en id, eftersom vi ofte vil have flere end ét element, vi kan ønske at markere på denne måde.

For eksempel ser du til venstre for disse afsnit den samme grafik. De er indsat, fordi elementerne er forsynet med en class="note". Det script, der sørger for det er følgende:

function init(){
var expdate = new Date("12/31/2010");
var curdate = new Date();
if (expdate.getTime() > curdate.getTime()){
  var newsArray = getElementsByClassName("note");
  for (i=0;i<newsArray.length;i++){
    var nytPix = document.createElement("span");
    nytPix.setAttribute("id","nyt");
    var pix = document.createElement("img");
    pix.setAttribute("src","res/ny.gif");
    pix.setAttribute("width","38");
    pix.setAttribute("height","14");
    pix.style.verticalAlign="middle";
    pix.style.position="relative";
    pix.style.marginLeft="-40px";
    pix.style.zIndex="1";
    nytPix.appendChild(pix)
    var spanElement=newsArray[i];
    spanElement.appendChild(nytPix);
    var flytElement=spanElement.insertBefore(nytPix, 
    -->  spanElement.firstChild);
    }
  }
}
onload=init;

Der er flere bemærkninger at gøre til dette:

  1. Jeg bruger W3C DOM funktionen document.createElement() i stedet for innerHTML. Det er for at slippe for overflødig opmærkning i kildekoden.
  2. I stedet har de elementer, der skal forsynes med grafikken, fået et class name class="note".
  3. Dato-sammenligningsfunktionen er præcis den samme som i det foregående eksempel. Hvis datoen er mindre end nytårsaftensdag 2010 oprettes et JavaScript Array bestående af alle de elementer, der har klassenavnet "note".
  4. Til at udføre
    document.getElementsByClassName("klassenavn")
    bruger jeg en modulfunktion, kodet af Robert Nyman og som kan findes i Googles kodebibliotek. W3C's DOM Level 3's tilsvarende metode laver ikke et sandt JavaScript Array, og understøttes kun sporadisk af dagens browsere. Denne funktion indlæses separat.
  5. for-løkken gennemløber Array'et newsArray, og for hvert element i dette Array oprettes et span-element.
  6. Dette element får får en id="nyt".
  7. Dernæst oprettes et nyt img-element.
  8. Dette img-element påtrykkes i de følgende 3 kodelinjer nogle attributter, src, width og height, og i de næste 4 kodelinjer nogle CSS-egenskaber.
  9. pix-elementet oprettes som barn (child) af span-elementet.
  10. span-elementet oprettes for hvert objekt i newsArray.
  11. Og til sidst flyttes nytPix-objektet til “positionen” som firstChild (af p-elementet). (Tak til Birger Sørensen i Usenet nyhedsgruppen om JavaScript for at retlede mig omkring dette sidste).

Hele denne sag kan laves adskilligt mere elegant, men både for min egen og mine læseres skyld foretrækker jeg den trinvise og mere læselige metode.

En alternativ måde

Du kan også ved hjælp af den samem dato-sammenligningsfunktion udføre nogle mere simple ændringer af udvalgte tekstafsnit, for eksempel:

function kolorerNyt() {
var expdate = new Date("12/31/2010");
var curdate = new Date();
  if (expdate.getTime() > curdate.getTime()){
    var obsArray = getElementsByClassName("obs");
    for (i=0;i<obsArray.length;i++){
    obsArray[i].style.color="maroon";
  }
}
onload=kolorerNyt;

Disse afsnit er koloreret rødbrune af funktionen ovenfor. Selve kodeeksemplet viser, at funktionaliteten er bevaret, selv om dette tekststykke har to klassenavne.

Kildekode

Al den kode jeg har skrevet om er indsat i sidens head-del, og kan kopieres ved hjælp af browserens Vis kildekode funktion. Det er en anelse mere kompliceret end det behøver at være, fordi jeg på samme side beskriver tre forskellige metoder til at fremhæve visse tekststykker. Kernefunktionen kan du downloade her: markernyt.js. Grafikken må du selv sørge for. Husk at intet af dette vil fungere uden Robert Nymans kodemodul.