javascriptcursus/hoofdstuk_10.php

<?php // Includes: require_once 'php/bookpage.php'; // Page: // H10 $page = new bookpage(10); // $page->addContent('<p>Zoals in '.$page->generateLinkToH(9, 5).' al werd gezegd is dit niet een naslagwerk. Toch worden in dit hoofdstuk een aantal veel voorkomende objecten en een deel van hun methodes behandeld, omdat deze altijd wel van pas zullen komen.</p>'); // H10.1 //$page->nextSubChapter(); // $page->addContent('<p>In '.$page->generateLinkToH(9).' werd uitgelegd wat objecten zijn. Je kan dus zelf objecten maken.</p>'); //$page->addJS('var mijnArray = new Array(); // Een array is een object, je maakt hier dus een object aan'); //$page->addContent('<p>Sommige objecten zijn echter al voor je gemaakt, dit zijn objecten die je zelf ook niet kan namaken. Je bent ze gedurende alle uitleg op deze site al eens tegen gekomen, bijvoorbeeld <i>document</i>. Dit zijn <i>globale objecten</i>, deze zijn dus overal in je code bruikbaar en zullen overal in je code naar hetzelfde object verwijzen. In dit hoofdstuk wordt van de belangrijkste uitgelegd wat ze doen en wat je er mee kan. Meer informatie kan wederom op het internet gevonden worden, waarbij het (weliswaar Engelstalige) <a href="http://w3schools.com/jsref/">naslagwerk van W3Schools over JavaScript</a> aan te raden is.</p>'); // H10.2 $page->nextSubChapter(); $page->addContent('<p>Het window-object gebruik je veel maar dat merk je nooit. Het eigenaardige aan dit object is namelijk dat dit het enige geval is waarbij je de objectnaam en dan de punt mag weglaten. Zo heb je de functie <i>alert()</i> al vaak gebruikt, maar eigenlijk is dat een methode van <i>window</i> terwijl je niet hoeft te typen '.$page->inlineJS('window.alert()').' (wat overigens wel mag).</p>'); $page->addContent('<p>Je mag de naam <i>window</i> dus weglaten. Je hoeft het enkel te weten om te snappen waarom ergens soms '.$page->inlineJS('window.alert()').' of '.$page->inlineJS('window.document.getElementById()').' staat in plaats van gewoon '.$page->inlineJS('alert()').' of '.$page->inlineJS('document.getElementById()').'. Zelf hoef je nooit '.$page->inlineJS('window.').' te typen, tenzij je dat natuurlijk overzichtelijker vindt.</p>'); $page->addContent('<p>Het window-object bevat nog twee handige methoden die je vaak zult gebruiken, <i>window.setTimeout()</i> en <i>window.setInterval()</i> Of zoals je het dus ook kan noemen: <i>setTimeout()</i> en <i>setInterval()</i>. Ze hebben beide 2 argumenten nodig, het eerste is een string die een stukje JavaScript bevat, het tweede een aantal milliseconden. Vervolgens wordt het stukje JavaScript in de string na het gegeven aantal milliseconden uitgevoerd. In het gevan van <i>setTimeout()</i> wordt het eenmalig uitgevoerd, in het geval van <i>setInterval()</i> wordt het elke keer weer opnieuw uitgevoerd na het gegeven aantal milliseconden.</p>'); $page->addJS('setTimeout(\'alert("Mij zie je na 5 seconden!");\', 5000); // 5000 ms = 5s setInterval(\'alert("Mij zie je elke 3.5 seconden!");\', 3500); // 3500 ms = 3.5s'); $page->addContent('<p>Soms wil je een time-out of interval stoppen. Zeker bij een interval kan dat handig zijn. Zodra je een van die twee functies aanroept geeft die een ID terug, dat ID kun je dan opslaan in een variabele en kun je later weer gebruiken om de timer te stoppen. Merk op dat als je de timer stopt de code dus niet meer uitgevoerd wordt. Het stoppen van die timer gaat met <i>clearTimeout()</i> voor time-outs en <i>clearInterval()</i> voor een interval. Als argument geef je dan het ID van de time-out of interval die je wilt stoppen aan de functie mee.</p>'); $page->addJS('var id = setTimeout(\'alert("Mij zie je na 5 seconden!");\', 5000); // Sla het ID op in een variabele clearTimeout(id); // Stop de timer'); // H10.3 $page->nextSubChapter(); $page->addContent('<p>Het document-object heb je ook al eens gebruikt. Het is deel van het window-object, maar zoals beschreven in '.$page->generateLinkToH(10, 2).' hoef je window niet te noemen. Je kan dus '.$page->inlineJS('window.document').' typen, maar ook '.$page->inlineJS('document').'.</p>'); $page->addContent('<p>Het document-object stelt het gehele HTML-document voor. Dus alle HTML-tags, plaatjes, links, formulieren, noem maar op. Het document-object bevat dan ook methodes en eigenschappen om die dingen op te vragen en te bewerken. Zo bevat document altijd vier arrays:</p>'); $page->addContent($page->createWhiteBlock('<table>'. '<thead><tr><td>Naam array</td><td>Zo gebruik je hem</td><td>Bevat</td></tr></thead>'. '<tbody>'. '<tr><td>anchors</td><td>'.$page->inlineJS('document.anchors').'</td><td>Alle <i>anchors</i> uit het HTML-document (a-elementen met het attribuut <i>name</i>).</td></tr>'. '<tr><td>images</td><td>'.$page->inlineJS('document.images').'</td><td>Alle img-elementen uit het HTML-document.</td></tr>'. '<tr><td>forms</td><td>'.$page->inlineJS('document.forms').'</td><td>Alle form-elementen uit het HTML-document.</td></tr>'. '<tr><td>links</td><td>'.$page->inlineJS('document.links').'</td><td>Alle links (dat kunnen a-elementen en area-elementen zijn) uit het HTML-document.</td></tr>'. '</tbody>'. '</table>', null, false)); $page->addContent('<p>Zo kun je bijvoorbeeld aangeven hoeveel plaatjes er op je webpagina staan.</p>'); $page->addJS('function telPlaatjes() { alert("Deze pagina bevat " + document.images.length + " plaatjes."); } window.onload = telPlaatjes; // Omdat de HTML eerst geladen moet worden voordat de JavaScript uitgevoerd kan worden (gezien de JavaScript de HTML gebruikt)'); $page->addHTML('<img src="img/plaatje.png" alt="Een plaatje" /><br /> <img src="img/plaatje2.png" alt="Nog een plaatje" />'); $page->addContent('<p>Aangezien die arrays HTML-elementen bevatten kan je die HTML-elementen ook aanpassen via die array.</p>'); $page->addJS('function veranderTekst() { for(var i=0; i<document.anchors.length; ++i) { document.anchors[i].innerHTML = "Hello world!"; // Pas de tekst van het a-element aan } alert("In alle anchors staat nu de tekst Hello world!"); } window.onload = veranderTekst;'); $page->addHTML('<a name="een naam">Tekst</a><br /> <a href="pagina.html">Nog wat tekst</a><br /> <a name="nog een naam" href="pagina2.html">En nog wat tekst!</a>'); $page->addContent('<p>De eigenschap <i>body</i> is ook wel noemenswaardig, '.$page->inlineJS('document.body').' verwijst gewoon naar de body van de HTML. Dus het <i>body</i>-element.</p>'); $page->addContent('<p>Verder bevat hij de volgende handige methodes:</p>'); $page->addContent($page->createWhiteBlock('<table>'. '<thead><tr><td>Methode</td><td>Zo gebruik je hem</td><td>Wat doet hij</td></tr></thead>'. '<tbody>'. '<tr><td>getElementById()</td><td>'.$page->inlineJS('document.getElementById("id");').'</td><td>Returnt het HTML-element met het gegeven id, als dit element niet bestaat wordt de waarde <i>null</i> terug gegeven.</td></tr>'. '<tr><td>getElementsByTagName()</td><td>'.$page->inlineJS('document.getElementsByTagName("tag-naam");').'</td><td>Returnt een array van alle HTML-elementen in het document met de gegeven naam (bijvoorbeeld alle b-elementen), als er geen zijn zal de array leeg zijn.</td></tr>'. '</tbody>'. '</table>', null, false)); $page->addContent('<p>Wat je allemaal met een HTML-element in JavaScript kan wordt uitgelegd in '.$page->generateLinkToH(10, 5).'. Een ding ken je al: <i>innerHTML</i>.</p>'); $page->addJS('function veranderTeksten() { var alleSpans = document.getElementsByTagName("span"); for(var i=0; i<alleSpans.length; ++i) // Eerst vullen we alle span-elementen met de tekst "How are you?" { alleSpans[i].innerHTML = "How are you?"; } document.getElementById("mijnID").innerHTML = "Hello world!"; // Daarna veranderen we de tekst van alleen het HTML-element met het id "mijnID" in "Hello world!" } window.onload = veranderTeksten;'); $page->addHTML('<span id="mijnID">Lorem ipsum</span> <span>dolor sit amet</span>'); $page->addContent('<p>Ook hier geldt weer dat er meer methodes bestaan, daarvoor verwijs ik wederom naar een naslagwerk: <a href="http://www.w3schools.com/jsref/dom_obj_document.asp">W3Schools JavaScript - Het document-object</a></p>'); // H10.4 $page->nextSubChapter(); $page->addContent('<p>Met het Math object kun je wiskundige functies en constanten (zoals &pi;) gebruiken. Deze website is niet bedoeld om wiskunde uit te leggen, dus er wordt alleen genoemd wat welke methode doet of wat een eigenschap voorstelt. Er wordt niet uitgelegd wat je er wiskundig mee kan.</p>'); $page->addContent($page->createWhiteBlock('<table>'. '<thead><tr><td>Methode</td><td>Wat doet het</td></tr></thead>'. '<tbody>'. '<tr><td>abs(x)</td><td>Geeft absolute waarde van <i>x</i></td></tr>'. '<tr><td>acos(x)</td><td>Geeft de boogcosinus van <i>x</i> in radialen (ook bekend als de inverse cosinus)</td></tr>'. '<tr><td>asin(x)</td><td>Geeft de boosinus van <i>x</i>, in radialen (ook bekend als de inverse sinus)</td></tr>'. '<tr><td>atan(x)</td><td>Geeft de boogtangens van <i>x</i> in radialen tussen -&pi;/2 en &pi;/2</td></tr>'. '<tr><td>atan2(x, y)</td><td>Geeft de boogtangens van de quoti&euml;nt van zijn argumenten</td></tr>'. '<tr><td>ceil(x)</td><td>Geeft <i>x</i>, naar boven afgerond</td></tr>'. '<tr><td>cos(x)</td><td>Geeft de cosinus van <i>x</i>, in radialen</td></tr>'. '<tr><td>exp(x)</td><td>Geeft E<sup><i>x</i></sup></td></tr>'. '<tr><td>floor(x)</td><td>Geeft <i>x</i>, naar beneden afgerond</td></tr>'. '<tr><td>log(x)</td><td>Geeft het natuurlijke logaritme (basis: E) van <i>x</i></td></tr>'. '<tr><td>max(a, b, c, ..., z)</td><td>Geeft het argument met de hoogste waarde terug (aantal argumenten maakt niet uit)</td></tr>'. '<tr><td>min(a, b, c, ..., z)</td><td>Geeft het argument met de laagste waarde terug (aantal argumenten maakt niet uit)</td></tr>'. '<tr><td>pow(x, n)</td><td>Geeft <i>x<sup>n</sup></i></td></tr>'. '<tr><td>random()</td><td>Geeft een willekeurig getal tussen 0 en 1</td></tr>'. '<tr><td>round(x)</td><td>Geeft <i>x</i>, afgerond naar het dichtsbijzijnde gehele getal</td></tr>'. '<tr><td>sin(x)</td><td>Geeft de sinus van <i>x</i>, in radialen</td></tr>'. '<tr><td>sqrt(x)</td><td>Geeft de vierkantswortel van <i>x</i></td></tr>'. '<tr><td>tan(x)</td><td>Geeft de tangens van <i>x</i>, in radialen</td></tr>'. '</tbody>'. '</table>', null, false)); $page->addContent('<p>De eigenschappen van het Math object zijn constant, dat wil zeggen dat je ze niet aan kan passen.</p>'); $page->addContent($page->createWhiteBlock('<table>'. '<thead><tr><td>Eigenschap</td><td>Wat stelt het voor</td><td>Is ongeveer</td></tr></thead>'. '<tbody>'. '<tr><td>E</td><td>Eulers constante</td><td>2.718</td></tr>'. '<tr><td>LN2</td><td>Natuurlijk logaritme van 2</td><td>0.693</td></tr>'. '<tr><td>LN10</td><td>Natuurlijk logaritme van 10</td><td>2.302</td></tr>'. '<tr><td>LOG2E</td><td>Logaritme van E, met basis 2</td><td>1.442</td></tr>'. '<tr><td>LOG10E</td><td>Logaritme van E, met basis 10</td><td>0.434</td></tr>'. '<tr><td>PI</td><td>&pi;</td><td>3.14159</td></tr>'. '<tr><td>SQRT1_2</td><td>Vierkantswortel van 1/2</td><td>0.707</td></tr>'. '<tr><td>SQRT2</td><td>Vierkantswortel van 2</td><td>1.414</td></tr>'. '</tbody>'. '</table>', null, false)); $page->addContent('<p>Voorbeeld van gebruik van het Math object:</p>'); $page->addJS('var x = prompt("Geef een getal op", ""); alert("De wortel van " + x + " is " + Math.sqrt(x));'); // H10.5 $page->nextSubChapter(); $page->addContent('<p>Wanneer je een variabele in JavaScript hebt die naar een HTML-element verwijst (bijvoorbeeld verkregen van <i>document.getElementById()</i>) dan kun je dat HTML-element aanpassen via die variabele. Zo\'n HTML-element is in JavaScript namelijk ook gewoon een object met methodes en eigenschappen. Voor een aantal HTMl elementen zijn natuurlijk specifieke eigenschappen (zoals bijvoorbeeld bij een img-tag het attribuut src ). Maar HTML-elementen hebben ook veel gemeen, in deze paragraaf worden een aantal handige methodes en eigenschappen beschreven die elk HTML-element in JavaScript heeft.</p>'); $page->addContent('<p>Zoals je al eerder hebt gezien kun je de inhoud van het element aanpassen via <i>innerHTML</i>. Dit vervangt de gehele inhoud, dus ook de tags die er in staan.</p>'); $page->addJS('function veranderTekst() { var span = document.getElementById("spanTag"); span.innerHTML="Hallo <i>wereld!</i>"; } window.onload = veranderTekst;'); $page->addHTML('<span id="spanTag">Hello <b>world!</b></span>'); $page->addContent('<p>De CSS-stijl van het element kan ook aangepast worden, via <i>style</i>. Dit is alsof je gewoon CSS zou neerzetten het style-attribuut van dat element. Zo kun je bijvoorbeeld de tekstkleur veranderen wanneer er met de muis overheen gegaan wordt.</p>'); $page->addJS('function veranderTekstKleur() { this.style.color = "#f00"; // Verander de tekst-kleur van het element waar vanuit de event getriggerd is in rood } function maakEvents() { var spans = document.getElementsByTagName("span"); for(var i = 0; i < spans.length; ++i) { spans[i].onmouseover = veranderTekstKleur; } } window.onload = maakEvents;'); $page->addHTML('<span>Dit is een beetje tekst</span><br /> <span>Nog wat tekst</span><br /> <span>Het laatste beetje tekst</span>'); $page->addContent('<p>Het gebruik is dus simpel: '.$page->inlineJS('element.style.CssStijlNaam = "CSS waarde";').', dit zou dan gelijk zijn aan '.$page->inlineHTML('style="CssStijlNaam: CSS waarde;"').' in het gekozen element. Alleen zijn er in CSS ook stijl namen met een - er tussen (zoals bijvoorbeeld <i>background-color</i>), en in een naam in JavaScript kan geen - zitten want dat is al een minteken. Daarom laat je dan de - weg, en begin je het woord na de - met een hoofdletter: '.$page->inlineJS('element.style.backgroundColor = "#f00";').'. Voor een volledig overzicht van alle CSS stijlen die via <i>style</i> aan te passen zijn, zie: <a href="http://www.w3schools.com/jsref/dom_obj_style.asp">W3Schools JavaScript - style</a></p>'); $page->addContent('<p>Merk op dat je in CSS vaak een eenheid erbij moet geven, bijvoorbeeld: <i>width: 20<b>px</b>;</i>, de waarde is dan dus <i>20px</i> en niet alleen <i>20</i> en dus zonder <i>;</i> (die geeft enkel aan dat de waarde daar eindigt, maar is dus geen deel van de waarde). Dus in JavaScript moet dat dan ook: '.$page->inlineJS('element.style.width = "20px";').' worden, waarbij dus die <i>;</i> niks met de CSS te maken heeft maar enkel het einde van het statement aan geeft (zie '.$page->generateLinkToH(3, 1).').</p>'); $page->addContent('<p>Via elke JavaScript-verwijzing naar een HTML-element kan het id of de class van dat HTML-element opgevraagd of gewijzigd worden. Dat kan via <i>element.id</i> of <i>element.className</i>. Zo kun je bijvoorbeeld met JavaScript alle spans selecteren die de class <i>abc</i> hebben.</p>'); $page->addJS('function veranderSpans() { var spans = document.getElementsByTagName("span"); // Selecteer alle spans in het document for(var i=0; i<spans.length; ++i) // Doorloop al die spans { if(spans[i].className == "abc") // Als de huidige span de class "abc" heeft { spans[i].style.color = "#f00"; // Pas de stijl van de huidige span aan, maak de tekst rood } } } function maakEvents() { document.getElementById("veranderABC").onclick = veranderSpans; } window.onload = maakEvents;'); $page->addHTML('<span class="abc">Deze span heeft de class &quot;abc&quot;</span><br /> <span class="abc">Deze ook...</span><br /> <span>Maar deze niet!</span><br /> <button id="veranderABC">Kleur alle abc-spans rood</button>'); $page->addContent('<h3>Nodes</h3>'); $page->addContent('<p>In HTML staan alle elementen in elkaar:</p>'); $page->addHTML('<div id="deDiv">Ik ben een div-element <span id="deSpan">En ik ben een span element in het div-element <b id="deB">Met daar in weer een b-element...</b> <i id="deI">en een i-element!</i> </span> </div>'); $page->addContent('<p>Als je met JavaScript een verwijzing naar een element hebt, kun je ook een verwijzing naar zijn <i>parent</i> krijgen. Zijn <i>parent</i> is het element waar hij in staat. Dus in het geval van de <i>span</i> hierboven, zou dat de <i>div</i> zijn. Die verwijzing kan met de eigenschap <i>parentNode</i> worden opgevraagd.</p>'); $page->addContent('<p>Een element kan altijd maar 1 parent hebben, maar kan meerdere <i>childs</i> (kinderen) hebben. Zoals de <i>span</i> in het bovenstaande voorbeeld, die heeft een <i>b</i> en een <i>i</i> als child, merk op dat de <i>b</i> en <i>i</i> wel indirect childs zijn van de <i>div</i> maar niet direct. Al die directe childs kun je verkrijgen met de eigenschap <i>childNodes</i>, dat is dus een array van alle HTML-elementen die direct in dat element zitten (kan dus ook leeg zijn).</p>'); $page->addContent('<p>Nou kan er ook nog tekst in een element staan, dit telt ook als child. Zelfs de enter en de paar spaties aan het eind van de div met het id <i>deDiv</i> (dus tussen '.$page->inlineHTML('</span>').' en '.$page->inlineHTML('</div>').') in het bovenstaande stukje HTML tellen als tekst, ook al zie je ze niet in het resultaat!</p>'); $page->addJS('function laatKinderenZien() { var div = document.getElementById("deDiv"); alert("Het div-element bevat " + div.childNodes.length + " childs"); var span = div.childNodes[1]; // Het span-element is 2e (na het stukje tekst) child van de div alert("Het span-element bevat " + span.childNodes.length + " childs"); for(var i=0; i<span.childNodes.length; ++i) { alert("Het " + (i+1) + "e element is een " + span.childNodes[i].nodeName + "-element"); } } window.onload = laatKinderenZien;'); $page->addHTML('<div id="deDiv">Ik ben een div-element <span id="deSpan">En ik ben een span element in het div-element <b id="deB">Met daar in weer een b-element...</b> <i id="deI">en een i-element!</i> </span> </div>'); $page->addContent('<p>In het bovenstaande stukje code zie je ook <i>nodeName</i> staan (regel 9). Dit is ook een eigenschap die elk HTML-element bevat, en is niks anders dan de naam van het element (<i>DIV</i>, <i>SPAN</i>, <i>B</i>, <i>I</i>, etc) in hoofdletters.</p>'); $page->addContent('<p>Wederom zijn er veel meer eigenschappen en methodes dan in deze paragraaf besproken zijn, daarvoor verwijs ik weer naar <a href="http://www.w3schools.com/jsref/dom_obj_all.asp">W3Schools JavaScript - Eigenschappen en methodes van alle HTML-elementen</a> </p>'); // H10.6 $page->nextSubChapter(); $page->addContent('<p>Zoals in '.$page->generateLinkToH(10, 5).' al is gezegd, hebben een aantal HTML-elementen nog wat specifieke eigenschappen. Zo heeft ook een tabel een aantal handige eigenschappen die ik hier nog wel wil bespreken. Je zal deze namelijk vaak nodig hebben. Als je bijvoorbeeld een spelletje maakt, dan gebruik je vaak een tabel als speelbord of level.</p>'); $page->addContent('<p>Elke tabel-object in JavaScript heeft een eigenschap <i>rows</i>, dit is een array van alle rijen in die tabel. Deze array kan dus leeg zijn. Elk element in die array is dus een verwijzing naar een <i>tr</i>-element. De rijen staan in de array op dezelfde volgorde als ze in de HTML voorkomen.</p>'); $page->addContent('<p>Elke rij, dus elk <i>tr</i>-element, bevat weer een een eigenschap genaamd <i>cells</i>. Dat is een array van alle cellen (dus <i>td</i>\'s) in die rij, ook weer in dezelfde volgorde als voorkomen in de HTML.</p>'); $page->addContent('<p>Op die manier kun je bijvoorbeeld een blokje door een tabel laten bewegen.</p>'); $page->addJS('var x = 2; // De x-coordinaat van het zwarte wordt in deze variabele bijgehouden var y = 2; // De y-coordinaat van het zwarte wordt in deze variabele bijgehouden function beweeg(event) { var table = document.getElementById("gameboard"); table.rows[y].cells[x].style.backgroundColor = "#fff"; // Maak het huidige zwarte vakje wit, we gaan immers hier vandaan verplaatsen // Als er geen pijltjes toets ingedrukt is blijven de coordinaten ongewijzigd // en zal het vakje dus opnieuw zwart worden gemaakt aan het einde van deze functie if(event.keyCode == 37){ // Pijltje naar links if(--x < 0){ // Trek 1 van x af, als het resultaat kleiner is dan 0 (dus buiten de tabel valt) x = 4; // Spring dan weer naar rechts } } if(event.keyCode == 38){ // Pijltje naar boven if(--y < 0){ // Trek 1 van y af, als het resultaat kleiner is dan 0 (dus buiten de tabel valt) y = 4; // Spring dan weer naar onder } } if(event.keyCode == 39){ // Pijltje naar rechts if(++x > 4){ // Tel 1 bij x op, als het resultaat groter is dan 4 (dus buiten de tabel valt) x = 0; // Spring dan weer naar links } } if(event.keyCode == 40){ // Pijltje naar onder if(++y > 4) { // Tel 1 bij y op, als het resultaat groter is dan 4 (dus buiten de tabel valt) y = 0; // Spring dan weer naar boven } } table.rows[y].cells[x].style.backgroundColor = "#000"; // Maak het vakje met de nieuwe coordinaten zwart } function maakEvents() { document.body.onkeydown = beweeg; } window.onload = maakEvents;'); $page->addHTML('<table id="gameboard" style="empty-cells:show;width:250px;height:250px;"> <tr><td></td><td></td><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td><td></td><td></td></tr> <tr><td></td><td></td><td style="background-color:#000;"></td><td></td><td></td></tr> <tr><td></td><td></td><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td><td></td><td></td></tr> </table> Bestuur het zwarte vakje met de pijltjes'); // H10.7 (opdrachten) $page->nextSubChapter(); $page->addAssignments(10); $page->printAll(); ?>

Resultaat

Made by Thijs Aarnoudse