Language elements Statements Variables Data Types Operators Control structures Functions Objects Events
4 4 4 4 6 8 11 12 13
The Document Object Model Legacy DOM Intermediate DOM DOM Level 1 DOM Level 2 DOM Level 3 DOM Level 4
18 18 18 18 18 19 19
The Browser Object Model Document Frames History Location Navigator Screen
20 20 20 21 21 21 22
jQuery Bestaansrecht jQuery Syntax jQuery Plugin
23 23 23 24
Reflectie
25
Geschiedenis In 1995 werd JavaScript (voorheen LiveScript) ontwikkeld door Brendan Eich, werkzaam bij Netscape Communications. Op dat moment was Microsoft bezig met de ontwikkeling van JScript. Beide talen voorzien de browser van mogelijkheden tot client-side scripting en zijn event-driven. Dit betekent dat de scripts worden uitgevoerd op processorkracht van de client (de computer van de gebruiker) en dat het script gestuurd wordt door handelingen die de gebruiker uitvoert. De talen verschilden van elkaar en werden niet door alle browsers ondersteund. JavaScript werd begrepen door alle Mozilla based browsers en JScript enkel door Internet Explorer. Om die reden ontstond op dat moment vanuit beide partijen de behoefte tot standaardisatie. De vraag aan het W3C (World Wide Web Consortium) om JavaScript te standaardiseren kwam in eerste instantie vanuit Netscape. Het W3C wees dit af en daaropvolgend stapte Netscape naar ECMA (European Computer Manufacturers Association). Omdat de merknaam JavaScript eigendom was van Sun Microsystems besloot deze dat de nieuwe standaard ECMAScript zou worden. Een taal die door alle browsers geïnterpreteerd zou moeten kunnen worden. Netscape en Microsoft gingen beiden verder met de ontwikkeling van respectievelijk JavaScript en JScript, maar baseerden deze nu op de nieuwe standaard ECMAScript. ActionScript werd in augustus 2000 geïntroduceerd door Adobe en is ook een afgeleide van de ECMA standaard. De taal wordt tegenwoordig ondersteund door Adobe Flash en Adobe Flex en is de opvolger van Adobe’s “Actions” uit 1999, een programmeertaal die nog werd gebruikt door Flash 4. Omdat webdevelopers hier vaak niet mee uit de voeten konden is er toenadering gezocht tot het meer herkenbare ECMAScript, waardoor programmeurs nu procedureel script of objectgeoriënteerde script konden gaan schrijven. In 2003 werd ActionScript 2.0 geïntroduceerd. De taal werd steeds meer object georiënteerd, maar werd nog altijd gecompileerd naar ActionScript 1.0. Met de komst van ActionScript 3.0 en Flash Player 9 in 2006 werd hier nog een grote wijziging in aangebracht door de Flash Player van twee Virual Machines te voorzien. VM1 wordt gebruikt voor de interpretatie van AS1.0 en AS2.0 en VM2 wordt gebruikt voor de interpretatie van AS3.0.
Language elements Statements Met een statement wordt het commando naar de browser bedoeld. document.getElementById("text").innerHTML = "Hello World"; In dit voorbeeld wordt de HTML binnen het HTML element met de identifier “text” veranderd naar de string “Hello World”. Een statement wordt altijd afgesloten met een semicolon.
Variables Met een variable wordt de houder voor opslag van informatie bedoeld. var x = 5; var y = 6; var z = x + y; Op regel 1 van dit voorbeeld wordt het getal 5 gedefinieerd als Number en opgeslagen in de variable met de naam x.
Data Types Met de definitie van een data type wordt het soort variable bepaald. De manier waarop JavaScript hier mee omgaat is dynamisch. Dit betekent dat het soort data in de variable kan verschillen. Met de global javascript function .typeof() kan het data type van een object worden achterhaald. Een global function kan vergelijken worden met een method, maar is dan niet gekoppeld aan één specifiek object en kan dus binnen verschillende objecten gebruikt worden. String Als een variable als string is gedefinieerd betekent dit dat het een serie aan karakters opslaat welke is gedefinieerd tussen de twee dubbele of enkele quotes (“ of ‘). Number Als een variable als number is gedefinieerd betekent dit dat het een getal mét of zonder decimalen bevat. Getallen kunnen negatief zijn en ook een
wetenschappelijke notatie voor extra grote of kleine getallen wordt op de juiste manier geïnterpreteerd. Boolean Als een variable als boolean is gedefinieerd kan deze twee waarden bevatten. True of false. De standaardwaarde van een boolean is false. Array Als een variable als array is gedefinieerd kan deze meerdere objecten tegelijkertijd bevatten. Deze objecten kunnen verschillen van data type en op zichzelf ook weer een array bevatten. In dit laatste geval spreken we van een multidimensionale array. De gewenste data wordt opgeroepen aan de hand van de index van het item. Het array object heeft een aantal specifieke properties en methods. Properties bevatten eigenschappen van het array object, zo kennen we binnen de array de property .length, welke de lengte van de array teruggeeft. Deze wordt vaak gebruikt om het aantal iteraties binnen een loop te kunnen vaststellen. Wanneer we een method aanroepen voeren we een bepaalde actie binnen het object uit. Het array object kent de .indexOf(‘value’) method. Deze method geeft het index number van een bepaald item in de array terug. Een ander veelvoorkomende method is .sort(). Met deze method kunnen we de waarden binnen een array sorteren op alfabetische of numerieke volgorde, zowel oplopend als aflopend. Om de reeks van waarden in de array aflopend te maken gebruiken we de .reverse() method. Object Zo’n beetje alles binnen JavaScript kan een object zijn en zijn in principe niet anders dan variables. Zelf vind ik de metafoor “dingen“ het meest treffend.
In het hoofdstuk “Objects” zal hier nog dieper op ingegaan worden. Undefined & null Over het algemeen worden variables netjes gedefinieerd bij de initatie van het script. Wanneer dit niet het geval is en een variable “on the fly” wordt aangemaakt, om bijvoorbeeld tijdelijk een waarde op te slaan, kan het voorkomen dat de variable undefined of null value teruggeeft. Op beiden zit men meestal niet te wachten, maar het verschil is wel van wezenlijk belang tijdens het debuggen van een script. Null wordt in JavaScript namelijk gezien als een object. Het Document Object Model geeft over het algemeen null terug wanneer het een bepaald element bijvoorbeeld niet kan vinden. Wanneer dit in JavaScript het geval is
wordt er undefined teruggegeven. Er kan een situatie voorkomen waarin je zult moeten checken of een variable null of undefined is. var x; //undefined (x == undefined)//true (x == null) //true In het bovenstaand voorbeeld wordt de equality operator (==) gebruikt. Er vindt hier ook type conversion plaats. Dat wil zeggen dat de data types van x en null kunnen verschillen, maar dat deze bij een vergelijkbare waarde gelijk wordt getrokken en de expressie alsnog true is. var x; //undefined (x === undefined) //true (x === null) //false In bovenstaand voorbeeld wordt de identity operator (===) gebruikt. Er vindt hier geen type conversion meer plaats en de uitkomst van de expressie blijkt dus ook false te zijn. Dat wil zeggen dat de data types van x en null niet overeenkomen.
Operators Een operator is een karakter(reeks) welke gebruikt worden binnen de expressie. Dit kan verschillende doelen hebben. Ze worden gebruikt om variables te definiëren, berekeningen uit te voeren of condities te vergelijken. Arithmic operators Met deze operators kan het script berekeningen uitvoeren. Een variable kan gedefinieerd worden, hier kunnen getallen bij opgeteld worden of juist vanaf getrokken worden. We kunnen binnen de expressie getallen met elkaar vermenigvuldigen of juist door elkaar delen. Ook kunnen we de modulus achterhalen. De modulus wordt gebruikt om het restgetal van een deling te achterhalen. Wanneer we bijvoorbeeld willen uitvinden hoe veel seconden er overblijven als we zo veel mogelijk volle minuten uit 10000 seconden willen halen, gebruiken we de modulus. s = 10000 % 60;
//s = 40
Assignment operators Met deze operators worden variables gedefinieerd. Deze variables krijgen dankzij een assignment operator data van een bepaald type toegewezen.
x = 0; x = “Hello world”; Ook zijn er combinaties van operators mogelijk om nieuwe operators te gebruiken. Het volgende voorbeeld laat zien hoe assignment operators worden gebruikt om expressie korter te schrijven. x += 5; //Hetzelfde als x = x + 5 Ditzelfde geldt ook voor het aftrekken, vermenigvuldigen, delen door en het gebruik van de modulus. Comparison operators Binnen expressies worden operators vaak gebruikt om bijvoorbeeld het verschil of de overeenkomst van twee variables te duiden. Dit noemen we comparison operators. Bij een succesvolle uitkomst, wordt true teruggegeven. Wanneer de uitkomst niet succesvol is (het expressies klopt niet), dan wordt false teruggeven. Variable x is gelijk aan de waarde in de expressie: var x = 6; (x == 6) //true (x === “6”) //false Variable x is niet gelijk aan de waarde in de expressie: var x = 6; (x != 6) //true (x !== 6) //true Variable x is groter dan de waarde in de expressie: var x = 6; (x > 8) //false Variable x is kleiner dan de waarde in de expressie: var x = 6; (x < 8) //true Variable x is groter of gelijk aan de waarde in de expressie: var x = 6; (x >= 8) //false Variable x is groter of kleiner dan de waarde in de expressie: var x = 6; (x <= 8) //true
Logical operators Expressies kunnen aan elkaar worden uitgebreid middels logical operators. We kennen &&, || en !. Hieronder volgen voorbeelden die het gebruik verduidelijken: var x = 6; (x < 8 && x == 6) (x < 8 || x == 8) !(x < 8)
//true (x is kleiner dan 8 en x is 6) //true (x is kleiner dan 8 of x is 8) //false (x is niet kleiner dan 8)
Conditional operators Conditional operators worden gebruikt om een bepaalde waarde aan een variable toe te kennen, afhankelijk van de uitkomst van de expressie. De conditie van de variable. var x = 0.33; x = (x < 0 ) ? x = -1 : x = 1; //x is groter dan 1 dus de waarde van x wordt 1
Control structures Control structures worden gebruikt om het script een bepaalde kant op te sturen binnen een stuk code of een functie. We kennen if, while, do ..while, for en switch statements. Hier volgen een aantal voorbeelden. if statement Wanneer de expressie binnen het if statement true teruggeeft wordt een volgend statement uitgevoerd. Wanneer dit niet het geval is, dan wordt dit statement overgeslagen. var x = 6; var i = 0; if(x > 3){ i++; } console.log(i); //i is 1 Deze constructie kan ook als volgt geschreven worden. Dit geldt voor alle soorten constructies behalve de switch. var x = 6; var i = 0; if(x > 3) i++;
Wanneer we aan de hand van een tweede mogelijke expressie ook iets willen uitvoeren dan kunnen we het statement uitbreiden met else if(expressie){}. var x = 6; var i = 0; if(x > 3){ i++; } else if(x < 3) { i--; } Wanneer we aan de hand van alle andere mogelijke expressies ook iets willen uitvoeren dan kunnen we het statement uitbreiden met louter else {}. var x = 6; var i = 0; if(x > 3){ i++; } else if(x < 3) { i--; } else { i = 0; } While Het while statement wordt gebruikt om een stuk code uit te voeren zolang als de expressie true is. We kunnen break of continue gebruiken om bijvoorbeeld een if statement te implementeren wat checkt of de gebruikte variable een bepaalde waarde aanneemt die de loop moet stoppen of juist moet laten doorgaan met de volgende iteratie. while (i < 10){ i++; if(i >= 5) break; console.log(i); //Logt 1,2,3 en 4. } Do … while Dit statement is vergelijkbaar met het while statement, met als verschil dat het de code achter do in ieder geval één maal uitvoert en vervolgens de while loop ingaat. do { i++; } while (i < 10);
For De for loop is wederom vergelijkbaar met de while loop, met als verschil we deze op 1 regel kunnen schrijven. De benodigde argumenten in dit statement zijn dan initialization, conditition en step. Ook binnen de for loop zijn break en continue te gebruiken om het script respectievelijk te stoppen of door te laten gaan met de eerstvolgende iteratie. for (var i = 0; i < 10; i++){ console.log(i); //Logt 0,1,2,3,4,5,6,7,9 } Loops worden veelal gebruikt in samenwerking met arrays. De .length property komt dan goed van pas om de laatste iteratie te bepalen. Hieronder volgt een voorbeeld van deze toepassing. a = ["een","twee","drie"]; for (var i = 0; i < a.length; i++){ console.log(a[i]); //Logt een, twee, drie } For in Naast de standaard for loop, die veelal wordt gebruikt om arrays uit te lezen, bestaat er ook de for in loop. Deze wordt toegepast om de waarden van objecten uit te lezen. Zie onderstaand voorbeeld voor een mogelijk toepassing. var object = {een : 1, twee : 2, drie : 3 } for (value in object){ console.log(object[value]); //Logt 1, 2, 3 } Switch Het switch statement evalueert een expressie en bepaalt aan de hand van het resultaat de flow binnen de control structure. De expressie wordt vergeleken met een de case label, welke enkel een constante waarde mag bevatten, en als deze true wordt bevonden wordt het bijbehorende statement uitgevoerd. switch(x){ case 1: console.log(“x is 1”); break;
case 2: console.log(“x is 2”); break default: console.log(“x is iets anders dan 1 of 2”); break; } In de basis is het switch statement vergelijkbaar met het if statement. Qua performance wint de switch het echter van het if statement. Bij het if statement worden de condities namelijk op volgorde gecheckt terwijl een switch direct naar het betreffende case label springt en de code uitvoert.
Functions Parameters Een functie is een blok specifieke code welke wordt uitgevoerd op het moment dat de functie wordt aangeroepen. Een functie kan bepaalde parameters met zich meedragen, deze vinden we tussen de haakjes (()). Local & Global variables Wanneer de functie bepaalde waardes ontvangt, hebben deze waarden een lokale scope. Dat wil zeggen dat ze enkel binnen de functie gebruikt kunnen worden. De variables die buiten de functie worden gedefinieerd noemen we global variables. Dat wil zeggen dat de variable binnen de volledige web pagina te gebruiken is. Local variables worden verwijderd wanneer de functie is uitgevoerd en de global variables worden verwijderd wanneer de web pagina wordt afgesloten. Syntax De syntax van een functie luidt als volgt: function custom_function(param1, param2) { return param1 * param2; } x = custom_function(arg1, arg2); Return Dit statement geeft de caller, het statement wat de functie aanroept, van de functie een waarde terug en stopt de functie. Zie de toepassing van de bovenstaande functie in onderstaand voorbeeld. x = custom_function(3, 4); //x = 12
Objects Zoals we eerder bij het deelonderwerp objects in het hoofdstuk Language Elements behandelden, kan zo’n beetje alles binnen JavaScript een object zijn. We gebruikten hier de metafoor “dingen”. Properties Deze dingen, ofwel objecten, hebben specifieke eigenschappen. Zo kan een object rood of groen zijn. We hebben het dan over de property color van het object. Deze kan opgevraagd worden door bijvoorbeeld de property object.color aan te roepen. Methods Naast dat deze objecten bepaalde eigenschappen hebben kunnen zij ook methods met zich meedragen. Methods zijn bepaalde acties die binnen het object uitgevoerd kunnen worden. Zoals bij het object array reeds beschreven kunnen deze methods iets doen met de waarden die het object bevat. Syntax Er zijn verschillende manieren om objecten te creëren, de meest eenvoudige is de object literal. Hiermee kunnen we binnen één statement het object zowel creeren als definiëren. De literal bevat een reeks van names en values door komma’s gescheiden. var person = {firstName : "Peter",lastName : "Polman",age : 25}; Een andere manier om het object te creëren en te definiëren luidt als volgt: var person = new Object(); person.firstName = "Peter"; person.lastName = "Polman"; person.age = 25; Accessing properties De eigenschappen van een object zijn op twee verschillende manieren te benaderen. De eerste luidt als volgt: firstName = person.firstName; We kunnen een eigenschap ook opvragen met een syntax die vergelijkbaar is met die van de array. In dit geval is het mogelijk om de key een variable van het type String te laten zijn. In tegenstelling tot arrays is het bij objecten niet mogelijk om een Number als key te gebruiken.
key = “firstName”; firstName = person[key]; Accessing methods Een method is in principe niets anders dan een functie gedefinieerd als property binnen een object. Deze functie kan dus voorzien worden van parameters en andere properties binnen het object gebruiken. var object = { firstName : "Peter", lastName : "Polman", age : 25, fullName : function(){ return object.firstName + " " + object.lastName; } } In het bovenstaande voorbeeld kan de custom method .fullName() aangeroepen worden om zowel de voor- als achternaam te loggen. In dit geval dus Peter Polman.
Events HTML Events zijn dingen die gebeuren met HTML elementen. JavaScript kan gebruikt worden om op deze events te reageren. Deze events zijn te verdelen in dingen die de browser doet, of dingen die de user doet. Handlers HTML elementen kunnen voorzien worden van JavaScript event handler attributes. De handler kan een call naar een functie maken of een stuk script uitvoeren. Als we een custom functie willen aanroepen op het moment dat er op een HTML element wordt geklikt, dan kunnen we dit als volgt schrijven. Built-in events zijn onder te verdelen in de volgende categorieën: Mouse Events, Keyboard Events, Frame/Object Events en Form Events. Event Object Het event object bevat standaard een aantal constants, properties en methods. We zullen er hier per categorie een paar behandelen. Constants
Een event maakt een aantal fasen door, de constants in het object beschrijven deze fasen en luiden respectievelijk: CAPTURING_PHASE (1), BUBBLING_PHASE (2), AT_TARGET (3). Middels de property eventPhase, kunnen een van deze drie waarden uitlezen. De numbers achter de names zullen dan teruggegeven worden. Properties Properties kunnen in een functie (getriggerd door een event) informatie over het event geven. Het argument event dient dan wel als parameter meegeven te worden. eventPhase kennen we reeds, daarnaast kunnen we nog properties oproepen die iets over de targetting zeggen, zoals currentTarget en target. Dit kan handig zijn op het moment dat het target van de functie wisselt. De notatie luidt als volgt: <script> function custom_function(e){ return console.log(e.currentTarget.innerHTML); //Logt “Click me!” } Met de intrede van DOM level 3 zijn er naast de standaard built-in events een aantal nieuwe Keyboard Event properties toegevoegd, te weten: keyIdentifier en keyLocation. Deze nieuwe properties kunnen de locaties en identifiers van de toetsen op het toetsenbord worden uitgelezen, zodat het nu ook in de browser mogelijk is om meer toetsen dan de reeds toegankelijke alt, shift en de ctrl toets te gebruiken. Custom events (non built-in) Naast de built-in events bestaan er ook mogelijkheden om custom events aan te maken. Op de ouderwetse manier werd hier gebruik gemaakt van onder andere de in de voorgaande paragraaf genoemde method initEvent(). var custom_event = new Event('build'); element.addEventListener('build', function (e) { /* custom code */ }, false); element.dispatchEvent(event);
Methods
Een deprecated method is initEvent() . We gebruiken tegenwoordig over het algemeen de method addEventListener(), omdat deze het event zowel aanmaakt als koppelt en initieert. De method dispatchEvent() wordt nog wel gebruikt om deze custom events te firen.
preventDefault() is te vergelijken met stopPropagating(, aangezien zij beiden dienen om capturing en bubbling in goede banen te geleiden. preventDefault() voorkomt dat het event zijn default actie uit gaat voeren nadat het event is getriggerd. stopPropagating() voorkomt dat het event uberhaupt nog acties gaat uitvoeren aangaande de volgorde van de getriggerde events. In de volgende paragraaf wordt het fenomeen capturing & bubbling nader toegelicht. Capturing & Bubbling Er bestonden voor DOM level 2 twee verschillende event models. Dit kan ik het best uitleggen aan de hand van een voorbeeld waarin één element in een ander element zit en zij beiden een onClick handler met zich meedragen. Als je op het binnenste element zou klikken, welke event wordt dan als eerst getriggerd? Die van het omsluitende, of die van het binnenste element? ----------------------------------| element1 | | ------------------------| | |element2 | | | ------------------------| | | ----------------------------------Netscape en Microsoft hadden hiervoor beiden een verschillende benadering. Netscape stelt dat het event op het omsluitende element als eerste getriggerd zou moeten worden. Dit noemen we capturing. | | ---------------| |----------------| element1 | | | | -----------| |----------| | |element2 \ / | | | ------------------------| | Event CAPTURING | -----------------------------------
Microsoft stelt dat het event op element2 als eerste getriggerd zou moeten worden en element 1 daarop volgt. Dit noemen we bubbling. / \ ---------------| |----------------| element1 | | | | -----------| |----------| | |element2 | | | | | ------------------------| | Event BUBBLING | ----------------------------------Eind 2000 stelde W3C hier een standaard voor in DOM Level 2. De oplossing was een compromis tussen beiden en laat zich als volgt verbeelden. | | / \ -----------------| |--| |----------------| element1 | | | | | | -------------| |--| |----------| | |element2 \ / | | | | | -------------------------------| | W3C event model | -----------------------------------------Ontwikkelaars hebben nu de vrijheid om te kiezen of ze willen capturen of bubblen door de derde parameter in de EventListener te voorzien van een boolean. element.addEventListener(“click”, custom_function(), true); //set to capture element.addEventListener(“click”, custom_function(), false); //set to bubble Middels de property bubbles kan worden uitgelezen of een event een bubbling event is of niet (true of false).
JSON The student can construct and explain a JSON string. JSON staat voor JavaScript Object Notation. Het is een syntax voor het opslaan en uitwisselen van data en een eenvoudiger alternatief voor XML. Omdat JSON identiek is aan de wijze waarop objecten binnen JavaScript worden genoteerd, hoeft er geen parsing plaats te vinden zoals bij het interpreteren van XML het geval is. Dit scheelt tijd en scoort daarmee performance punten. De syntax van JSON objecten is gelijk aan die van JavaScript objecten. Dit komt waarschijnlijk niet als verrassing, maar toch bestaat er nog een verschil. Binnen het JSON object kunnen namelijk geen functies worden opgenomen, daar het model enkel geschikt is voor de opslag van objecten. .eval() en .parse() Eval wordt binnen JavaScript gebruikt om bepaalde programma’s te compilen en uit te voeren. Deze functie is al heel erg krachtig, maar voor JSON is er een nog snellere functie beschikbaar. De parse() method is specifiek bedoeld voor JSON en dient door de browser ondersteund te worden. Wanneer dit niet het geval is zal worden teruggevallen op de eval() method. .stringify() Stringify doet in weze het omgekeerde van de parse method. De stringify method interpreteert een JavaScript object en vertaalt dit naar een string. Deze string kan vervolgens ergens worden opgeslagen, om op een later moment door de parse() method weer uitgelezen te kunnen worden. var object = { firstName : "Peter", lastName : "Polman", age : 25 } var objectStr = JSON.stringify(object); //Vervolgens kan de string ergens worden opgeslagen. var JSONObj = JSON.parse(objectStr); //Nadat de string weer geparsed is kan deze weer als object gebruikt worden binnen het script.
The Document Object Model Het Document Object Model is een Application Programming Interface (API). Het zorgt voor de structurele interpretatie en weergave van documenten en biedt mogelijkheid tot interactie. Deze structuur wordt de document tree genoemd en browsers kunnen deze informatie parsen om de uiteindelijke visuele weergave te produceren. Het DOM Level wordt gehanteerd om een verzameling aan specificaties van DOM objecten, methods en behaviours te beschrijven. Met een nieuw DOM level kunnen volledig nieuwe specificatie categorieën toegevoegd worden en daarnaast kunnen veranderingen enkel toevoegen of aanpassingen op bestaande specificaties zijn.
Legacy DOM Het ontstaan van het DOM (DOM Level 0) is sterk gekoppeld aan het ontstaan van JavaScript en JScript. Op dit moment ontstond er een sterke behoefte aan het direct kunnen aanspreken van specifieke elementen binnen een document. Iets waar toentertijd nog geen onafhankelijke standaard voor was.
Intermediate DOM Toen in 1997 Dynamic HTML werd ondersteund door de browsers van Netscape en Microsoft, werden er vanuit beide partijen verschillende uitbreidingen gedaan op de Legacy DOM. We spreken in deze periode van Intermediate DOM. Nog steeds waren deze uitbreidingen browser afhankelijk en na het uitbrengen van de standaard ECMAScript, ging het W3C zicht dan ook bezig houden met het opstellen van een standaard voor de interpretatie van deze scripts.
DOM Level 1 In 1998 bracht het W3C DOM Level 1 uit. De DOM API is platform en taal onafhankelijk en browsers dienden gebruik te maken van deze API om op die manier de interpretatie van het script op verschillende browsers te kunnen bewerkstelligen.
DOM Level 2 Eind 2000 werd level 2 geïntroduceerd. De getElementById functie werd toegevoegd om op een meer toegankelijke manier elementen aan te kunnen spreken. Evenals
het event model om interactie met de gebruiker naar een volgend niveau te kunnen brengen. Ook CSS werd vanaf dit level ondersteund door het DOM.
DOM Level 3 In 2004 werd level 3 geïntroduceerd. Hiermee werd onder andere ondersteuning voor xPath toegevoegd, maar ook een interface om het serializen van XML bestanden mogelijk te maken. Dat wil zeggen dat XML bestanden niet alleen ingeladen, maar ook opgeslagen kunnen worden.
DOM Level 4 Aan level 4 wordt op dit moment gewerkt.
The Browser Object Model Het Browser Object Model stelt JavaScript in staat om met de browser te communiceren. Aangezien moderne browsers vergelijkbare JavaScript methods en properties hebben geïmplementeerd, worden deze gezien als de methods en properties van de BOM. Browser vendors zijn echter vrij in de wijze waarop het BOM wordt geïmplementeerd, in tegenstelling toto het door W3C gestandaardiseerde DOM. Het window object wordt door alle browsers ondersteund en heeft als belangrijkste property het HTML Document Object Model. Alle andere global objects, functies en variables worden gezien als members van de BOM. In principe hoeft het window object niet aangeroepen te worden en dat maakt dat de daarop volgende statements vergelijkbaar zijn. window.document.getElementById(“element”).writeIn(“blabla”); doet precies hetzelfde als: document.getElementById(“element”).writeIn(“blabla”); Aangaande bovenstaande tabel zien we dat er naast het DOM nog een aantal andere objecten beschikbaar zijn. Hier volgt een korte beschrijving en mogelijke toepassing van de overige objecten binnen het BOM. Door de objecten te loggen kun je een hoop informatie met betrekking tot de inhoud van deze objecten achterhalen.
Document window.document bevat onder andere het HTML DOM. In het volgende hoofdstuk wordt de historie en structuur verder behandeld.
Frames Bij het loggen van het window.frames object wordt het window object getoond. Aangezien frames inmiddels deprecated zijn wegens slecht functioneren op het moment dat bezoekers op de pagina kwamen via een zoekmachine (deze frame
documents werden los van elkaar geïndexeerd). Ook ontstonden er moeilijkheden op het moment dat pagina’s gebookmarked of geprint werden.
History window.history geeft toegang tot de history van de browser. Met de methods .back(), .forward() en .go() kun je hierbinnen navigeren. De .go() method dient vergezeld te worden van een parameter, zie het volgende voorbeeld: window.history.go(-2); Bovenstaand statement stuurt de bezoeker naar twee pagina’s terug in de browser geschiedenis.
Location window.location geeft informatie met betrekking tot je locatie binnen het web. Je kunt bijvoorbeeld de URL in je adresbalk opvragen met behulp van window.location.href. Daarnaast kun je het protocol checken, het eventuele port number en tot slot kun je deze informatie manipuleren met de .replace() method. var var var var var
var hrefOriginal = window.location.href; window.location.replace(href); //laadt de pagina met deze URL Buiten het bovenstaande kent dit object nog een aantal interessante properties. Zo geeft window.location.referrer je de URL van de voorgaande locatie van de bezoeker. Dit werkt echter alleen als de bezoeker via een link bij het document is gekomen. Wanneer de URL direct in de adresbalk wordt ingevoerd werkt dit niet. Dit kan ook voorkomen worden door de privacy settings van de browser op te voeren.
Navigator window.navigator geeft je informatie met betrekking tot het platform waarop de browser draait. Vendor, useragent en version properties zijn hiermee bijvoorbeeld op te vragen. Ook de taalinstellingen kunnen van belang zijn. Op deze wijze kun je, aangaande de standaard instellingen van de bezoeker, achterhalen in welke taal hij
of zij de software het liefst voorgeschoteld krijgt. Achter de tweeletter code betreffende de taalinstelling staat nog een tweeletter landcode. var lang = window.navigator.language; //en-US
Screen window.screen geeft je informatie over het scherm waarop de browser wordt gedraaid. Zo kunnen we de pixelDepth, height en width opvragen om bijvoorbeeld de uiteindelijke weergave van het document te beïnvloeden.
jQuery Bestaansrecht
In januari 2006 werd de cross-platform JavaScript library jQuery gelanceerd. Het doel was om met behulp van deze library het client-side scripting te vereenvoudigen. Tegenwoordig gebruikt zo’n 80% van de 10000 meest bezochte websites de library en is daarmee de meest populaire JavaScript library. jQuery heeft zijn voor en nadelen ten opzichte van pure JavaScript. Deze zal ik hieronder uiteen zetten: Gebruiksvriendelijk De in 2006 gedefinieerde doelstelling duidt ook het grootste voordeel van jQuery. De vereenvoudigde JavaScript syntax en enorme hoeveelheid voor gedefinieerde functies stellen de gebruiker in staat om met veel minder regels code een vergelijkbaar resultaat te bewerkstelligen. SEO Waar Flash tegenwoordig bijvoorbeeld op mobile Apple devices niet meer wordt ondersteund is jQuery daar een waardige vervanger voor geworden. Bijkomend voordeel is dat, met het gebruik van jQuery, de gemanipuleerde HTML in het DOM ook door zoekmachines geïndexeerd kan worden. Dit komt de pagerank van de pagina ten goede en zal de pagina hoger in de zoekmachine resultaten doen laten eindigen. Sterke open-source community Een grote en krachtige open-source community zorgt voor een constante optimalisatie van de library en bestaande plugins. Dit zorgt ervoor dat security en performance issues tijdig getackeld worden op het moment dat deze aan het licht komen. Veel documentatie en tutorials Doordat jQuery inmiddels al een tijdje meegaat en het een sterke online community heeft ontwikkeld is de documentatie uiterst verzorgd en zijn er legio tutorials beschikbaar.
jQuery Syntax De basis jQuery syntax luidt als volgt:
$(selector).action() $ definieert het jQuery object. De (selector) zoekt het betreffende HTML element en .action() definieert de actie die verricht wordt op het HTML element. De $ refereert net als de variable jQuery naar het jQuery object. De syntax zou dus ook als volgt geschreven kunnen worden: jQuery(element).action() We zouden dus het volgende kunnen stellen: window.jQuery = window.$ = jQuery; console.log($); Als we dit object loggen dan blijkt dat dit object de volgende functie terug te geven: function (a,b){ return new m.fn.init(a,b) } Als het jQuery object wordt aangeroepen wordt het bovenstaande dus uitgevoerd. Hieruit kunnen we opmaken dat er twee parameters (a,b) meegegeven dienen te worden. Dit zijn respectievelijk de selector voor het element waarop de gewenste actie toegepast dient te worden en de functienaam om de juiste method binnen het jQuery object te initiëren.
jQuery Plugin Een jQuery plugin, ofwel een uitbreiding op de standaard jQuery library, definieer je als volgt: (function( $ ){ $.fn.myfunction = function(options) { console.log(); return this; }; })( jQuery ); Het statement op de eerste regel, inclusief de closing tag, wordt gebruikt om deze uitbreiding op het $ object enkel voor jQuery libraries te laten gelden.
Reflectie Gedurende het schrijven van deze verdieping had ik herhaaldelijk het gevoel dat ik mijn tijd aan het verdoen was door zo’n beetje alle W3C JavaScript documentatie te herschrijven. Het doel van deze verdieping was echter om de hiaten in mijn kennis te vullen en waar nodig naar een standaard te trekken en reflecterend moet ik concluderen dat dat zeker gelukt is. Waar ik in het begin alle language elements van JavaScript heb aangestipt, heb ik hier misschien niet bijster veel nieuws geleerd. Maar dit heeft er wel voor gezorgd dat ik de standaard gebruikswijze van deze objecten in mijn hoofd heb zitten en betere manieren van toepassing kan gaan gebruiken. Zo zal ik met de kennis van vandaag eerder aanspraak maken op een for in loopje ten opzichte van een for met een gammele if constructie daar in. In PHP kende ik de foreach functie wel en ik wist dat jquery een each() method heeft. Maar de JavaScript equivalent is mij niet eerder voorbij gekomen. Een erg handige toevoeging dus! Wat het BOM en DOM zijn kon ik eerder wel duiden op het moment dat de begrippen in een context stonden. Nu kan ik het echter ook helder uitleggen en dit zorgde er voor dat ik alle API’s ook ineens een plek kon geven in de hiërarchie van het systeem. Ik vond het verrassend om te zien dat ik via het location object heel eenvoudig de referrer van de bezoekers in kaart kon brengen. In hoeverre je gedetailleerde informatie kan achterhalen viel uiteindeijk (gelukkig) nog wel tegen. Het bleek dat zoekmachines vaak al veel informatie uit de url strippen, zodat jouw zoekwoorden en dergelijke niet direct gemeenschappelijk goed worden op het moment dat je een “kwaadwillende” website zal bezoeken. Ik ben naast deze verdieping ook een beetje in object georiënteerd PHP gedoken en heb via die weg al wat theorie tot me genomen met betrekking tot het “object”. Het begrip kwam binnen JavaScript dus niet uit het niets vallen, maar juist daardoor kon ik de praktische toepassing hiervan een stuk makkelijker vatten. De wijze waarop je een metafoor voor de wereld om je heen kon gebruiken om de materie beter te begrijpen deed me realiseren dat deze denkwijze er reeds in zat, maar ik het nog niet aan deze vorm van kennis had gekoppeld. In principe is dit onderwerp natuurlijk louter aangetikt in deze verdieping, maar ik kijk uit naar wat meer verdieping rondom dit onderwerp! Mijn motivatie is in ieder geval weer op pijl.