JavaScript for Interactive Web Pages 2



Vergelijkbare documenten
Inhoud leereenheid 4. Inleiding JavaScript. Introductie 99. Leerkern 100. Zelftoets 108. Terugkoppeling 109

Inhoud leereenheid 7c. JavaScript: Objecten en functies. Introductie 59. Leerkern 60. Samenvatting 82. Opdrachten 83. Zelftoets 89.

Variabelen en statements in ActionScript

Inhoud leereenheid 7a. JavaScript for Interactive Web Pages 1. Introductie 9. Leerkern 10. Samenvatting 19. Opdrachten 20.

Javascript oefenblad 1

Zelftest Inleiding Programmeren

Lab Webdesign: Javascript 3 maart 2008

Visual Basic.NET. Visual Basic.NET. M. den Besten 0.3 VB. NET

recursie Hoofdstuk 5 Studeeraanwijzingen De studielast van deze leereenheid bedraagt circa 6 uur. Terminologie

van PSD naar JavaScript

Foutcontrole met Javascript

Formulieren maken met Dreamweaver CS 4/CS 5

HOOFDSTUK 3. Imperatief programmeren. 3.1 Stapsgewijs programmeren. 3.2 If Then Else. Module 4 Programmeren

Recursion. Introductie 37. Leerkern 37. Terugkoppeling 40. Uitwerking van de opgaven 40

Inhoud. Introductie tot de cursus

Lab Webdesign: Javascript 25 februari 2008

Informatietechnologie 2. JavaScript. Strings, getallen, datums, arrays en loops. Kristof Michiels

Een topprogrammeur in het OO programmeren is Graig Larman. Hij bedacht de volgende zin:

Inhoud. Introductie tot de cursus

Lab Webdesign: Javascript 11 februari 2008

Lab Webdesign: Javascript 7 april 2008

Programmeermethoden NA. Week 5: Functies (vervolg)

Websitecursus deel 3 JavaScript

Uitwerking Tweede deeltentamen Imperatief programmeren - versie 1 Vrijdag 21 oktober 2016, uur

Les 9: formulier controle met javascript.

Uitwerking Aanvullend tentamen Imperatief programmeren Woensdag 24 december 2014, uur

APPLICATIEBOUW 3E COLLEGE: OBJECT GEORIËNTEERD PROGRAMMEREN, METHODEN, PARAMETERS, SCOPE VAN VARIABELEN. Onderdeel van SmartProducts

Het relaas van de beginnende programmeur. Het hoe en waarom van de assistent


Programmeermethoden NA. Week 5: Functies (vervolg)

Als een PSD selecties bevat, deelt de lijn van het programma zich op met de verschillende antwoorden op het vraagstuk.

JavaScript. 0 - Wat is JavaScript? JavaScript toevoegen

Controle structuren. Keuze. Herhaling. Het if statement. even1.c : testen of getal even of oneven is. statement1 statement2

Universiteit van Amsterdam FNWI. Voorbeeld van tussentoets Inleiding programmeren

OEFENINGEN PYTHON REEKS 1

In de tweede regel plaatsen we in het gereserveerde stukje geheugen een getal.

Programmeren (1) Examen NAAM:

Modelleren en Programmeren

Een korte samenvatting van enkele FORTRAN opdrachten

Syntax- (compile), runtime- en logische fouten Binaire operatoren

Disclaimer Het bestand dat voor u ligt, is nog in ontwikkeling. Op verzoek is deze versie digitaal gedeeld. Wij willen de lezer er dan ook op wijzen

Programmeermethoden NA

Informatietechnologie 2. JavaScript. Functies, Objecten en toegang tot de DOM. Kristof Michiels

Software 1. php mysql. bachelor grafische en digitale media cross-media ontwerp & grafimediatechnologie academiejaar semester 1

Web building gevorderden: CSS & JavaScript. Karel Nijs 2008/11

Programmeren in Java les 3

Programmeermethoden NA. Week 6: Lijsten

Programmeerstructuren met App Inventor

PYTHON REEKS 2: FUNCTIES. Mathias Polfliet

Hoofdstuk 6: Zelf functies maken

II. ZELFGEDEFINIEERDE FUNCTIES

Inleiding tot programmeren: Javascript

[15] Variabelen in functies (of: een woordje over scope)

Stroomschema s maken op papier

Rekenen aan wortels Werkblad =

Quick Guide VivianCMS

extra oefening algoritmiek - antwoorden

Lab Webdesign: Javascript 11 februari 2008

5. Functies. In deze module leert u:

MINICURSUS PHP. Op dit lesmateriaal is een Creative Commons licentie van toepassing Sebastiaan Franken en Rosalie de Klerk Bambara

Bijlage Inlezen nieuwe tarieven per verzekeraar

Je hoeft je maar met twee bestanden bezig te houden:

OEFENINGEN PYTHON REEKS 1

BEGINNER JAVA Inhoudsopgave

PROS1E1 Gestructureerd programmeren in C Dd/Kf/Bd

Opdrachten herhalen. public void tekenscherm (object o, PEA pea) { int x; x = 1; zolang de voorwaarde geldig is

oefening JavaScript - antwoorden

College Introductie

HOE TEKEN IK EEN OMGEVINGSMODEL

6,1. Samenvatting door een scholier 1809 woorden 28 oktober keer beoordeeld. Informatica

Vergelijkingen met breuken

Functies. Huub de Beer. Eindhoven, 4 juni 2011

Websitecursus deel 1 HTML

Hoofdstuk 7: Werken met arrays

17 Operaties op bits Bitoperatoren en bitexpressies

In het CMS is het mogelijk om formulieren aan te maken. Voorafgaand een belangrijke tip:

Hoofdstuk 6: Zelf functies maken

OEFENINGEN PYTHON REEKS 1

Stacks and queues. Introductie 45. Leerkern 45. Terugkoppeling 49. Uitwerking van de opgaven 49

Objective-C Basis. 23 april 2005, Eindhoven Patrick Machielse

Programmeren A. Genetisch Programma voor het Partitie Probleem. begeleiding:

Datum, Tijd en Timer-object

Informatica: C# WPO 6

Inhoud. Pagina 2 van 13

Vakgroep CW KAHO Sint-Lieven

De principes van unobtrusive JavaScript. Peter-Paul Koch (ppk) PFCongrez, 12 april 2008

Opdracht 3: Betere oplossingen

Examen Programmeren 2e Bachelor Elektrotechniek en Computerwetenschappen Faculteit Ingenieurswetenschappen Academiejaar juni, 2010

Voorbeeldtentamen Inleiding programmeren (IN1608WI), Oktober 2003, , Technische Universiteit Delft, Faculteit EWI, Afdeling 2.

Handleiding Wordpress

1 Delers 1. 3 Grootste gemene deler en kleinste gemene veelvoud 12

VAN HET PROGRAMMEREN. Inleiding

Hoofdstuk 5: Functies voor getallen en teksten

Java Les 3 Theorie Herhaal structuren

Informatietechnologie 2. JavaScript. Inleidende les. Kristof Michiels

Handleiding JCreator. Inhoud. Een Workspace en een eerste project maken

HTML Graphics. Hans Roeyen V 3.0

Formulieren en waarden posten naar een view

WEBSITE-DESIGN CHRIS VERMAAS & FJODOR VAN SLOOTEN B

Transcriptie:

Leereenheid 7b JavaScript for Interactive Web Pages 2 I N T R O D U C T I E In de vorige leereenheid heeft u kennisgemaakt met JavaScript, en heeft u geleerd om eenvoudige event handlers te schrijven. U heeft in die leereenheid nog maar met een heel beperkte subset gewerkt van wat mogelijk is met JavaScript. In deze leereenheid breiden we die subset uit: u maakt kennis met constructies voor programmalogica, en de logische operatoren die u daarbij kunt gebruiken. Ook leert u werken met arrays, met parameters bij functies, en leert u iets over scope. LEERDOELEN Na het bestuderen van deze leereenheid wordt verwacht dat u kunt uitleggen wat het verschil is tussen een lokale en een globale variabele kunt uitleggen wat de reden is van de regel om variabelen met het keyword var te declareren de in de cursus behandelde vergelijkings- en logische operatoren kunt gebruiken functies met parameters kunt gebruiken arrays en array-methoden kunt gebruiken de in de cursus behandelde conditionele statements en while loops kunt gebruiken de betekenis van de volgende begrippen kunt uitleggen: truthy, falsey, short-circuit evaluation, lokale en globale scope, sparse array, multidimensionaal array. Studeeraanwijzingen Voor deze leereenheid bestudeert u de paragrafen 7.3, 7.4 en 7.5 van het tekstboek. We verwachten dat u voor het bestuderen van deze leereenheid ongeveer 7 uur zult nodig hebben. L E E R K E R N 7.3 Program Logic 7.3.1 COMPARISON OPERATORS Weblink: Operator precedence Details over welke operatoren een sterkere binding hebben dan andere vindt u behalve in het tekstboek ook in de referentie over operator precedence. OU 35

Webapplicaties: de clientkant De operatoren === en!== vergelijken zonder automatische typeconversie. Relational operators Equality operators Er is een verschil tussen de relational operators (>, <, >=, <=) en de equality operators (=,!=) voor wat betreft de behandeling van de waarde null. In een expressie met een relational operator wordt de waarde null, indien nodig, naar 0 geconverteerd. De expressie 0 >= null levert dus true op, evenals de expressie 0 <= null. In een expressie met een equality operator wordt de waarde null niet naar 0 geconverteerd. De expressie 0 == null levert dus false op. In een expressie met een equality operator wordt null wel naar undefined geconverteerd indien nodig. De expressie null == undefined levert dus true op. TABEL 7b.1 expressie Impliciete typeconversie van null resultaat 0 >= null true 0 <= null true 0 == null false 0 == undefined true OPGAVE 7b.1 Waar in de expressies van Table 7.16 wordt aan impliciete typeconversie gedaan en waar niet? De expressies in de tabel zijn: 5 < 10.0 7 == "7" 7 === "7" 7!= "7.0" 7!== "7.0" 42 < "hello" 42 >= "hello" 10 > "3 french hens" Programmeeraanwijzing Impliciete typeconversie kan handig zijn, maar het kan ook leiden tot onverwachte resultaten. Pas er dus mee op! 7.3.2 CONDITIONAL STATEMENTS: IF/ELSE Net als in veel andere talen zijn de accolades in principe niet nodig als er in een if- of else-gedeelte slechts één statement staat. Omdat er bij het later veranderen van code dan gemakkelijk fouten kunnen optreden (als er een extra statement nodig is in zo n gedeelte) is het aan te bevelen om altijd accolades te gebruiken. Programmeeraanwijzing Gebruik in een if-else constructie altijd accolades om de statements, ook als het maar om één statement gaat. 36 OU

Leereenheid 7b JavaScript for Interactive Web Pages 2 OPGAVE 7b.2 In Example 7.32 zou u, om hetzelfde effect te bereiken, in plaats van de combinatie van een for loop met een if-else-statement ook twee for loops kunnen gebruiken. Hoe zou die code er uit zien? Switch Als u een aantal maal else if in uw conditionele statement gebruikt is het overzichtelijker om over te stappen op het switch statement dat JavaScript ook kent. De syntax van het switch statement is: switch (expression) { case label1: statements1 [break;] case label2: statements2 [break;]... case labeln: statementsn [break;] default: statements_def [break;] De werking ervan is dat expression wordt geëvalueerd. Als het resultaat gelijk is aan label1 worden statements1 en verder uitgevoerd tot er een break staat. Als het resultaat gelijk is aan label2 worden statements2 en verder uitgevoerd. Een break zorgt ervoor dat niet automatisch alle volgende statements ook worden uitgevoerd: de executie van het switch statement stopt bij de break. De break is optioneel: als hij in een case-gedeelte ontbreekt wordt alles wat in de volgende case-gedeelten staat ook uitgevoerd, tot de eerste break. 7.3.3 BOOLEAN VALUES Impliciete typeconversie Wat de eerste alinea van paragraaf 7.3.3 in feite zegt is dat impliciete typeconversie in JavaScript, als er een boolean waarde verwacht wordt, altijd een waarde oplevert. Er zijn regels die bepalen voor welke waarden impliciete typeconversie true oplevert en voor welke waarden impliciete typeconversie false oplevert. Truthy De waarden die naar true converteren worden truthy genoemd. Falsey De waarden die naar false converteren worden falsey genoemd. Het is voor een programmeur natuurlijk van groot belang om te weten welke waarde truthy en welke falsey zijn, met andere woorden, welke waarden door de impliciete typeconversie naar true en welke naar false worden geconverteerd. OPGAVE 7b.3 Er is een aantal gevallen waarin de variabele myvariable in de expressie if (myvariable) bestaat, en een waarde heeft, maar waarbij de test negatief zal uitvallen. Welke situaties zijn dat? OU 37

Webapplicaties: de clientkant 7.3.4 LOGICAL OPERATORS Short-circuit evaluation Default-waarde Short-circuit evaluation houdt in: Als de linkerkant van een OR-expressie een truthy waarde bevat, wordt de rechterkant niet geëvalueerd. Dat is niet nodig omdat de expressie toch de waarde van de linkerkant op zal leveren. 2 2/0 levert dus geen fout op, maar 2. Als de linkerkant van een AND-expressie een falsey waarde bevat, wordt de rechterkant niet meer geëvalueerd. Dat is niet nodig omdat de expressie toch de waarde van de linkerkant op zal leveren. false && 2/0 levert dus geen fout op, maar false. In een expressie met meerdere logische operatoren worden operanden van links naar rechts geëvalueerd tot er niet meer verder hoeft te worden gekeken. In het voorbeeld 2 3 4 && 2/0 hoeft dus alleen maar de 2 te worden bekeken: dan is al duidelijk dat de expressie 2 zal opleveren, omdat 2 een truthy waarde is. Als u werkt met input van de gebruiker, kunt u er nooit van uitgaan dat alles netjes op de juiste manier is ingevuld. Als u een variabele keuze als waarde textfield.value zou geven zonder default-waarde zou u later in het programma in de problemen kunnen komen als u verwacht dat keuze een waarde heeft terwijl dat niet het geval blijkt. De operator heet ook wel de default-operator omdat het mogelijk is om daarmee een default-waarde te geven, zoals Example 7.37 laat zien. Programmeeraanwijzing 1 Als het noodzakelijk is dat de gebruiker een bepaald invoerveld heeft ingevuld (met een waarde die anders is dan 0 of ""), test dan of dat het geval is met if (invoerveld.value). 2 Als het niet noodzakelijk is dat de gebruiker een bepaald invoerveld heeft ingevuld, maar u heeft wel een waarde nodig bij het verwerken van de gegevens, geef dan een default-waarde met var data = invoerveld.value defaultwaarde;. 7.3.5 WHILE LOOPS Uiteraard geldt in de while loop voor de accolades om de statements hetzelfde als bij de if-else-constructie. Programmeeraanwijzing Gebruik in een while-constructie altijd accolades om de statements, ook als het maar om één statement gaat. OPGAVE 7b.4 a Waarom kunt u de while-constructie uit Example 7.40 (leapyear) niet vervangen door een for-lus? b Waarom is het nodig om in Example 7.40 de functie parseint te gebruiken voor de waarde die de gebruiker ingeeft voor het jaar? JavaScript doet toch aan impliciete typeconversie? 38 OU

Leereenheid 7b JavaScript for Interactive Web Pages 2 7.4 Advanced JavaScript Syntax 7.4.1 SCOPE AND GLOBAL VARIABLES Scope Een variabele is niet altijd `zichtbaar' binnen alle code in een JavaScriptbestand. Het gebied waarbinnen een variabele zichtbaar is heet z n scope. Globale scope betekent dat een variabele zichtbaar is binnen alle JavaScriptcode van één pagina. Lokale scope houdt in dat er een beperkter gebied is (binnen één functie) waarbinnen de variabele bekend is; daarbuiten bestaat de variabele niet. Hier ziet u de reden voor de regel om variabelen altijd expliciet te declareren met het keyword var: als u dat niet doet, is de variabele globaal. Als u ergens in uw programma iets verandert aan een globale variabele, geldt die verandering voor uw gehele programma. In een HTML-pagina kunt u meerdere JavaScript-bestanden laden. Een verandering aan een globale variabele in de code van één van die bestanden zal te merken zijn in alle JavaScript-code die in die pagina is geladen als er op twee plaatsen een globale variabele van dezelfde naam wordt gebruikt. Programmeeraanwijzing Vermijd het gebruik van globale variabelen zoveel mogelijk. Dezelfde naam, andere variabele Als er een globale variabele a bestaat, en binnen een functie wordt er een lokale variabele met de naam a gebruikt (die variabele wordt binnen de functie dus met het keyword var gedeclareerd), is die lokale variabele dus een andere variabele dan de globale a. Dat houdt in dat u binnen die functie niet meer met de globale variabele a kunt werken: de naam a verwijst binnen die functie naar de lokale variabele a. OPGAVE 7b.5 In de event handlers die u tot nu toe heeft leren gebruiken, heeft u vaak de methode getelementbyid aangeroepen van het object document. Is document een globale of een lokale variabele? Verklaar uw antwoord. 7.4.2 ARRAYS Een snellere manier om een array te creëren en te vullen is om dat in één keer te doen: var xgames = ["Freestyle BMX", "MotoX", "Skateboarding"]; De for loop in Example 7.44 heeft als voordeel dat heel duidelijk is wat de maximum waarde van teller i in de loop is, maar heeft als nadeel dat elke keer dat de loop wordt doorlopen, het attribuut length van de array opgezocht. Het is daarom efficiënter om dat attribuut slechts eenmaal op te zoeken, en de waarde ervan aan een variabele toe te kennen: for (var i = 0; i < xgames.length; i++) OU 39

Webapplicaties: de clientkant wordt dan: var lengte = xgames.length; for (var i = 0; i < lengte; i++) Verwarrend kan zijn dat in JavaScript de indexen van een array niet opeenvolgend hoeven te zijn. Het is bijvoorbeeld toegestaan om te schrijven: var xgames = ["Freestyle BMX"]; xgames[100] = "MotoX"; Sparse array Zo n array, waarin als het ware indexen ontbreken, heet een sparse array. Als u van de array uit het voorbeeld niet zeker zou weten of het wel of geen sparse array is, zou u binnen de for-lus dus moeten controleren of er op de betreffende index wel een waarde zit: if (xgames[i]) { alert(xgames[i]; Length niet hetzelfde als het aantal waarden Toekenning: referentie Het attribuut length geeft daardoor niet per definitie de lengte van de array weer, maar de waarde van de hoogste index, verhoogd met 1. In het geval van een sparse array is dat niet gelijk aan het aantal waarden in de array. In het bovenstaande voorbeeld zou het attribuut length 101 aangeven, terwijl de array slechts twee waarden bevat. Bij een toekenning krijgt een variabele net als in het geval van een object geen kopie van een array, maar een referentie naar die array. Om die reden is het ook niet mogelijk om twee arrays met elkaar te vergelijken met behulp van de == operator. Wat vergeleken wordt is niet de inhoud van de arrays, maar de referenties: wijzen ze naar hetzelfde array? FIGUUR 7b.1 Arrays met elkaar vergelijken In figuur 7b.1 is dat te zien: in het bovenste geval wijzen de variabelen a en b naar twee verschillende arrays, die gevuld zijn met dezelfde waarden. De expressie (a == b) zal de waarde false opleveren: ze wijzen niet naar dezelfde array. 40 OU

Leereenheid 7b JavaScript for Interactive Web Pages 2 In het onderste geval, waarin de waarde van de variabele a aan b is toegekend, wijzen de variabelen a en b beide naar hetzelfde array. De expressie (a == b) zal in dat geval true opleveren. Om arrays inhoudelijk met elkaar te vergelijken moet u ze dus element voor element met elkaar vergelijken. Multidimensionale array De waarden in een array kunnen zelf ook weer een array zijn. In dat geval spreken we over een multidimensionale array. Als voorbeeld creëren we een aantal arrays van woorden die met dezelfde letter beginnen: var a = ["aap", "appel", "aardappel"]; var b = ["beer", "banaan", "boerenkool"]; var c = ["civetkat", "citroen", "cichorei"]; Die arrays zetten we in een array: var woorden = [a, b, c]; Vervolgens kunnen we een dier dat met een b begint krijgen met: woorden[1][0]; Een groente die met een c begint krijgen we als volgt: woorden[2][2]; OPGAVE 7b.6 Gegeven de volgende code: var a = ["aap", "appel", "aardappel"]; var b = ["beer", "banaan", "boerenkool"]; var c = ["civetkat", "citroen", "cichorei"]; var woorden = [a, b, c]; a Hoe krijgt u het fruit dat met een a begint? b En hoe krijgt u het dier dat met een c begint? 7.4.3 FUNCTION PARAMETERS AND RETURNS Parameters: lokale variabelen Parameters van een functie fungeren binnen die functie als lokale variabelen. OPGAVE 7b.7 JavaScript biedt de functie Math.pow(base, exponent) om de macht van een getal te berekenen, met een mee te geven exponent. U gebruikt die functie vaak, en merkt dat u in heel veel gevallen als exponent 2 gebruikt. Schrijf een functie die gebruik maakt van Math.pow(base, exponent), waarbij u, als u slechts één getal als parameter meegeeft, 2 als exponent gebruikt. OU 41

Webapplicaties: de clientkant 7.4.4 INPUT DIALOG BOXES Net zoals bij een alert verhindert de pop-up box van een confirm of een prompt dat de gebruiker de browser gebruikt om bijvoorbeeld een andere tab te bekijken. Gebruikers hebben dan ook vaak een hekel aan dit soort pop-up boxes, en als u overweegt er een te gebruiken is het aan te raden om alternatieven te overwegen. 7.5 Case Study: Hangman S A M E N V A T T I N G JavaScript kent vijf primitieve typen: Number, String, Boolean, null en undefined. De gebruikelijke rekenkundige en logische operatoren op numbers, strings en boolean waarden die bijvoorbeeld Java ook kent, zijn ook beschikbaar in JavaScript. De syntax voor commentaar is ook hetzelfde als in Java. In JavaScript kan elke waarde gebruikt worden als een boolean test. De waarden 0, de lege string " ", null en undefined zijn zogenaamde falsey waarden; alle andere waarden zijn truthy waarden. Arrays in JavaScript lijken op die in Java, maar ze hebben de eigenschap dat ze dynamisch kunnen groeien wanneer dat nodig is. Een variabele die zonder het keyword var is gedeclareerd, is een globale variabele. O P D R AC H T E N Vergelijkingsoperatoren, bij 3.1 OPDRACHT 7b.1 Als u Firebug heeft geopend, en op de Console tab klikt, kunt u op de invoerregel onderaan expressies invoeren. Het resultaat wordt dan in de console gezet. Bekijk wat het resultaat is van de volgende expressies: 1 > null; 1 > "null"; 1 > NaN; 1 > 1.0; 1 == 1.0; 1 == "1.0"; Er is geen uitwerking bij deze opdracht. If-else, bij 3.2 OPDRACHT 7b.2 In deze opdracht gebruikt u de if-else-constructie om de invoer van een textarea te verwerken. U kunt uitgaan van blog/index.html en blog/blog.js uit de bouwstenen. 42 OU

Leereenheid 7b JavaScript for Interactive Web Pages 2 In de vorige leereenheid heeft u een event handler geschreven voor de knop Publiceer van die blog-applicatie, die enters in de invoer interpreteert, en p-tags tussenvoegt. In deze opdracht verfijnt u die functie: met behulp van een if-elseconstructie is het mogelijk om elke zin op een nieuwe regel te beginnen door een br-element in te voegen. Voor u de invoer in paragrafen splitst, vervangt u elke punt door een punt gevolgd door een br-tag. Aan u de taak om de functie publiceer op die manier uit te breiden. U vindt een uitwerking in de bouwstenen, in blog/blog.js, en er is een toelichting in de terugkoppeling. Teksttool, bij 3.2 Datum, bij 3.2 Truthy en falsey, bij 3.3 Short-circuit evaluation, bij 3.4 OPDRACHT 7b.3 In deze opdracht oefent u met de if-else-constructie. Uitgangspunt vormt de teksttool uit de vorige leereenheid. U vindt de bestanden in de directory teksttool in de bouwstenen. Voeg een knop Geen spaties toe die spaties laat verdwijnen. U vindt een uitwerking bij de bouwstenen: teksttool/teksttool.html en teksttool.teksttool.js. OPDRACHT 7b.4 In deze opdracht experimenteert u met de switch-constructie. In de map datum bij de bouwstenen vindt u code met een switch erin, die afhankelijk van de dag van de week een welkomstboodschap in de pagina zet. Als u meer wilt weten over het ingebouwde Date object brengt de weblink Referentie Date object u bij de referentie. a Bekijk de code en laadt de pagina in Firefox. Haal dan de breaks weg en laad de pagina opnieuw (niet op zaterdag!). Verklaar het effect. U vindt een verklaring bij de terugkoppeling. b Verander de code nu zo dat er alleen wordt gemeld of vandaag in het weekend valt of een weekdag is. U vindt een uitwerking bij de bouwstenen, in datum/datum.js. OPDRACHT 7b.5 In deze opdracht controleert u wat u weet over truthy en falsey waarden. In truthyenfalsey/datum.js vindt u de code van de vorige opdracht, waarbij op twee plaatsen een alert is tussengevoegd. Bekijk de code, voorspel welke alert wel en welke niet zal verschijnen, en test of u gelijk heeft. U vindt een toelichting in de terugkoppeling. OPDRACHT 7b.6 Om short-circuit evaluation in werking te zien doet u het volgende. Geef in de console van Firebug in: var a = dinges.doeiets(); OU 43

Webapplicaties: de clientkant Firebug zal aangeven: ReferenceError, dinges is not defined. Geef nu in de console in: b = 1 nogeendinges.doeiets(); b; Firebug zal aangeven dat de variabele b de waarde 1 heeft. De expressie nogeendinges.doeiets(); is dus niet geëvalueerd. Er is geen uitwerking bij deze opdracht. Default-waarde, bij 3.4 Leapyears, bij 3.5 Globaal en lokaal, bij 4.1 OPDRACHT 7b.7 In het blog-voorbeeld kunt u een default-waarde voor de tekst in het textarea-element gebruiken. Uitgangspunt is de uitwerking van opdracht 7b.2. Verander de functie publiceer zo dat, als de gebruiker op Publiceer klikt zonder iets in de textarea te hebben gezet, de volgende tekst als invoer wordt genomen: 'Vandaag heb ik geen zin om te bloggen!!!'. U vindt een uitwerking in blog/default.js. OPDRACHT 7b.8 In deze opdracht bekijkt u een while loop. Bekijk de code van Example 7.40. De benodigde bestanden zitten bij de bouwstenen: leapyears/schrikkel.html en leapyears/schrikkel.js. Probeer uit wat er gebeurt als u geen getal invult en op de knop klikt (niet schrikken: de browser blijft niet permanent hangen!). Kijk ook wat er gebeurt als u negentienhonderd als jaar invoert. Verbeter het script door op een geschikte plaats een default-waarde te schrijven. Een uitwerking zit bij de bouwstenen: leapyears/schrikkel.js. OPDRACHT 7b.9 Bekijk globaal/globaal-lokaal.js en open globaal/globaal.html in de browser, met Firebug geopend. Firebug meldt dat b niet is gedefinieerd. Verwijder in het JavaScript-bestand de regels die de waarde van b en c willen schrijven uit de functie voor window.onload en ververs de pagina. Er horen nu geen foutmeldingen meer voor te komen. Verander nu de regel a = 2 * 2; in de functie scopetest in: var a = 2 * 2; Kijk nogmaals wat er gebeurt met de waarde die er voor a wordt geschreven buiten de scopetest. Verklaar steeds wat u ziet. Er is een uitwerking bij de terugkoppeling. Linklijst, bij 4.2 OPDRACHT 7b.10 Met behulp van de methoden van het array-object kunt u het blog-voorbeeld uitbreiden met de mogelijkheid voor het toevoegen van links. 44 OU

Leereenheid 7b JavaScript for Interactive Web Pages 2 Aan de HTML is de volgende code toegevoegd (u vindt de bestanden bij de bouwstenen als blog/links.html, blog/links.js en blog/links.css): <h2>voeg een link toe</h2> <div> <label for="url">url</label> <input type="text" id="url"></input> <label for="naam">naam</label> <input type="text" id="naam"></input> </div> <div> <button id="publink">publiceer</button> </div> <div id="menu"> <h3>links</h3> <ul id="linkslijst"></ul> </div> De pagina ziet er nu als volgt uit: FIGUUR 7b.2 Blog met links a Declareer een globale variabele linklijst, en initieer die als lege array. Schrijf een functie updatelijst die de elementen van linklijst tussen li-tags zet (u kunt daar de methode join van array voor gebruiken), en die het element met id linkslijst vult met die li-elementen. b Schrijf een methode publiceerlink die aan de variabele linklijst een string toevoegt met als waarde een a-element met de URL uit het formulier als href, en de naam als waarde. Roep aan het einde van deze functie de zojuist geschreven functie updatelijst aan. Voeg publiceerlink als event handler toe aan de knop met id publink, en test of alles werkt. U vindt een uitwerking in blog/links.js. OU 45

Webapplicaties: de clientkant Parameters, bij 4.3 Examen, bij de gehele leereenheid OPDRACHT 7b.11 De functie publiceer is nogal onoverzichtelijk geworden. Een oplossing daarvoor is om er een aantal functies uit te splitsen. a Schrijf een functie regels, die als parameter een waarde van type String heeft, en als returnwaarde een string geeft waarin de punten vervangen zijn door een punt gevolgd door een br-tag. b Schrijf een functie paragrafen, die als parameter een waarde van type String heeft, en als returnwaarde een string geeft waarin de enters vervangen zijn door p-tags. c Vereenvoudig de functie publiceer door gebruik te maken van die nieuwe functies. U vindt een uitwerking bij de bouwstenen: blog/return.js. OPDRACHT 7b.12 In de bouwstenen vindt u de bestanden examen.html, examen.js en examen.css. Als u examen.html in Firefox opent ziet u de volgende pagina: FIGUUR 7b.3 De pagina examen.html a Bekijk de drie bestanden en probeer te achterhalen hoe de pagina wordt opgebouwd. Wat is er met de tips gebeurd die u in de HTML ziet? U vindt een toelichting bij de terugkoppeling. b Vul het JavaScript-bestand zo aan dat de tips verschijnen als de gebruiker met de muis over een van de vraagtekens beweegt, en weer verdwijnen als de muis niet over een vraagteken beweegt. U kunt daarvoor de functies toon en wis gebruiken die in examen.js staan. Event handlers binden aan het met de muis in of uit een element bewegen doet u met 46 OU

Leereenheid 7b JavaScript for Interactive Web Pages 2 element.onmouseover = functienaam; en element.onmouseout = functienaam; U kunt de functies toon en wis niet direct als event handlers gebruiken: de functies verwachten een parameter, en die kunt u niet meegeven bij het opgeven van de event handler; u kunt alleen de naam opgeven. U zult dus twee event handlers moeten schrijven die gebruik maken van toon en wis, en met behulp van die functies alle tips laten verschijnen en verdwijnen. U vindt een toelichting bij de terugkoppeling. c Schrijf een functie controleer die de antwoorden checkt, en de vraagtekentjes verandert in goed.jpg of fout.jpg. De juiste antwoorden zijn gespecificeerd in de arrays voor elke vraag: de string achter elke array met antwoorden geeft het juiste antwoord aan. De door een gebruiker gekozen waarde van een select-element is te vinden in de value van dat element. Bindt de functie aan de knop onderaan de pagina met het vraagteken: als de gebruiker op de knop drukt moeten de gegeven antwoorden worden gecontroleerd. U vindt een toelichting bij de terugkoppeling. d Breid de functie controleer nu zo uit dat de knop met het id controleer verandert in geslaagd.jpg bij drie of meer goede antwoorden, en in gezakt.jpg bij minder dan drie juiste antwoorden. Zorg ervoor dat er bij vijf juiste antwoorden een alert komt met `Uitstekend!!!', en bij nul of één juist antwoord een alert met `Dat was wel erg minimaal!'. U vindt een toelichting bij de terugkoppeling, en er is een een complete uitwerking in de bouwstenen: examen/examen.js. Z E L F T O E T S 1 Gegeven is de volgende code: var aantal = 5; function verdubbel(aantal) { return 2 * aantal; var uitkomst = verdubbel(4); a Welke waarde heeft uitkomst na het uitvoeren van deze code? b Leg uit waarom uw antwoord te maken heeft met lokale en globale variabelen. OU 47

Webapplicaties: de clientkant 2 Gegeven is de volgende code: var count = 0; function zonderklinkers(woord) { var result = ""; for (count = 0; count < woord.length; count ++) { switch (woord.charat(count)){ case "a": case "e": case "i": case "o": case "u": break; default: result += woord.charat(count); return result; zonderklinkers("webdevelopment"); a Wat is de waarde van count na het doorlopen van de code? b Misschien is hier sprake van een vergissing. Welke vergissing? 3 a Hoe kunt u op een korte manier testen of de variabele myvariable bestaat en een waarde heeft? b In welke gevallen loopt de test mis? 4 Wat betekent de term truthy? 5 Gegeven is de volgende JavaScriptcode: var lijst = [5, 20, 4, 7, 13]; Hoe voegt u de getallen 6 en 8 aan deze array toe, vooraan? 6 Gegeven is de volgende JavaScriptcode: var lijst1 = [1, 2, 3]; var lijst2 = [5, 6, 7, 8]; U wilt de elementen uit de tweede lijst achterstevoren toevoegen aan de eerste lijst, tot en met het getal 6. Gebruik een while loop om dat te doen. 7 Schrijf een functie voorzievantags, met als parameters een tekst en de naam van een tag, die HTML-code teruggeeft waarbij de tekst van beginen eindtag is voorzien. 48 OU

Leereenheid 7b JavaScript for Interactive Web Pages 2 T E R U G K O P P E L I N G 1 Uitwerking van de opgaven 7b.1 Expressie Impliciete typeconversie 5 < 10.0 geen impliciete typeconversie, want het type Number is er voor zowel gehele als reële getallen 7 == "7" impliciete typeconversie, want om te kunnen vergelijken moet de string "7" eerst naar een waarde van type Number geconverteerd worden. 7 === "7" geen impliciete typeconversie, want de operator === vergelijkt ook de typen, en er zal dus juist niet geconverteerd worden. 7!= "7.0" impliciete typeconversie, want om te kunnen vergelijken moet de string "7.0" eerst naar een waarde van type Number geconverteerd worden. 7!== "7.0" geen impliciete typeconversie, want de operator!== vergelijkt ook de typen met elkaar, en er vindt dus geen conversie plaats. 42 < "hello" impliciete typeconversie, want om te vergelijken moet "hello" geconverteerd worden naar een waarde van type Number. Dat lukt niet, zodat typeconversie de waarde NaN oplevert. 42 >= "hello" impliciete typeconversie, op dezelfde manier als hierboven. 10 > impliciete typeconversie, want om te vergelijken moet destring "3 french "3 french hens" worden geconverteerd naar een waarde van type hens" Number. Dat lukt niet, zodat typeconversie de waarde NaN oplevert 7b.2 U zou twee for loops kunnen gebruiken op de volgende manier: var lengte = name.length; // even for (var i=0; i < lengte; i=i+2) { name = name.charat(i).touppercase(); // oneven for (var i=1; i < lengte; i=i+2) { name = name.charat(i).tolowercase(); 7b.3 Stel dat de variabele myvariable op een van de volgende manieren is gedeclareerd: var myvariable = 0; var myvariable = ""; var myvariabele = null; var myvariable = false; De test if (myvariable) zal dan false opleveren, ondanks het feit dat de variabele wel bestaat en wel een waarde heeft. 7b.4 a Een for-lus zoals: for (var count=0; count < 40; count++) wordt precies veertig maal doorlopen. De while-lus uit het voorbeeld wordt net zo lang doorlopen tot er tien schrikkeljaren zijn gevonden. Afhankelijk van het gekozen jaar kan dat dus vaker of minder vaak zijn (het hangt er bijvoorbeeld van af of er een jaar tussen zit dat door 100 deelbaar is). OU 49

Webapplicaties: de clientkant b Het is een goede programmeergewoonte om de functie parseint te gebruiken als u invoer van een gebruiker inleest, en een getal verwacht. Juist omdat JavaScript aan impliciete typeconversie doet, kunnen er fouten ontstaan als u bijvoorbeeld de + operator gebruikt. Als u de functie parseint gebruikt, kunt u er van uitgaan dat u een waarde van type Number heeft, en dat u een geheel getal heeft en geen getal met decimaal. 7b.5 De variabele document moet een globale variabele zijn. Als het een lokale variabele zou zijn, zou hij ergens binnen een functie zijn gedeclareerd, en zou hij buiten die functie als waarde undefined hebben. Het feit dat u hem vanuit willekeurig welke functie kunt gebruiken bewijst dus dat het een globale variabele is. U heeft die globale variabele niet zelf gedeclareerd. Het is de JavaScriptomgeving van de browser die dat voor u heeft gedaan, en die de variabele ook een waarde heeft gegeven waar u als JavaScript-programmeur gebruik van kunt maken. 7b.6 a Het fruit dat met een a begint krijgt u met: woorden[0][1]; b Het dier dat met een c begint krijgt u met: woorden[2][0]; 7b.7 Bij het schrijven van zo'n functie kunt u gebruik maken van het feit dat JavaScript geen foutmelding geeft als u een functie aanroept met minder parameters dan waarmee u die functie heeft gedefinieerd. U kunt bovendien gebruik maken van de in 7.3.4 beschreven methode om een default-waarde te creëren. De functie zou er dan als volgt uit kunnen zien: function macht(basis, exponent) { exponent = exponent 2; return Math.pow(basis, exponent); Een nadeel van deze oplossing is dat de functie geen juiste waarde op zal leveren als de exponent 0 is: dan wordt als exponent 2 gebruikt. 2 Uitwerking van de opdrachten 7b.2 Er bestaat een handiger oplossing dan de oplossing waarbij u de if-elseconstructie gebruikt: JavaScript kent de functie replace: string.replace(substring, nieuwesubstring); De eerste parameter is de te vervangen substring; de tweede parameter is de substring die de eerste vervangt in string. De functie replace vervangt het eerste voorkomen van de te vervangen substring. Voor het vervangen van alle voorkomens van de te vervangen substring heeft u reguliere expressies nodig; die vallen buiten de onderwerpen in deze cursus. We laten hier zien hoe u alle voorkomens van de punt kunt vervangen, maar lichten de reguliere expressie niet verder toe. 50 OU

Leereenheid 7b JavaScript for Interactive Web Pages 2 Met behulp van die functie kunt u de code vereenvoudigen: function publiceer() { var detekst = ""; var input = document.getelementbyid("tekst").value; input = input.replace(/\./g, ".<br>"); var paragrafen = input.split("\n"); var lengte = paragrafen.length; for (var i=0; i < lengte; i++) { detekst += "<p>" + paragrafen [i] + "</p>"; document.getelementbyid("nieuw").innerhtml = detekst; 7b.4 a Als in het case-gedeelte van een switch statement geen break staat, wordt alles wat in de volgende case-gedeelten staat ook uitgevoerd. 7b.5 In de if-else-constructie voor de eerste alert wordt getest op een variabele die een lege string als waarde heeft: var boodschap = ""; if (boodschap) { alert("een lege boodschap"); Een lege string is een falsey waarde: deze alert zal dus niet verschijnen. In de volgende if-else-constructie heeft de variabele boodschap wel een waarde gekregen. Die waarde is truthy; de alert zal dus wel verschijnen. 7b.9 In de oorspronkelijke code is de enige variabele die globaal bekend is a. In window.onload wordt naar b en c verwezen, maar die hebben binnen die functie geen waarde gekregen: vandaar dat Firebug een foutmelding geeft. Als u het keyword var toevoegt aan de plaats waar a een waarde krijgt binnen de functie scopetest, wordt die a daarmee een andere variabele dan de globale a. U ziet dan achtereenvolgens: Buiten scopetest is a 2 Binnen scopetest is a 4 Buiten scopetest is a 2 Als u (door het keyword var weer weg te halen) binnen de functie scopetest de globale a een nieuwe waarde geeft, verandert dat in: Buiten scopetest is a 2 Binnen scopetest is a 4 Buiten scopetest is a 4 De globale a is dus ook veranderd. 7b.12 a De stijl van de div-elementen met class tip laat zien: visibility:hidden. Daardoor zijn de tips niet te zien. b Aan window.onload voegt u de volgende regels toe binnen de forlus: document.getelementbyid("uitslag"+i).onmouseover = toontips; document.getelementbyid("uitslag"+i).onmouseout = wistips; OU 51

Webapplicaties: de clientkant De functies toontips en wistips definieert u als volgt: function toontips { for (var i=0; i < 5; i++) { toon(document.getelementbyid("tip" + i)); function wistips() { for (var i=0; i < 5; i++) { wis(document.getelementbyid("tip" + i)); Verderop in de cursus zult u leren hoe u in dit geval alleen de tip die bij het desbetreffende vraagteken hoort kunt laten verschijnen en verdwijnen. Daarvoor heeft u op dit moment nog niet voldoende kennis. c De functie controleer kunt u als volgt implementeren: function controleer() { for (var i=0; i < 5; i++) { if (document.getelementbyid("antwoord" + i).value == vragen[i][2]) { document.getelementbyid("uitslag" + i).src = "goed.jpg"; else { document.getelementbyid("uitslag" + i).src = "fout.jpg"; In window.onload voegt u buiten de for-lus toe: document.getelementbyid("controleer").onclick = controleer; d U kunt de functie als volgt uitbreiden: var aantaljuist = 0; for (var i=0; i < 5; i++) { if (document.getelementbyid("antwoord" + i).value == vragen[i][2]) { document.getelementbyid("uitslag" + i).src = "goed.jpg"; ++ aantaljuist; else { document.getelementbyid("uitslag" + i).src = "fout.jpg"; 52 OU

Leereenheid 7b JavaScript for Interactive Web Pages 2 switch (aantaljuist) { case 5: alert("uitstekend!!!"); case 4: case 3: document.getelementbyid("controleer").src = "geslaagd.jpg"; break; case 0: case 1: alert("dat was wel erg minimaal!"); case 2: document.getelementbyid("controleer").src = "gezakt.jpg"; De switch werkt hier gemakkelijker dan een constructie met if en een aantal maal else if: het is overzichtelijker zo. De code voor de gehele uitwerking vindt u bij de bouwstenen. Denk er aan dat de oplossing met een aantal globale variabelen niet optimaal is; hoe dat beter kan leert u verderop in deze cursus. 3 Uitwerking van de self-checks 14 De == operator vergelijkt waarden, en past impliciete typeconversie toe als dat nodig is. De === operator past geen impliciete typeconversie toe. Met behulp van die laatste operator is het dus mogelijk om onderscheid te maken tussen de waarde 10 en de waarde "10". Met de == operator is dat niet mogelijk. 15 a falsey b truthy c falsey d falsey e truthy f falsey g falsey Of een waarde truthy of falsey is, is gemakkelijk te testen in de console van Firebug. Met bijvoorbeeld -: Boolean("false"); 16 a 2 b 42 c 0 d "me" e null f "1" g 1 JavaScript kijkt niet verder dan nodig is. Bij de operator kan er dus gestopt worden als er een truthy waarde is gevonden (de hele expressie is dan truthy); bij de && operator moet juist alles bekeken worden, omdat er altijd een falsey waarde tussen kan zitten. OU 53

Webapplicaties: de clientkant 17 if (!amount) { De restrictie is dat een bedrag van 0 ook een waarschuwing zal opleveren. 18 De waarde van a is 4: a kreeg eerst als waarde 1, en heeft in de aangeroepen functie f de waarde 4 gekregen. De waarde van b is 2: b kreeg eerst als waarde 2, en is in de aangeroepen functie f niet veranderd.. De waarde van c is 3: c kreeg eerst als waarde 3, en dat is zo gebleven. De variabele c die in de aangeroepen functie f de waarde 5 krijgt is een andere, lokale variabele. De waarde van d is undefined. De variabele d bestaat niet buiten de functie f: binnen de functie is het een lokale variabele. De waarde van e is 6: binnen de functie f is e (impliciet) globaal gedeclareerd, doordat het keyword var niet is gebruikt. Bij de aanroep van f heeft e daarom een waarde gekregen, en e blijft met die waarde bestaan buiten de functie. 19 var naam = ["Barack, "Hussein", "Obama"]; 20 De betekenis van het woord slice is in plakken snijden.de methode slice is bedoeld om een subarray te krijgen, die begint bij de meegegeven index in de array, tot en met de meegegeven eindindex, of, als die niet wordt meegegeven, tot en met het laatste element van de array. De betekenis van het woord splice is verbinden, ineenvlechten, lassen. De methode splice verwijdert een opgegeven aantal elementen uit de array, te beginnen bij de opgegeven beginindex, en voegt er de elementen aan toe die bij de aanroep worden meegegeven. Het aantal van die elementen doet er niet toe (en hoeft dus niet hetzelfde te zijn als het aantal verwijderde elementen). 21 De array ziet er achtereenvolgens als volgt uit: ["Stef", "Amit"] ["Stef", "Amit", "Brian"] ["Morgan", "Stef", "Amit", "Brian"] ["Morgan", "Stef", "Amit"] ["Stef", "Amit"] ["Amit", "Stef"] ["Amit", "Victoria", "Stef"] 22 Er is een aantal mogelijkheden. De eerste manier is om gewoon de string letter voor letter te vergelijken met de overeenkomstige letter van de achterkant: function palindromealert(woord) { var palindroom = true; var woordlengte = woord.length; for (var i=0; i < woordlengte/2; i++) { if (word.charat(i)!= word.charat(woordlengte-i-1) { palindroom = false; 54 OU

Leereenheid 7b JavaScript for Interactive Web Pages 2 if (palindroom) { alert("het is een palindroom!"); else { alert("nee, geen palindroom"); Een andere manier maakt van de methoden pop en shift van arrays gebruik, om steeds de eerste en laatste letter met elkaar te vergelijken. Daartoe veranderen we de string eerst in een array met de methode split, waarbij we een lege string als delimiter geven (dat levert een array van letters op): function palindromealert(woord) { var palindroom = true; var woordarray = woord.split(""); while (woordarray.length > 1) { if (woordarray.shift()!= woordarray.pop()) { palindroom = false; if (palindroom) { alert("het is een palindroom!"); else { alert("nee, geen palindroom"); Het lijkt aantrekkelijk om gebruik te maken van de methode reverse van array, maar omdat twee arrays alleen element voor element met elkaar te vergelijken zijn schieten we met die methode niet veel op. 23 Zo n functie is: function fnaarc(fgraden) { return (Fgraden 32) * 5 / 9; 4 Uitwerking van de zelftoets 1 a 8 b Als de body van de functie verdubbel wordt uitgevoerd, is de variabele aantal die via de parameter wordt meegegeven een andere dan de globale variabele aantal. Binnen de body is aantal een lokale variabele, en de waarde ervan wordt bepaald door de meegegeven parameter. De variabele aantal binnen de body heeft dus niets te maken met de globale variabele aantal. 2 a 14 b Het is mogelijk dat de programmeur per ongeluk het keyword var is vergeten voor de definitie van de variabele count in de for-lus. In dat geval was het eigenlijk de bedoeling dat de variabele count waarmee de lus wordt doorlopen een andere is dan de globale variabele count. Daarnaast gaat het mis met de "ij": daarvan blijft alleen de "j" over. OU 55

Webapplicaties: de clientkant 3 a if (myvariable) b De test loopt mis als myvariable een falsey waarde heeft, zoals 0 of "". 4 In JavaScript vindt er altijd impliciete typeconversie plaats als er een waarde van type Boolean verwacht wordt. Een waarde die converteert naar true wordt truthy genoemd. 5 De getallen 6 en 8 vooraan aan de array toevoegen gaat op de volgende manier: lijst.unshift(6, 8); 6 De elementen uit de tweede lijst achterstevoren toevoegen aan de eerste lijst, tot en met het getal 6 gaat op de volgende manier: while (lijst1[lijst1.length-1]!== 6) { lijst1.push(lijst2.pop()); 7 Zo n functie kan er als volgt uitzien: function voorzievantags(tekst, tag) { var begintag = "<" + tag + "<"; var eindtag = "</" + tag + ">"; return begintag + tekst + eindtag; 56 OU