Javascript ja DOM

Harjoitellaan Javascriptin ja DOM-rajapinnan perusteita.

Mallivastaus (malli.zip)

Alkuvalmistelut

Hello World

  1. Tallenna käyttöösi valmis dokumenttipohja johonkin väliaikaishakemistoon.
  2. Avaa paketti W:\web-sovellukset-hakemiston alihakemistoon ohjaus2.
  3. Luo haluamallasi editorilla nanonano.js-tiedosto samaan kansioon tallentamasi dokumenttipohjan kanssa.
  4. Avaa editoriin ja Firefox-selaimeen Nanonanon kotisivu index.html.
  5. Liitä nanonano.js XHTML-dokumenttin head-osaan script-elementillä.
  6. Kirjoita nanonano.js-tiedostoon ensin yksinkertaisin mahdollinen Javascript-ohjelma:
    alert("Hello world");
    
  7. Lataa sivu uudelleen selaimessa. Jos kaikki meni ok niin näytölle pitäisi ilmestyä dialogi jossa lukee Hello world.
  8. Dialogi ilmestyy jo ennen sivun sisältöä joten korjataan ohjelmaa sen verran, että sivu ilmestyy ensin ja vasta sitten dialogi. Siirrä alert-funktiokutsu ikkunan onload-tapahtumankäsittelijäfunktioon.
    "use strict"; // estää pahimpia virheitä
    
    window.onload = function() {
      alert("Hello world");
    };
    
  9. Kokeile ladata sivu uudelleen (reload). Nyt dialogi ilmestyy vasta dokumentin latauduttua.
  10. Kommentoi (// tai /* */) alert-komento pois ennen seuraavia tehtäviä.

Elementtien saanti ja arvojen muuttaminen

Haetaan elementtien sisältä tekstejä ja muutetaan niitä.

Otsikoiden numerointi

  1. Lisää uusi funktio numeroi ja kutsu tätä window.onload-tapahtuman käsittelijäfunktiossa.
  2. Hae numeroi-funktiossa kaikki h2-elementit sopivan nimiseen muuttujaan. Tämä onnistuu getElementsByTagName-metodilla.
  3. Käy for-silmukassa läpi listassa olevat h2-elementit. Listan alkioiden määrän saa length-metodilla.
  4. Haetaan h2-elementtien tekstit
    • Yksittäisen h2-elementin saa item-metodilla tai []-operaattorilla.
    • Kunkin elementin sisällä oleva teksti muodostaa vielä oman TextNode-tyypin olionsa.
    • Tämän saat firstChild-attribuutista.
    • Varsinaisen tekstin (String-tyyppiä) saa nodeValue-attribuutista.
    • Kokeile miten textContent-ominaisuus toimii. Sillä saat suoraan jonkun elementin tekstisisällön eikä tarvitse välittää erillisistä TextNodeista
  5. Aluksi tekstin voi laittaa menemään Firebugin konsoliin console.log-metodilla ja testata tuleeko sinne tekstiä. Arvoja voi myös tutkia Firebugin debuggerilla.

    Breakpointien ja watchien käyttöä Firebugilla.

    • Valitse Script-välilehti, napauta rivinumeroa ja lataa sivu uudelleen.
    • Koodin suoritus pysähtyy breakpointiin. Maalaa haluamasi lauseke ja valitse oikealla Add Watch.
    • Osoittamalla muuttujia saat myös näkyviin niiden arvot.
    • Kun suoritus on pysähtynyt voit testata sen hetkisiä arvoja kirjoittamalla lausekkeen Console-välilehteen.
  6. nodeValue-attribuuttiin voi myös asettaa arvoja. Lisää nykyisen arvon eteen vielä for-silmukassa käytetyn indeksin arvo. Kokeile. Numerointi ei vielä mene oikein, joten lisää kierrosnumeroon vielä yksi.

Menu

Avautuva menu

Tehdään yksinkertaisempi versio luennolla esitetystä menusta, jossa alakohtia voidaan piilottaa.

  1. Luo dokumentin alkuun XHTML:ää kirjoittamalla kaksitasoinen sisäkkäinen lista, jossa on pääkohdat Artikkelit, Harkat ja Linkit ja näiden alle pari listakohtaa, joiden sisällä on linkit. Lisää näiden listakohtien eteen img-elementillä minus.jpg-kuva merkitsemään avattua menukohtaa.
  2. Merkitse ulompi lista id-attribuutilla. Muotoile CSS:llä listan ulkoasu ja liu'uta se oikeaan laitaan.
  3. Luo nanonano.js-tiedostoon uusi funktio muuta_nakyvyys ja aseta ensimmäisen parametrin nimeksi event.
  4. Hae window.onload-tapahtumankäsittelijässä edellä määrittelemälläsi id:llä varustettu ul-elementti johonkin muuttujaan (getElementById).
  5. Pyydä kaikkia tämän ul-elementin alla olevia img-elementtejä getElementsByTagName-metodilla.
  6. Käy for-silmukalla img-elementtilista läpi ja lisää kunkin elementin click-tapahtuman käsittelijäksi funktio muuta_nakyvyys. kts.tapahtumat
    elementti.addEventListener("click", muuta_nakyvyys);
  7. Selvitä muuta_nakyvyys-funktion alussa mikä elementti on aiheuttanut tapahtuman. Tämä selviää muuta_nakyvyys-funktiolle parametrina tulevan event-olion target-attribuutista. Voit esim. kokeilla mitä tekee console.log(event.target.nodeName) tai katsoa Firebugin debuggerilla mitä event-parametri pitää sisällään.
  8. Muuta kuvan (event.target) src-attribuutin arvoksi plus.jpg. Kts. setAttribute. Kokeile selaimella. Lisää logiikkaa ja aseta src-attribuutiksi plus.jpg jos ennen oli minus.jpg, muutoin toisinpäin. Muuta myös alt-attribuutin ominaisuutta tekstiksi Auki/Kiinni tilan mukaan. Testaa toimintaa.
  9. Tutki Firebugilla millainen puu sisäkkäisestä listasta muodostuu. Tämä näkyy Firebugin HTML-välilehdellä.

    HTML inspector firebugissa

  10. Selvitä, miten pääset käsiksi tapahtuman aiheuttaneen img-elementin seuraavaan (sibling) ul-elementtiin. Tapoja on monia, voit joutua käyttämään esim. joitain seuraavista attribuuteista/metodeista: parentNode, childNodes, nextSibling, nodeName ja getElementsByTagName (kts. elementtien saanti).
  11. Piilota sisempi ul-elementti samalla kun asetat src-attribuutin arvoksi plus.jpg, muutoin näytä elementti.
    • Elementin näkyvyyttä voi muuttaa esimerkiksi className-attribuuttia muokkaamalla.
    • Lisää CSS-tiedostoon luokka, jossa on ominaisuus display: none;.
    • Elementin saa näkyväksi poistamalla class-attribuutin. Tämä onnistuu removeAttribute-metodilla.

Elementtien lisäys

Lisätään elementtejä sivulle dynaamisesti DOM-rajapinnan avulla.

Linkit tekstiksi linkkilistaan

Linkit tekstiksi a-elementin jälkeen

  1. Luo uusi funktio linkit ja kutsu sitä window.onload-käsittelijäfunktiossa.
  2. Merkitse id-ominaisuudella dokumentin lopussa oleva ul-elementti.
  3. Hae linkit-funktiossa id:llä varustettu ul johonkin muuttujaan.
  4. Pyydä kaikkia tämän elementin alla olevia a-elementtejä getElementsByTagName-metodilla.
  5. Tee for-silmukka ja hae kunkin a-elementin http-osoite href-ominaisuudesta ja tulosta se Firebugin konsoliin. Tämä onnistuu getAttribute-metodilla.
  6. Luo osoitteesta uusi tekstisolmu createTextNode-metodilla.
  7. Lisää se kyseisen a-elementin sisältävän li-elementin loppuun. Tarvitset parentNode-attribuuttia ja appendChild-metodia.
  8. Kokeile toimiiko skripti. Ulkoasua voi parantaa lisäämällä tekstin alkuun vielä yhden välilyönnin. Koodin uudelleenkäytettävyyttä voi vielä parantaa siten, että funktion parametriksi laitetaan id, tämä id haetaan dokumentista ja tämän jälkeläisinä olevat linkit "tekstitetään".

Yhteenlaskupeli

Rivejä joissa kaksinumeroisia lukuja ja tekstikenttä niiden summaa varten

Tehdään Nano nanon sivuille päässälaskun harjoitteluun pieni yhteenlaskutehtäviä generoiva peli.

  1. Lisää h2-otsikko ja sen alle div-lohko, jonka on id-ominaisuuden arvo on laskut. Lisää myös painike Tarkista, jolla on myös oma id-ominaisuuden arvonsa.
  2. Tee funktio luo_lasku, joka ottaa parametrinä rivin numeron ja palauttaa p-elementin, joka sisältää arvotun laskutehtävän tekstinä ja tekstilaatikon vastaukselle. Tuotettu elementti on muotoa:
    <p><span id="ekaluku_riviX">LUKU1</span> + <span id="tokaluku_riviX">LUKU2</span>
     = <input id="summa_riviX" type="text" size="3" /></p>
    • Elementin runko-osan saa luotua helposti DOMTool-työkalulla. Kopioi elementit HTML-osaan ja napauta Create DOM Statements. Kopioi DOM-koodi js-tiedostoosi. Palautettava elementti löytyy Nodes to Append -osasta.
    • Muuta id-attribuuttien asettamista siten, että X:n tilalle tulee parametrina annettu numero.
    • Arvo tekstien LUKU1 ja LUKU2 tilalle jotkin luvut väliltä 0-99. Tämä onnistuu Math.random-metodilla.
  3. Tee funktio luo_laskut, joka luo kymmenen laskua for-silmukassa ja lisää ne laskut-div-lohkon sisälle. Kutsu luo_lasku-funktiota silmukan kierrosluvun arvolla. Lisää luo_laskut-funktiokutsu window.onload-tapahtuman käsittelijään.
  4. Tee CSS-tiedostoon uusi luokka .virhe, jossa muuttaa elementin taustanvärin punaiseksi ja tekstinvärin mustaksi.
  5. Tee funktio tarkista_laskut. Lisää tämä funktio window.onload-tapahtuman käsittelijässä tarkista-napin click-tapahtuman käsittelijäksi.
  6. Käy tarkistuksessa kaikki rivit läpi for-silmukassa ja tarkista ovatko kaikki laskut oikein.
    • Summaa luvut yhteen ja vertaile onko luku sama kuin tekstilaatikossa.
      • Luvut sisältävät elementit saat document-olion getElementById-metodilla. Lisää id-arvojen runkojen ekaluku_rivi, tokaluku_rivi ja summa_rivi silmukan kierroksen numero.
      • Tekstin saa textContent- tai nodeValue-attribuutilla. Tekstilaatikosta arvon saa value-ominaisuudesta. Huom. ei html-koodin attribuutista vaan DOM-objektin value-ominaisuudesta.
      • Summausta varten luvut on muutettava integer-tyyppiseksi parseInt-funktiolla
    • Jos ei ole, niin laita tekstilaatikon class-attribuuttiin arvo virhe.
    • Jos rivi on kunnossa, niin poista class-attribuutti
    • Jos kaikki rivit ovat ok, niin ilmoita alert-funktiolla pelin läpipääsystä.
  7. Testaa "pelin" toimintaa.

Tapahtumat

Lisätään Javascriptillä elementteihin tapahtumia.

Tapahtumankäsittelijän lisääminen

  1. Luo johonkin kohtaan dokumenttia painike button-elementillä. Anna painikkeelle jokin id-arvo ja näkyvä teksti Hello world.
  2. Luo uusi funktio varoitus ja siirrä alert-kutsu sinne.
  3. Lisää onload-tapahtuman käsittelijään koodi, joka hakee napin väliaikaismuuttujaan. Tämä onnistuu document-olion getElementById-metodilla.
  4. Aseta painikkeelle click-tapahtuman käsittelijäksi funktio varoitus addEventListener-metodilla.
  5. Testaa napin toimintaa. Javascript-virheet näkee helposti Firebugin avulla selaimen oikeasta alakulmasta Error-tekstiä klikkaamalla:

    Firebug-laajennuksen virheikkuna

  6. Muuta ohjelman toimintaa siten, että Hello world ilmestyy vain tuplaklikkauksesta (kts. XHTML:n tapahtumat).

Jos aikaa jäi, niin kokeile vielä toteuttaa uuden pelin arpominen ja vastaamisen kuluneen ajan laskeminen pelin uudelleenaloituksesta hyväksyttyyn tarkistukseen.

Mallivastaus (malli.zip)

Lisätehtäviä

Voit harjoitella myös tekemällä Canasta-korttipelin pistelaskurin.

Käyttäjien kommentit

Kommentoi Lisää kommentti
Kurssimateriaalien käyttäminen kaupallisiin tarkoituksiin tai opetusmateriaalina ilman lupaa on ehdottomasti kielletty!
http://appro.mit.jyu.fi/web-sovellukset/ohjaus/ohjaus2/
© Tommi Lahtonen (tommi.j.lahtonen@jyu.fi) <http://hazor.iki.fi/>
2017-01-24 11:05:55
Informaatioteknologia - Jyväskylän yliopiston informaatioteknologian tiedekunta