Dynamiske hjemmesider med Javascript

Tags:    javascript
<< < 123 > >>
Skrevet af Bruger #4575 @ 10.01.2005


Styring af elementer via ID



Nu da du kender det mest basale om javascripts, som brugen af variabler, løkker, if-sætninger, funktioner og events er det på tide at du kan se hvad du kan bruge javascriptet til rent praktisk, da det tidligere kun har været ret ligegyldige ting du har lært.
Jeg vil starte med at vise dig, hvordan du kan ændre teksten i et span eller div element ved identificere det via dets ID. Først skal du lave følgende fil:

Fold kodeboks ind/udKode 


Nu har du et dokument med en span og en div i sig, hvert med sit indhold, men nu skulle vi jo gerne have dem til at ændre indholdet. Først beslutter vi os, hvornår vi vil have indholdet til at ændre sig - Jeg har valgt onmouseover og onmouseout.
Nu skal vi så igang med at lave noget kode, som ændrer vores elementers indhold:

Fold kodeboks ind/udKode 


Først opretter vi en global variabel, old_content, til at indeholde det gamle indhold af elementerne, så vi kan skifte tilbage til dette, når musen bliver fjernet fra indholdet igen...
Derefter laver jeg funktionen mouseOver, som tager en parameter, som hedder ID. Det er den, som vi skal bruge til at identificere hvilket element musen er blevet ført over, når vi skal ændre indholdet.
Nu er vi så klar til at gemme det gamle indhold af dokumentet i old_content. Først identificerer vi elementet med funktionen document.getElementByID, som logisk nok finder et element med det givne ID, hvor efter vi gemmer dets indre HTML (innerHTML), eller den tekst, som står mellem <span>/<div> og </span>/</div> tags'ne, eller et hvert andet tag.
Bagefter sætter vi så den nye værdi af samme element til Musen er nu over indholdt!, så vi kan se en efekt, når musen bliver ført over elementet.
Til sidst har vi så funktionen mouseOut, som når musen bliver ført ud fra elementet sætter dets indre HTML tilbage til den gamle værdi (old_content), så vi også kan se en effekt den vej :D

Nu skal vi så bare have den til at kalde vores events ved onmouseover og out. Det gør vi sådan:

Fold kodeboks ind/udKode 


Læg mærke til, at jeg har angivet id'erne på elementerne inde i funktionerne, så de bliver gemt i ID parametret. Da vi ikke kan bruge gåseøjne ("") inde i vores onmouseover eller out bliver vi i stedet ' tegnet, da det ellers ville forvirre browserne.

Der er dog 2 ulemper ved denne funktion. Den ene har du nok lagt mærke til, da det er, at elementet bliver større eller mindre, når det dets nye værdi, hvilket er ret irriterende. Den anden er ikke lige så åbenlys, men meget mere generende, når det kommer til stykket.
Den består i, at det kun er IE 5 og opefter, Opera, Mozilla og andre nyere browsere, som understøtter document.getElementById funktionen, så hvis vi bruger en ældre browser vil vi sandsynligvis bare få en fejl. Dog er der selvfølgelig en løsning på disse problemer, så lad os kigge på det.

Fold kodeboks ind/udKode 


Vi bruger den samme kode som før, men denne gang tjekker vi hvilken browser filen bliver vist i, og bruger efter browseren den rigtige funktion til at finde elementet med. Det burde ikke være så svært at forstå nu, så jeg vil ikke beskrive det særlig meget mere.
Men det er en god ide at huske det, når man laver scripts, så de også virker i ældre browsere, da der jo næsten altid vil være nogen med ældre browsere end dig selv :)

Endelig har jeg for at fjerne det med størrelsen bare tilføjet noget style som et eksempel på at blande CSS og javascript, da vi senere vil benytte dette:

Fold kodeboks ind/udKode 


Nu har i set en måde, hvorpå man kan fange alle elementer i dokumentet, men det er faktisk lidt besværligt, hvis vi bare skal have fat på det element, som musen bevæges hen over.
Hvis vi vil gøre denne process meget lettere, uden at skulle tage højde for browser osv. kan vi benytte objektet "this". This giver en handler af det element, som man sender den fra, som når man ændrer en attribute i den også ændrer det på elementet selv.
Det lyder måske lidt uklart lige nu, men lad os lige se et eksempel:

Først laver vi nogle nye events til vores 2 elementer:
Fold kodeboks ind/udKode 


Som du kan se, så har jeg nu valgt at ændre den parameter, som javascriptet skal modtage fra ID'et på elementet til this, så vi i javascriptet kan arbejde direkte med elementet, udenom brugen af document.all, document.layers eller document.getElementById.
Men lad os også lige tage et tjek på javascriptet:

Fold kodeboks ind/udKode 


Som du kan se, så har vi undgået brugen af funktionerne, til at få fat i elementerne via deres ID, og kan nu arbejde med dem direkte fra Object parametret. Dette gør det meget lettere at lave funktionerne, da vi med denne funktion ikke behøver at tage os af hvilken browser klienterne benytter.
Dog kan du komme ud for, at du har behov for at ændre værdier i andre elementer, end det, som eventet opstod i, og i tilfælde af, at du havner i denne situation bliver du nødt til at benytte document.all/layers/getElementById...

Nu var det eksempel, som vi gjorde brug af her, ret nytteløst, da de fleste ikke ønsker at ændre indholdet af ting i elementer ved onmouseover, men hvad nu hvis man også kunne ændre layoutet af et element ved onmouseover? F.eks. kunne man ændre baggrundsfarve, tekstfarve, gennemsigtighed eller andre ting?
Det ville jo pludselig gøre det meget sjovere at lege med sine elementer i forhold til javascript, da ikke alle elementer har hover effekten som a elementet. Og selvfølgelig kan vi det... Vi kan faktisk ændre en temmelig stor del af CSS værdierne for et element via javascript, og desuden kan vi give elementet en helt ny klasse!

Lad os starte med et eksempel, hvor vi samtidig med at ændre indholdet af vores 2 elementer også tekst farven til hvid.

Fold kodeboks ind/udKode 


Som i kan se benytter vi nu værdien "style.color", til at ændre tekst farven, hvilket også for sig fungerer fint nok. Dog kan man komme i problemer, hvis man vil ændre synligheden af et element, da nyere og ældre browsere skal have forskellige værdier i forskellige attributer, for at ændre dette. Derfor plejer jeg at oprette en 2 klasser i CSS: en normal samt en til når vi har musen over elementet.
I vores nye eksempel vil vi nu ændre synligheden af det element, som musen ikke er over, så det bliver væk, men kun ændre indholdet af det element, som vi har musen over til "Ha! Nu er du væk :)".

Lad os starte med at oprette 2 klasser, en hvor elementet er "normalt" og en hvor det er usynligt:

Fold kodeboks ind/udKode 


Jeg vil ikke forklare denne kode, da jeg går udfra, at du allerede kan CSS, dog skal du lige være opmærksom på,at denne del af koden skal også stå i headeren lige over javascriptet.
Nu skal vi så have modificeret vores events i elementerne, da vi nu skal bruge 2 variabler, en til at identificere elementet, som musen blev ført over samt en til at identificere det andet element. Det gør vi sådan:

Fold kodeboks ind/udKode 


Som du kan har jeg tilføjet en ekstra parameter, så vi kan identificere det modsatte element, da vi jo som tidligere nævnt ville gøre dette usynligt.
Nu mangler vi bare javascript funktionerne, så vi kan få tingene til at hænge sammen:

Fold kodeboks ind/udKode 


Som du kan se, så bliver vi igen nødt til at tjekke browser versionen, da vi skal identificere det andet element via dets ID, men da vi først har fået gjort dette, så er det ret simpelt bare at ændre værdien className til enten "Invisible" eller "Standard". Når vi gør dette opnår vi den effekt, som er defineret for klasserne i CSS'et, så på den måde er det let at redigere i layoutet, via javascript og CSS klasser.
Som tidligere nævnt foretrækker jeg selv, at gøre brug af denne metode til at ændre i layoutet, fremfor at ændre enkelte værdier i et element, for at lave om på layoutet, da jeg dels synes, at det giver bedst overblik, og så letter det arbejdet, hvis man vil crosscode, altså lave javascripts, som virker i alle eller de fleste browsere.

Inden vi går videre vil jeg lige vise hele filen i sin sammenhæng:
Fold kodeboks ind/udKode 


Nu tror jeg efterhånden, at du er meget godt inde i det med at identificere elementerne via deres ID'er, så jeg vil nu gå videre til det endelige eksempel, hvor jeg laver en dropdown menu, hvor man kan åbne & lukke den samt vælge links via tastaturet.




<< < 123 > >>

Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.

Del også gerne artiklen med dine Facebook venner:  

Kommentarer (17)

User
Bruger #3275 @ 11.01.05 12:18
WOW...det er godt nok det længste artikel jeg nogensinde har set. Har ikke fået tygget mig igennem hele artiklen endnu men den ser spændende ud. Godt arbejde :D
User
Bruger #345 @ 11.01.05 16:35
Jeg har et par kommentarer til artiklen.
Den rækkefølge du checker for browserne i er omvendt. Du indikerer via kommentarne at du checker for IE4 via
if(document.all)

Nu er det bare sådan at alle IE versioner har document.all collectionen, og derfor vil den matche samtlige versioner, ikke kun version 4. Du bør derfor placere
if(document.getElementById)
som den første betingelse.

Dernæst er din translateKeyCode funktion langt mere kompleks end det er nødvendigt.

function translateKeyCode(code) { return String.fromCharCode(code).toUpperCase(); }

Du bruger også Object som et variabel navn. Object er en indbygget type i javascript, og det kan derfor lede til visse problemer at bruge netop det som et variabel navn. Jeg vil forslå du ændrer det til noget ala obj.

Og så lige en mindre detalje, i dit mouseOver/mouseOut script har du en lille kommentar fejl. Du indikerer at du checker for IE4, men du checker document.layers, og derfor Netscape. :)
User
Bruger #4404 @ 12.01.05 16:15
God artikkel Mads :P
Den lære man sq noget af :D
User
Bruger #4575 @ 12.01.05 19:49
Hybbe:
Tak fordi du gør opmærksom på det!.. Jeg kendte faktisk ikke til de problemet med rækkefølgen af browser tjekket samt brugen af Object som variabel navn, men jeg vil forsøge at rette det i løbet af ugen...

Hvad angår translateKeyCode, så kan jeg sq godt se at din er noget smartere :)

Jonas:
Ved godt den ser lang ud, men der er meeeget af den, som er kode eksempler...

Mere generelt... Jeg ligger og roder med et WYSIWYG Online CMS, dog endnu kun på test niveau, men er der stemning for en tutorial om det emne, når jeg engang har fået sat mig ind i hvordan man laver sådan et system?..
User
Bruger #6080 @ 15.01.05 10:52
Kanon artikel Mads

Tog dog lidt tid at tygge sig igennem men har da lært en del, så tak for det.

Ja, fra min side syntes jeg det ville være fedt med en artikel om det emne, så håber da det kommer. :D

4 hefra.
User
Bruger #4575 @ 15.01.05 11:01
Jamen så må jo se om ikke jeg inden alt for lang tid kan få skrevet en artikel om det emne...

Jeg tror dog, at jeg inden det lige vil skrive en artikkel om avanceret javascript, som string handling, at lave sine egne objekter samt image preload, da jeg allerede nu bruger disse ting meget i mit CMS.
User
Bruger #7227 @ 09.02.05 14:58
Det er svært at vide, hvor man skal starte og hvor man skal slutte :)

Skriver du noget somhelst før din DTD, disabler du IE's mulighed for at gøre brug af en meget væsentlig del af CSS-standarden - box-modellen. Altså slet din XML-prolog (du har ikke brug for den, da du alligevel ikke kan skrive XHTML).
Du kan teste din sides CSS-kompatibillitet med følgende. der skal returnere 'CSS1Compat':

<script type="text/JavaScript">
document.compatMode()
</script>

Læs evt. mere her (specielt under The !DOCTYPE "Switch"):
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnie60/html/cssenhancements.asp

Dernæst er det at skifte klasse temmelig dårlig kodeskik. Når en CSS-klasse skiftes på et element, spytter browseren et helt nyt DOM-træ ud, som kræver en genberegning af hele dokumentet ... det er yderst dårligt performende.
Langt bedre er det at skifte de enkelte style-properties på elementet. Det kan nu også gøres ganske 'sexy':

<script type="text/JavaScript">
var stylesA = {
"color": "#ff0000",
"backgroundColor": "#ffff00",
"border": "1px solid #ff0000",
};
var stylesB = {
"color": "#ffff00",
"backgroundColor": "#ff0000",
"border": "1px solid #ffff00",
};
function swapStyles(elm, styleObj) {
for (x in styleObj) elm.style[x] = styleObj[x];
}
</script>

<div onmouseover="swapStyles(this, stylesA)" onmouseout="swapStyles(this, stylesB)">TEST</div>

- hvilket giver browseren langt mindre at svede over - og dermed er betydeligt bedre.

Til slut kommer vi så til det spørgsmålet om XHTML:
Sagen er, at XHTML ikke kan bruges på ordentlig måde på nettet, som dette ser ud idag. Faktisk parses stort set al XHTML idag som dårlig HTML4-kode.
Dels fordi, der er så få, der overhovedet _kan_ kode XHTML (det er nemlig *meget* mere end blot at lukke tags og skrive med småt) - dels fordi, den ultimativt største browser (IE6.0) kun understøtter XHTML, hvis XP er opdateret med SP2 ... og så ikke engang fuldt ud.

Du bruger både document.write og innerHTML på trods af, at disse to hører til HTML-DOM'en og ikke kan bruges under XHTML. Gør man det alligevel, tvinger man browseren til at parse siden som HTML4 - men koden må altså parses som fejlfyldt HTML4, da den er fyldt med ' />', som HTML-parseren ikke kender ... og en forkert DTD i forhold til indholdet.
Det samme gælder f.eks. for document.images og document.forms. De tilhører også HTML-DOM'en og kan således ikke bruges under XHTML.

I virkeligheden er din XHTML-kode langt dårligere, end hvis du havde skrevet i HTML4.01-Strict.
Jeg tror, du bør læse noget helt grundlæggende om XHTML, da der tydeligvis er en hel del ting, du slet ikke har forstået. Prøv f.eks. at begynde her:
http://www.eksperten.dk/artikler/537
http://www.eksperten.dk/artikler/538
- hvor jeg har forsøgt at få styr på nogle af de grundlæggende misforståelser omkring XHTML, der hærger nettet - og som din artikel er et udmærket eksempel på.

Jeg giver ikke laveste karakter, da der trods alt er huller mellem fejlene :)
/mvh
User
Bruger #7227 @ 09.02.05 15:20
PS: Jeg manglede alert'en :o)

<script type="text/JavaScript">
alert(document.compatMode)
</script>
User
Bruger #4575 @ 20.02.05 14:29
Til Ole Clausen:
Kan godt se du har ret angående problemerne med XHTML'en ;)
Hvad angår det med klasse skift fra javascript ved jeg godt, at det kan være et problem at gøre det på den måde, som jeg har vist her - Men da det skulle være en relativt simpel artikkel har jeg valgt at vise klasse skift frem for ændringer af attributerne hver for sig (Jeg vidste faktisk ikke man kunne gøre som du viser).
Hvad det problem angår vil jeg så tilgengæld i næste artikkel vise hvordan man laver en klasse, som kan bruges til at ændre attributer osv. for et element, hvilket jeg generelt foretrækker fremfor at skulle identificere elementet hver gang :)

Men ellers tak for kritikken...! Den var konstruktiv og kan helt sikkert bruges i den næste artikel (og evt. videre artikler)...
User
Bruger #7227 @ 25.02.05 02:32
Hej igen Mads :)

Det glæder mig, du får noget ud af mine udgydelser. I den forbindelse - og da du skriver, du ikke kendte metoden, jeg viste til property-skift - kunne det være, du også skulle læse denne:
http://www.eksperten.dk/artikler/227
- hvor jeg prøver at gøre rede for det nære slægtskab mellem JS-objekter og JS-arrays :)
/mvh
User
Bruger #4575 @ 27.02.05 15:53
Det vil jeg da gøre :)
Dog... Jeg er lidt overbebyrdet med lektier & arbejde for tiden, så jeg får desværre ikke tid til at ændre artiklen foreløbig, men jeg vil ordne det hurtigst muligt!
User
Bruger #4575 @ 15.04.05 13:44
Har indsendt en rettet version til godkendelse, så nu er der bare tilbage at vente på, at den bliver godkent :)
User
Bruger #7553 @ 04.06.05 02:05
Har lige et spørgsmål kun hvofor gør du den ik lidt kortere og vælger at lave en style.css eksempel. Men ellers meget god.. :)
User
Bruger #4575 @ 17.06.05 22:36
Har rettet den, så den er blevet væsentligt kortere, men er desværre ikk blevet godkendt (eller afvist) endnu :|
User
Bruger #5062 @ 15.07.05 14:30
Dobbelt op på super duper mega giga onderen total niceren sej artikel dér!
User
Bruger #7812 @ 05.11.05 01:31
Jah! er færdig med den!

Mega godt skrevet Go artikel
User
Bruger #9674 @ 29.11.06 16:00
Rigtig god artikel som man kan lære rigtig meget af...

Nogle enkelte småfejl, men blot taste fejl, ellers fejl fri efter min forståelses evne...

Den sikrer ens basiks med JS og har givet mig en del videre muligheder...
Du skal være logget ind for at skrive en kommentar.
t