30.4.2015 Aulikki Hyrskykari Antti Sand
o Edellinen luento Oliot Built-in oliot ja for in o Tällä kertaa: JavaScript HTML ja DOM Tapahtumat ja tapahtumankäsittelijät HTML5 Canvas JavaScript-kirjastoista
o DOM on standardoitu keino päästä käsittelemään ohjelmallisesti HTML-dokumentin osiin ja ominaisuuksiin o Se välittää HTML-elementit JavaScriptiin olioina olioita (ts. sivun elementtejä) voi siten käsitellä JavaScriptillä voidaan muokata HTML-elementtien ominaisuuksia JavaScriptin kautta käyttöön olioille (ts. sivun elementeille) määriteltyjä tapahtumia ja metodeja o Toisin sanoen, DOM standardoi sen, miten HTML-dokumentin (www-sivun) elementtejä voi ohjelmallisesti muokata, luoda ja poistaa
<!DOCTYPE html> <html> <head> <title>simple HTML document</title> </head> <body> <h1> Esimerkkisivu </h1> <p id = esittely > Tämä dokumentti sisältää otsikon ja kaksi kappaletta. </p> <p> Tämä on <em>toinen</em> kappale ja tässä on sisältönä paitsi tekstiä ja kuva <a href="http://www.visittampere.fi/">tampereelta</a> <br /> <img src = "img/nasinneula.png" alt="näsinneula" /> </p> </body> </html> o Selain muodostaa sivusta DOM-puun joka koostuu solmujen hierarkiasta
document html head body title h1 p p #text #text id #text #text em #text a br img #text href #text src alt
o DOM puun solmu olioilla on kolme yhteistä ominaisuutta o nodetype, solmun tyyppi (kokonaisluku 1 12), esim. 1=elementtisolmu, 2=attribuuttisolmu, 3=tekstisolmu, 9=kommenttisolmu ja 10=dokumenttisolmu o nodename, solmun nimi merkkijonona DOM spesifikaatiossa kaikille elementeille annettu vakionimet kapitaalikirjaimin kirjoitettuna, esimerkiksi <p> elementille: nodename == "P" o nodevalue, solmun arvo, esim. tekstisolmujen (nodetype=3) arvo on teksti itse attribuuttisolmun (nodetype=2) arvo on attribuutin arvo elementtisolmun (nodetype=1) arvo on null o Kullakin solmutyypillä muitakin ominaisuuksia ja metodeja
o Elementtisolmun (nodetype=2) style-ominaisuuden kautta pääsee käsiksi solmun css-piirteisiin var kappale= document.getelementbyid("esittely"); kappale.style.color="red"; o Solmun style-ominaisuuden (edelleen olio) ominaisuudet vastaavat CSS-piirteitä, mutta nimeämiskäytäntö JavaScript-tyyppisesti camelcase, esim. CSS DOM o border-color bordercolor o background-image backgroundimage o color color ks. esim. http://www.w3schools.com/jsref/dom_obj_style.asp esimerkki: http://www.sis.uta.fi/~jwt/14/esim/06-01-html-dom.html
o Aiemmin oli esillä getelementbyid(tunnus), jolla noudettiin sivulta elementti, jolla oli määrätty tunnus o Toinen tapa on käyttää html elementtinimeä (nodename) getelementsbytagname ( nodename") o Funktio palauttaa listan solmu olioita palautetun listan oliotyyppi on HTMLCollection viittaus listan yksittäisiin solmuihin indeksoinnilla [0], [1], var kappaleet = document.getelementsbytagname("p"); kappaleet[0].textcontent = "Ensimmäisen kappaleen uusi teksti"; kappaleet[1].textcontent = "Muutetaan toinen kappale"; o Listan pituus (solmujen lukumäärä)? tallennettu solmulistan ominaisuuteen length solmulistan solmut ensimmäinen ja viimeinen alkio solmut[0] solmut[elem.length 1] http://www.sis.uta.fi/~jwt/14/esim/06-02-html-dom-getelementsbytagname.html
kappale.nextelementsibling.childnodes[1] o Kun on olemassa viittaus johonkin DOM puun elementeistä, pääsee sen kautta kiinni mihin tahansa sivun muista elementeistä. o Kaikilla solmuilla on seuraavat ominaisuudet: childnodes, lapsisolmujen lista firstchild, ensimmäinen solmu lapsisolmujen listassa =childnodes(element)[0] lastchild, viimeinen solmu lapsisolmujen listassa =childnodes(element)[listanpituus 1] nextsibling, seuraava sisarussolmu nextelementsibling, seuraava sisarus, jonka nodetype==1 previoussibling (previouselementsibling), edellinen sisarussolmu parentnode, solmun äiti var solmu = document.getelementbyid("esittely"); alert(solmu.nextelementsibling.firstchild.nodevalue); o Tuottaisi valintaikkunaan tekstin: "Tämä on" (ed. esimerkin Tampere-sivulla)
o Edellä skriptipalat suoritettu dokumentin latautuessa selaimeen, ts. ne oli kirjoitettu sivulle ns. inline skripteinä o Tyypillisempi tapa tapahtumat ja tapahtumankäsittelijät (events, event handlers) toisin sanoen tietty tapahtuma saa aikaan siihen liitetyn skriptin suorituksen - esim. sivun latautuminen, hiiren napsaututus tai kaksoisnapsautus, lomakkeen lähettäminen, näppäimen painaminen jne.
o Tapahtumankäsittelijä koodipala (yleensä funktio) jonka tapahtuma laukaisee o Tapahtumankäsittelijä voidaan määritellä HTML-elementin attribuutiksi o Attribuutin nimi on tyyppillisesti muodoltaan "onxxx" jossa XXX on tapahtuman nimi esimerkiksi <img href="kuvan osoite" onclick="kasittelyfunktio(parametrit)">
event-attribuutti attribuuttiin liitetyn funktion kutsun saa aikaan onchange tekstikentän, -alueen tai pudotusvalikon sisällön muutos onclick napsautus elementin päällä ondblclick kaksoisnapsautus elementin päällä onmousedown hiiren painikkeen painallus elementin päällä onload sivun tai kuvan latauksen valmistuminen onsubmit lomakkeen lähetys onreset lomake palauttaminen alkuarvoonsa onunload dokumentin sulkeminen onresize elementin koon muutos täydellinen lista, ks esim. http://www.w3schools.com/tags/ref_eventattributes.asp
<!DOCTYPE HTML> <html> <head> <meta charset="utf 8"> <title>mousedown/up-esimerkki</title> </head> <body> <p id="p1" onmousedown="kasittelemdown()" onmouseup="kasittelemup()"> text belonging to paragraph </p> </body> </html> <script> function kasittelemdown(){ document.getelementbyid("p1").style.color="red"; } function kasittelemup(){ document.getelementbyid("p1").style.color="green"; } </script> esimerkki: http://www.sis.uta.fi/~jwt/14/esim/06-04-mousedownupevent.html
o Tapahtuma luo aina event-olion olio sisältää tapahtumaan liittyvää tietoa tällaisia ovat mm. seuraavat olion ominaisuudet clientx clienty offset * offset * button hiiren x-koordinaatti (ikkunassa) hiiren y-koordinaatti (ikkunassa) hiiren x-koordinaatti suhteessa tapahtuman laukaisseen elementin vasempaan reunaan hiiren y-koordinaatti suhteessa tapahtuman laukaisseen elementin yläreunaan liittyykö tapahtumaan hiiren painikkeen (ja minkä niistä 1=vasen, 2=oikea, 3=keski) painallus keycode näppäimistön näppäimen koodi o täydellinen luettelo esim. täällä: https://developer.mozilla.org/en-us/docs/web/api/event#dom_event_subclasses * Puuttuvat Firefoxin event-olio mallista
<!DOCTYPE HTML> <html> <head>... </head> <body> <p id= "status">status</p> <div id = "alue" onmousemove = "handlemousemove(event)" ></div> Event olio välitetään funktiolle <script> var statusrivi = document.getelementbyid("status ); function handlemousemove(e) { statusrivi.textcontent = "client(x,y): (" + e.clientx + ", " + e.clienty + ") " + "offset(x,y): ( + e.offsetx + ", " + e.offsety + ")"; } </script> </body> </html> JWT 2015 @Aulikki Hyrskykari, Antti Sand, SIS, esimerkki: UTA http://www.sis.uta.fi/~jwt/14/esim/06-05-event-olion-valittama-tieto-coordxjay.html
<!DOCTYPE HTML> <html> <head>... </head> <body> <p id= status">viesti</p> <p onmousedown="whichbutton(event)"> Tapahtumaan liittyvään tietoa voidaan välittää event-oliolla... </p> <script> var viestirivi = document.getelementbyid( status"); function whichbutton(e) { var msg = "button: "; switch (e.button) { case 0: msg += "left"; break; case 1: msg += "middle"; break; case 2: msg += "right"; break; } viestirivi.textcontent = msg; } </script> Event olio välitetään funktiolle </body> </html> http://www.sis.uta.fi/~jwt/14/esim//06-05-b-event-olion-valittama-tieto-mousedown.html
o DOM-olioille voi asettaa kuuntelijafunktion (event listener) o Kuuntelijan asetus tapahtuu metodilla addeventlistener() o Metodille voi antaa kaksi parametria tapahtuman nimi (event name) ja kuuntelijafunktio, joka suoritetaan tapahtuman aktivoiduttua object.addeventlistener( tapahtumannimi", callbackfnimi); o Olio huolehtii tapahtuman havaitsemisesta tapahtumaa ei siis liitetä HTML-dokumenttiin tapahtumien nimet esim. täältä https://developer.mozilla.org/en-us/docs/web/reference/events o Ohjelmoija (sinä) kirjoitat kuuntelijafunktion (callback) joka suoritetaan, kun tapahtuma aktivoituu o Jos kuuntelijan asetetaan window-oliolle, tapahtuma ikkunassa saa aikaan kuuntelijafunktion kutsumisen
o var x = document.getelementbyid("mybtn"); if (x.addeventlistener) { // For all major browsers, except IE 8 and earlier x.addeventlistener("click", myfunction); } else if (x.attachevent) { // For IE 8 and earlier versions x.attachevent("onclick", myfunction); }
keydown- ja keyup-tapahtumia kuunnellaan koko ikkunassa tuottavat tekstiä sivulle <p>-elementin sisällöksi... <body> <p id= status">status</p> script> window.addeventlistener("keydown", reportkeycode); window.addeventlistener("keyup", reportkeyup); function reportkeycode(e) { statusrivi.textcontent += e.keycode + " "; } function reportkeyup() { statusrivi.textcontent += "UP "; } </script> </body> </html> http://www.sis.uta.fi/~jwt/14/esim/06-06-addeventlistenerforkeycodes.html keydown-tapahtumaa kutsutaan niin kauan kun näppäin pohjassa kutsun taajutta ei pääse kontrolloimaan tehdään sama window-ikkunan JWT 2015 setinterval-metodin @Aulikki Hyrskykari, Antti Sand, SIS, UTAavulla
luodaan tyhjä olio keysdown - keydown-listener luo oliolle ominaisuuden, jonka nimi on painetun näppäimen koodi jakeyup-listener poistaa ominaisuuden setinterval-metodin avulla kutsutaan funktiota update, joka keysdownolion avulla tietää mitä näppäintä on painettu <body> <p id= status">status</p> script> var keysdown = {}; window.addeventlistener("keydown", keyflagon); window.addeventlistener("keyup", clearkeyflag); window.setinterval(update,10); function keyflagon(e) { keysdown[e.keycode] = true;}; function clearkeyflag(e) { delete keysdown[e.keycode];}; function update() { // tätä funktiota kutsutaan 10 ms välein, täällä voidaan toistuvasti // esim. trkastaa mitä näppäimistön näppäimiä on painettu // ja regoida siihen kulloinkin tarkoituksenmukaisella tavalla } </script> </body> </html> esimerkki: http://www.sis.uta.fi/~jwt/14/06-07-siirrakuvaanuolinappaimilla.html
key keycode home-näppäin 36 nuoli vasemmalle 37 nuoli ylös 38 nuoli oikealle 39 nuoli alas 40 insert-näppäin 45 delete-näppäin 46 o verkosta löytyy täydellisempiä listoja, esim http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
o document-olion metodeja: createelement(elementname) createtextnode(text) appendchild(newchild) removechild(node) o Esimerkki: lisätään listaan uusi alkio: var list = document.getelementbyid("list1") var newitem = document.createelement("li") var newtext = document.createtextnode(text) list.appendchild(newitem) newitem.appendchild(newtext)
Canvas elementti on rajattu alue, taustakangas se voidaan asemoida sivulle haluttuun kohtaan siihen voi tuoda kuvan, tai siihen voi piirtää ohjelmallisesti elementille määritellään konteksti-olio (graphics context) - konteksti säilyttää piirtämiseen liittyvät ominaisuudet (esim. kynän sijainti, koko, väri, jne.) <body> <canvas id="mycanvas" width="640" height="480"></canvas> <script> var cv = document.getelementbyid('mycanvas'); var context = cv.getcontext('2d');... </script>
o Kutsutaan getcontext() metodia parametrilla 2d o 3d parameteria ei ole, 3-ulotteisia kuvia piirretään webgl:ää käyttäen - getcontext( WebGL ) o http://www.w3schools.com/tags/ref_canvas.asp <body> <canvas id="mycanvas" width="640" height="480"></canvas> <script> var cv = document.getelementbyid('mycanvas'); var context = cv.getcontext('2d'); context.linewidth = "3"; context.strokestyle = "green"; context.beginpath(); // aloitetaan uusi piirtoviiva context.moveto(100, 150); // viivan alkukohta context.lineto(450, 50); // viivan loppukohta context.stroke(); // piirretään viiva... </script>
o Canvas elementille annetaan luotaessa koko <canvas id="mycanvas" width="640" height="480"></canvas> o Jos koko jätetään antamatta, oletus on 300 x 150 o Huom: CSS sääntöjen avulla voi muuttaa canvasin kokoa ikkunassa, mutta se ei muuta piirtoalueen dimensioita
o Ontto suorakaide ctx.linewidth = 7; ctx.strokestyle = 'black'; ctx.rect(300,300, 30, 30); // x,y,leveys,korkeus ctx.stroke(); o Täytetty suorakaide ctx.fillstyle = "#CC0000"; ctx.fillrect(300,300,30,30); o Kaari (osa ympyrää) ctx.beginpath(); ctx.arc(200,300,40,0,2*math.pi); // x,y, radius, start angle, end angle ctx.fill(); ontto ympyrä: ctx.stroke() 360 o = 2 * PI radians
o Vaikka elementteihin pääsee DOM puun kautta käsiksi, se ei ole aivan ongelmatonta o DOM puuhun tallennetaan muutakin kuin vain esitellyt elementit sivun sisältöä (tekstit, kuvat, jne.) käsittellään eri selaimissa eri tavoin rakentaessaan DOM puuta selaimet tulkitsevat tyhjätilamerkit eri tavoin jotkut selaimet ohittavat ne, toiset tekevät niistä oman DOM solmunsa. o Selainten tulkinta DOM puun rakentamisesta toivottavasti tarkentuu ajan myötä toistaiseksi turvallisen JavaScript koodin kirjoittaminen vaatii aikaa tarkastaa miten pääselaimet joissain erikoistilanteissa rakentavat oman DOM puunsa o Viittaaminen sivun kohteisiin vaikuttaa monimutkaiselta kun otetaan huomioon, että CSS:ään on jo toteutettu selkeät ja yksikäsitteiset valitsimet. o Ratkaisuna näihin ongelmiin: o JavaScript kirjastot jos käytämme Javasciptiä jonkun yleisesti hyvälaatuiseksi todetun javascript kirjaston kautta, nämä perustason ongelmat on niissä valmiiksi ratkaistu
o jquery dokumentit: http://jquery.com/ tutoriaali esim: http://www.w3schools.com/jquery/default.asp o Jotta jquery funktioita voi käyttää kirjasto tulee tuoda omaan ohjelmaan (kuten mikä tahansa muukin JavaScript funktiotiedosto) funktiokirjaston kopioida itselleen jqueryn kotisivuilta (http://jquery.com/) mutta kirjaston voi kuitenkin tuoda myös suoraan muutamasta paikasta: http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js http://ajax.microsoft.com/ajax/jquery/jquery 1.4.2.min.js siis esim: <script type="text/javascript src="http://ajax.microsoft.com/ajax/jquery/jquery 1.4.2.min.js"> </script>
o jquery on räätälöity helpottamaan HTML elementtien valintaa ja niiden käsittelyä syntaksi: $(selector).action() $ = lyhenne sanalle jquery kertoo, että skripti löytyy jquery kirjastosta (selector) kysely (tai etsi)" HTML elementti action() toiminta, joka näille elementeille suoritetaan o Esimerkki: elementin piilota tämä o Esimerkki: piilota / näytä elementti, jonka id = #panel, silloin kun napsautetaan elementtiä, jonka id = #flip <script> $(document).ready(function(){ $("p").click(function(){ $(this).hide(); }); }); </script> <script> $(document).ready(function(){ $("#flip").click(function(){ $("#panel").slidetoggle("slow"); }); }); </script> slide/toggle: http://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_slide_toggle animate: http://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_animation