javascriptcursus/hoofdstuk_7.php

<?php // Includes: require_once 'php/bookpage.php'; // Page: // H7 $page = new bookpage(7); $page->addContent('<p>Je wil vaak dat er iets gebeurt op het moment dat de gebruiker ergens op klikt, op een toets drukt of iets anders doet. Events maken dit mogelijk.</p>'); // H7.1 $page->nextSubChapter(); $page->addContent('<p>Een event is letterlijk een gebeurtenis. Als een event wordt getriggerd (in werking gesteld), voert die de toegekende code uit. In andere woorden: je kan dus bepaalde code laten uitvoeren bij een bepaald event (gebeurtenis).</p>'); // H7.2 $page->nextSubChapter(); $page->addContent('<p>Een event gebeurt altijd bij een bepaald element. Als er bijvoorbeeld op een knop geklikt wordt, zal die knop een onclick event triggeren. Welke events er allemaal zijn komt in '.$page->generateLinkToH(7, 3).', nu houden we het even bij het onclick event van een knop.</p>'); $page->addContent('<p>Je kan in de HTML-code events toekennen aan elementen. Dan zijn ze gewoon een attribuut:</p>'); $page->addHTML('<button onclick="javascript hier">Klik hier!</button>'); $page->addContent('<p>Maar het is beter om de JavaScript en HTML geheel gescheiden te houden. Dus zullen we de events via JavaScript moeten toekennen. Daarvoor moet er eerst een functie gemaakt worden die uitgevoerd moet worden bij dat event. Vervolgens kan die functie aan het event worden toegekend.</p>'); $page->addJS('// Functie voor het even maken function functieBijEvent() { alert("Je klikte!"); } // Functie aan het event toekennen document.getElementById("knop").onclick = functieBijEvent; // Let op, nu geen () gebruiken'); $page->addHTML('<button id="knop">Klik hier</button>'); $page->addContent('<p>Merk op dat er bij het toekennen aan het event geen ( ) gebruikt wordt. Je roept de functie immers niet aan, maar je ken hem toe.</p>'); $page->addContent('<p>Er wordt hier ook gelijk een nieuwe functie ge&iuml;ntroduceerd: '.$page->inlineJS('document.getElementById()').'. Waarom hier <i>document.</i> voor de functie staat komt in '.$page->generateLinkToH(9, 4).' aan bod, zie het voor nu maar als deel van de naam van de functie. Deze functie geeft een variabele terug die verwijst naar het HTML-element met het opgegeven id. Dat HTML-element moet dus wel bestaan. Via de verwijzing naar dat HTML-element kunnen dus de events (en meer, maar dat komt in '.$page->generateLinkToH(10, 4).' aan bod) ervan aangepast worden</p>'); $page->addContent('<p>Alleen gaat dit niet helemaal goed als de JavaScript voor het HTML-element komt in de pagina. Want dan wordt eerst de JavaScript uitgevoerd en dan pas het HTML-element aangemaakt. Wat betekent dat het HTML element met het id <i>knop</i> nog niet bestaat zodra de JavaScript wordt uitgevoerd en dus kan er geen event aan toegekend worden. Om dit op te lossen kan een ander event gebruikt worden dat wel vanaf het begin bestaat: '.$page->inlineJS('window.onload').'. Dit event wordt getriggerd op het moment dat de pagina geladen is, en omdat je hier geen HTML element aanspreekt heb je niet het probleem dat het element mogelijk nog niet bestaat. We maken dus een functie die alle andere events toekent, en we kennen die functie toe aan het '.$page->inlineJS('window.onload').'-event.</p>'); $page->addJS('function functieBijEvent() { alert("Je klikte!"); } function maakEvents() { // Events voor de HTML-elementen aanmaken: document.getElementById("knop").onclick = functieBijEvent; } window.onload = maakEvents; // Functie maakEvents() wordt aangeroepen als window.onload getriggerd wordt // In die functie worden de rest van de events toegekend aan hun HTML-elementen // Omdat window.onload pas getriggerd wordt als alles geladen is bestaan alle HTML-elementen al'); $page->addHTML('<button id="knop">Klik hier</button>'); // H7.3 $page->nextSubChapter(); $page->addContent('<p>Er zijn heel veel events, de volgende events gelden voor elk HTML-element:</p>'); $page->addContent($page->createWhiteBlock('<table>'. '<thead><tr><td>Event</td><td>Wordt getriggerd als...</td></tr></thead>'. '<tbody>'. '<tr><td>onblur</td><td>... een element de focus verliest</td></tr>'. '<tr><td>onclick</td><td>... er op het element geklikt wordt</td></tr>'. '<tr><td>ondblclick</td><td>... er op het element gedubbelklikt wordt</td></tr>'. '<tr><td>onfocus</td><td>... het element de focus krijgt</td></tr>'. '<tr><td>onkeydown</td><td>... er een toets wordt ingedrukt</td></tr>'. '<tr><td>onkeypress</td><td>... er een toets wordt ingedrukt of ingedrukt is</td></tr>'. '<tr><td>onkeyup</td><td>... er een toets los gelaten wordt</td></tr>'. '<tr><td>onmousedown</td><td>... een muisknop ingedrukt wordt</td></tr>'. '<tr><td>onmousemove</td><td>... de muis beweegt</td></tr>'. '<tr><td>onmouseout</td><td>... de muis uit het element weg beweegt</td></tr>'. '<tr><td>onmouseover</td><td>... de muis over het element heen beweegt</td></tr>'. '<tr><td>onmouseup</td><td>... de muisknop losgelaten wordt</td></tr>'. '<tr><td>onresize</td><td>... een scherm of frame van grootte verandert</td></tr>'. '</tbody>'. '</table>', null, false)); $page->addContent('<p>De volgende events worden maar door enkele elementen ondersteund:</p>'); $page->addContent($page->createWhiteBlock('<table>'. '<thead><tr><td>Event</td><td>Wordt getriggerd als...</td><td>Elementen</td></tr></thead>'. '<tbody>'. '<tr><td>onchange</td><td>... de inhoud van een invoerveld verandert</td><td>'.$page->inlineJS('<input type="text"> <textarea> <select>').'</td></tr>'. '<tr><td>onerror</td><td>... er een fout optreedt tijdens het laden van een document of plaatje</td><td>'.$page->inlineJS('<img> <object> <style>').'</td></tr>'. '<tr><td>onload</td><td>... een pagina of plaatje geladen is</td><td>'.$page->inlineJS('<img> <body>').'</td></tr>'. '<tr><td>onselect</td><td>... de inhoud van een invoerveld geselecteerd wordt</td><td>'.$page->inlineJS('<input type="text"> <textarea>').'</td></tr>'. '<tr><td>onunload</td><td>... de gebruiker de pagina verlaat</td><td>'.$page->inlineJS('<body> <frameset>').'</td></tr>'. '</tbody>'. '</table>', null, false)); // H7.4 $page->nextSubChapter(); $page->addContent('<p>Vaak wil je dat er juist met het element dat het event getriggerd heeft iets gebeurt. Bijvoorbeeld een plaatje die een blauwe rand krijgt als hij aangeklikt is. Of een tekstvakje waarvan de tekst wordt geselecteerd zodra je erop klikt. Dan kun je wel met allemaal id\'s gaan werken en het juiste element telkens proberen te vinden met dat id. Maar JavaScript heeft iets veel makkelijkers: een variabele die naar het element dat de event getriggerd heeft wijst. Die variabele heet '.$page->inlineJS('this').'.</p>'); $page->addContent('<p>Wat je allemaal precies kan aanpassen aan zo\'n element komt in '.$page->generateLinkToH(10, 5).'. Maar voor nu hoef je alleen te weten dat '.$page->inlineJS('element.innerHTML').' de HTML die in dat element zit bevat. Als je die dus aanpast zal ook de inhoud van dat element aangepast worden.</p>'); $page->addContent('<p>De variabele '.$page->inlineJS('this').' is alleen bekend in zijn event. Maar dat is op zich geen probleem, want dat is ook de enige plek waar je hem meestal wil gebruiken. De variabele '.$page->inlineJS('this').' verwijst dus naar het element vanuit waar het event getriggerd is, dus kun je met '.$page->inlineJS('this').' bijvoorbeeld de inhoud van dat element aanpassen.</p>'); $page->addJS('function vertaal() { // Binnen in deze functie is \'this\' dus bekend, als deze functie tenminste door het triggeren van een event wordt aangeroepen // Als je zelf ergens \'vertaal();\' neerzet dan zal \'this\' niet bekend zijn, wat in dit geval dus tot een fout zou leiden (gezien \'this\' gebruikt wordt) this.innerHTML = "Hallo wereld!"; // Pas de inhoud van het HMTL-element dat dit event getriggerd heeft aan } function maakEvents() { document.getElementById("translate_me").onclick = vertaal; } window.onload = maakEvents;'); $page->addHTML('<div id="translate_me">Hello world!<br />(click to translate to Dutch)</div>'); $page->addContent('<p>Je kan meerdere events aan dezelfde functie koppelen. Omdat '.$page->inlineJS('this').' telkens naar een andere element verwijst (namelijk naar degene die het event getriggerd heeft) hoeven we de functie niet eens te herschrijven.</p>'); $page->addJS('function vertaal() { this.innerHTML = "Hallo wereld!"; // Pas de inhoud van het HMTL-element dat dit event getriggerd heeft aan } function maakEvents() { // Alle HTML-elementen hebben een event met dezelfde functie // Maar toch zal die functie alleen het element waarop geklikt wordt \'vertalen\' document.getElementById("translate_me1").onclick = vertaal; document.getElementById("translate_me2").onclick = vertaal; document.getElementById("translate_me3").onclick = vertaal; document.getElementById("translate_me4").onclick = vertaal; document.getElementById("translate_me5").onclick = vertaal; } window.onload = maakEvents;'); $page->addHTML('<div id="translate_me1">Hello world!<br />(click to translate to Dutch)</div> <div id="translate_me2">Hello world!<br />(click to translate to Dutch)</div> <div id="translate_me3">Hello world!<br />(click to translate to Dutch)</div> <div id="translate_me4">Hello world!<br />(click to translate to Dutch)</div> <div id="translate_me5">Hello world!<br />(click to translate to Dutch)</div>'); $page->addContent('<p>Merk op dat de naam '.$page->inlineJS('this').' een gereserveerde naam is, en dat je dus niet zelf ergens een variabele of functie met die naam aan mag maken (zoals beschreven in '.$page->generateLinkToH(4, 2).').</p>'); // H7.5 $page->nextSubChapter(); $page->addContent('<p>Soms wil je ook informatie over het event hebben. Bij een <i>onkeypress</i>-event wil je bijvoorbeeld vaak weten welke toets er ingedrukt is. Hiervoor kan je een parameter toevoegen aan de eventfunctie. Deze parameter noemen we vaak gewoon <i>event</i>, maar het kan net zo goed <i>pipo</i> zijn. Je mag het zelf verzinnen.</p>'); $page->addContent('<p>Het is de browser die voor jou die functie uitvoert als de event getriggerd wordt, en het is ook de browser die als argument een event-object aan die functie als argument meegeeft. Je hoeft dus niet zelf daarvoor te zorgen en iets als argument mee te geven. Jouw zelfverzonnen parameter is dus dan dat event-object.</p>'); $page->addJS('function functieDieEventGebruikt(event) { // Code waarin je event gebruikt } function maakEvents() { document.getElementById("knop").onclick = functieDieEventGebruikt; } window.onload = maakEvents;'); $page->addHTML('<button id="knop">Klik hier</button>'); $page->addContent('<p>Via de variabele '.$page->inlineJS('event').' kan allerlei informatie over het event worden opgevraagd. Hieronder kun je in een tabel zien welke informatie opgevraagd kan worden.</p>'); $page->addContent($page->createWhiteBlock('<table>'. '<thead><tr><td>Attribuut</td><td>Omschrijving</td></tr></thead>'. '<tbody>'. '<tr><td>altKey</td><td>Is true als de alt-toets was ingedrukt toen het event getriggerd werd</td></tr>'. '<tr><td>ctrlKey</td><td>Is true als de control-toets was ingedrukt toen het event getriggerd werd</td></tr>'. '<tr><td>shiftKey</td><td>Is true als de shift-toets was ingedrukt toen het event getriggerd werd</td></tr>'. '<tr><td>keyCode</td><td>Waarde van de toets die ingedrukt werd</td></tr>'. '<tr><td>clientX</td><td>Geeft de x-co&ouml;rdinaat van waar de muis was toen het event getriggerd werd, waarbij 0 de linkerrand van het element waarin geklikt werd is</td></tr>'. '<tr><td>clientY</td><td>Geeft de y-co&ouml;rdinaat van waar de muis was toen het event getriggerd werd, waarbij 0 de bovenrand van het element waarin geklikt werd is</td></tr>'. '<tr><td>screenX</td><td>Geeft de x-co&ouml;rdinaat van waar de muis was toen het event getriggerd werd, waarbij 0 de linkerrand van het scherm is</td></tr>'. '<tr><td>screenY</td><td>Geeft de y-co&ouml;rdinaat van waar de muis was toen het event getriggerd werd, waarbij 0 de bovenrand van het scherm is</td></tr>'. '<tr><td>button</td><td>Geeft aan welke muisknop ingedrukt was toen het event getriggerd werd</td></tr>'. '</tbody>'. '</table>', null, false)); $page->addContent('<p>Bij die laatste, '.$page->inlineJS('button').', geldt het volgende (merk op dat <i>Internet Explorer</i> andere waardes hanteert):</p>'); $page->addContent($page->createWhiteBlock('<table>'. '<thead><tr><td>Waarde</td><td>Waarde in <i>Internet Explorer</i></td><td>Muisknop</td></tr></thead>'. '<tbody>'. '<tr><td>0</td><td>1</td><td>Linker muisknop</td></tr>'. '<tr><td>1</td><td>4</td><td>Middelste muisknop</td></tr>'. '<tr><td>2</td><td>2</td><td>Rechter muisknop</td></tr>'. '</tbody>'. '</table>', null, false)); $page->addContent('<p>Hoe kun je nou de waarde van zo\'n attribuut opvragen via de variabele '.$page->inlineJS('event').'? Simpel, met: '.$page->inlineJS('event.attribuut').', waarbij <i>attribuut</i> natuurlijk vervangen moet worden door de naam van het attribuut.</p>'); $page->addJS('function showCoords(event) { alert("De coordinaten van je muis op het scherm zijn: (" + event.screenX + ", " + event.screenY + ")"); } function maakEvents() { document.getElementById("divje").onclick = showCoords; } window.onload = maakEvents;'); $page->addHTML('<div id="divje">Klik hier om de co&ouml;rdinaten van je muis weer te geven</div>'); $page->addContent('<p>Merk op dat de genoemde attributen niet altijd een waarde hebben. Zo heeft <i>keyCode</i> alleen een waarde als het een <i>onkeypress</i>, <i>onkeydown</i> of <i>onkeyup</i> event was. Want het geeft de toets aan die bij dat event ingedrukt was. Zo hebben <i>button</i>, <i>clientX</i>, <i>clientY</i>, <i>screenX</i> en <i>screenY</i> ook alleen een waarde bij <i>onclick</i>, <i>onmouseup</i> en <i>onmousedown</i>. De attributen hebben dus alleen een waarde als dat zinnig is.</p>'); $page->addContent('<p>Om te weten welke toets er ingedrukt is, via attribuut keyCode, moet je de bijbehorende functie triggeren via de onkeydown-, onkeypress- of onkeyup-event van het document-object.</p><p>Omdat je hier niet een functie koppelt aan iets met een id, kan je de toewijzing meteen bij de start van de pagina doen. Het hoeft dus niet in een functie die je start via '.$page->inlineJS('window.onload').'.</p>'); $page->addJS('document.onkeydown = toetsen function toetsen(event){ //iets met event.keyCode doen }'); // H7.6 (opdrachten) $page->nextSubChapter(); $page->addAssignments(7); $page->printAll(); ?>

Resultaat

Made by Thijs Aarnoudse