De HTML / Attribute methode
Tot op heden hebben we javscript op een verkeerde manier gebruikt. Door HTML te vermengen met javascript wordt de bedoeling van HTML misbruikt. (HTML is voor betekenis en nergens anders voor). Net als CSS willen we de javascript Helemaal los koppelen van de HTML. Gelukkig hebben we daar de mogelijk toe.
Naast het feit dat we de javascript gaan los schrijven van de HTML willen we ook dat javascript alleen zo wordt ingezet dat het de dagelijkse gang van zaken niet wordt verstoord. Javascript kan eigenlijk alleen worden ingezet op een manier zodat als het niet aanwezig niet rare dingen gaat opleveren voor de HTML pagina. Dus bijvoorbeeld het verbergen van bepaalde elementen (display:none) met css en aanzetten door middel van een event met javascript is dus uit den boze. Dit zou javascript dus beide moeten doen uitzetten en doormiddel van een event aanzetten. Als javascript er dan niet is zie in iedergeval alles als gebruiker.
Er bestaan ongeveer 3 manieren (of twee het is maar hoe je het
ziet). om javascript te implementeren.
manier 1 is volledige gescheven in de HTML,
manier 2 is gedeeltelijk in HTML (events) en een
extern javascript document en manier 3 volledige
gescheiden.
Manier 1
Deze manier is inde voorgaande lessen behandeld. In hetvoorbeeld hieronder zie je dat de anchor een onclick event attribute heeft. Deze haalt een javascript functie op die wordt uitgevoerd
...<p>Hier staat dus wat tekst en een <a id="klikker" href="http://www.hro.nl" onclick="message(this.href);" >link</a> en de tekst gaat door</p>... <script> function message(href){ alert('Je heb de url '+ href + ' opgevraagd'); } </script>
Manier 2
Is eigenlijk hetzelfde maar dan de functie geplaatst in een extern .js bestand. Na wat onderzoek van mij op het internet en om dat de functie van toepassing is op de reeds aanwezige elementen in de HTML, is het goed om de koppeling van het document aan het einde van het HTML document te plaatsen. Dit levert minder fout meldingen (door dat het element nog niet bestaat) en levert vooral bij IE een preformance winst op. Zet het gelinkte document dus buiten de body onderaan
<script language="JavaScript" type="text/javascript" src="external.js"></script>
In je javascript kun je vervolgens (zonder (html) <script> tag) al je javascript functies schrijven. Het event dat de functie aanroept staat echter nog in de HTML en dat willen we eigenlijk ook niet.
...<p>Hier staat dus wat tekst en een <a id="klikker" href="http://www.hro.nl" onclick="message(this.href);" >link</a> en de tekst gaat door</p>...
Manier 3
Deze manier zit wat ingewikkelder in elkaar dan de voorgaande. Bekijk eerst het onderstaande voorbeeld.
...<p>Hier staat dus wat tekst en een <a id="klikker" href="http://www.hro.nl">link</a> en de tekst gaat door</p>... <script> document.getElementById('klikken').onclick = function () { alert('Je heb de url '+ this.href + ' opgevraagd'); } </script>
In de HTML staat een in geval een a met een id="klikken". Deze kan met javascript worden aangewezen met een document.getElementById('id'). Als je er doormiddel van een punt notitie een event aan koppelt en javascript vertelt dat dat een functie is dan kun je er tussen de accolades vanalles tussen zetten. Alle inhoud en attributes zijn te benaderen via het this object. Dus in dit geval this.href.
Meedere functies verzamelen + getElementsByTagName();
Vaak is het zo dat functies van toepassing zijn op het zelfde soort links. Stel je wil aangeven dat gebruiker bezig is het scherm te verlaten om naar een andere site gaan. (Ik weet het is een slecht voorbeeld aangezien dat mensen je site nu eenmaal verlaten: ik zocht een eenvoudig voorbeeld). Alle links hebben de potentie om de gebruiker dit te laten doen. Nu wil ik niet voor elke link een aparte functie schrijven. Maar een algemene functie schrijven voor elke link. Dit kan met getElementsByTagName (Let op de s). Als men deze functie op roept dan krijgen we alle elementen terug die hier aan voldoen. De tagnames moeten geschreven worden in capitalen. Dus in het onderstaande voorbeeld staan meerdere links in het HTML document.
### HTMLdoc.html ###
...
<p>Hier staat dus wat tekst en
een <a href="http://www.hro.nl">link</a> en
de tekst gaat door en nog een <a href="http://startpagina.cmd.hro.nl">link</a>
enz enz</p>
...
We linken naar een javascript document en maken een array aan voor alle links.
... <script src="alerts.js" type="text/javascript"></script> ... ### alerts.js ### var all_links = new Array(); all_links = document.getElementsByTagName('a'); // Let op met een Hoofdletter 'A' en een s achter de Elements: getElementsByTagName
all_links is nu gevuld met alle links in de pagina. Wat vervolgens willen is dat alle links een functie krijgen die afhankelijk is van het onclick event. Dit kunnen we doen door een forloop te gebruiken. We loopen door alle links en koppelen er een onclick event aan. Dit zie je in het onderstaande voorbeeld.
for(var i=0 ; i < all_links.length ; i++){ all_links[i].onclick = function(){ alert('Je heb de url '+ this.href + ' opgevraagd'); return false; // laat de browser niet naar de link gaan } }
Het koppelen van een event gebeurt door de het opgeroepen element: all_links[i] met een punt "." teverbinden en het betreffende event: onclick er achter te schrijven in dit geval: all_links[i].onclick. Daarna vertellen we javascript dat het een functie is. Dit doen we door na de koppeling achter het "="-teken function () te schrijven. Je browser begrijpt nu dat als er op een link wordt geklikt dat de gekoppelde functie uitgevoerd moet worden. Binnen de functie kunnen de attributen van het element worden opgevraagd met this. In dit voorbeeld dat href. Welke gealert wordt.
Complexere For loops
Soms willen we eerst filteren om een bepaald element wel in een array te zetten. Doormiddel van een test kunnen we bepalen of een elment in een array moet komen. Als bevoorbeeld kijken naar het volgdende voorbeeld:
### HTMLdoc.html ### ... <p>Hier staat dus wat tekst en een <a href="#">link</a> en de tekst en <a class="external" href="http://www.hro.nl">link</a><br/> en de tekst en <a href="images/plaatje.jpg">link</a><br/> en de tekst en <a class="external" href="http://bosys.cmd.hro.nl">link</a><br/> en de tekst en <a class="external" href="http://startpagina.cmd.hro.nl">link</a><br/> enz enz</p> ...
Wat we willen is dat alleen de links (a) met een class genaamd = "external" worden gealert niet de interne links. Deze class zou ook gebruik kunnen worden voor het uiterlijk maar dat is secundair. We passen een zelfde soort aanpak toe als eerder: getElementsByTagName('a') maar we maken naast de all_links array een andere namelijk external_links array aan. Vervolgens doen we een loop door de all_links om de external_links te vullen. Daarna zullen we door de external_links loopen en het event en functie koppelen.
### alerts.js ### //stap 1: alle links ophalen en in een array stoppen var all_links = new Array(); all_links = document.getElementsByTagName('a'); //stap 2: de links filteren en in een nieuwe array stoppen met alleen de externe links //Maak een nieuwe lege array aan voor de externe links var external_links = new Array(); // loopen door alle links en filteren for(var i=0, k=0 ; i<all_links.length ; i++){ all_links[i].onclick = function() { //test if class = external: filter if (all_links[i].className == 'external'){ external_links[k] = all_links[i]; k++; } } }
Wat anders is dan anders is het feit dat de forloop begint met twee indexen: i en k. Dit is mogelijk. Het is mogeijk om een for loop te beginnen, alleen de i wordt op gehoogt door de loop zelf. De k wordt alleen verhoogt als de voorwaarde wordt verhoogt. Het hoeft niet op deze manier maar dit is wel de mooiere manier. Een andere mogelijkheid is door een push uit te voeren external_links: external_links.push(all_links[i])
// stap 3: aan elke externe link vertellen wat er moet gebeuren als er op wordt geklikt // loopen door goede links en event koppelen for(i=0; i<external_links.length; i++){ external_links[i].onclick = function () { alert('Je heb de url '+ this.href + ' opgevraagd'); return false; } }
De laaste is al eerder vertoond, maar dan met een andere array