Javascript ja DOM - Viikkotehtävä 2
Tässä tehtävässä opitaan Javascript-ohjelmointikieltä sekä XML/HTML-dokumentin käsittelyä DOM-rajapinnan avulla. DOM-rajapinnan käyttäminen pitää dokumentin rakenteen ehjänä ja sovelluksen siistinä.
Käy ensin läpi nämä luentomateriaalit:
Kaikille tasoille yhteiset vaatimukset:
- Käytetään vain Javascript-ohjelmointikieltä.
- Javascript-ohjelmassa on käytettävä Strict modea
// Whole-script strict mode syntax "use strict";
- Ohjelman pitää toimia myös ilman verkkoyhteyttä, ts. Javascriptillä ei saa kutsua mitään www-palvelimelta löytyviä palveluja.
- Ohjelma pitää pystyä suorittamaan useaan kertaan lataamatta sivua uudelleen.
- Ohjelma pitää toteuttaa pohjaksi annettuun HTML5-dokumenttiin. Pohjaksi annettuja HTML5-sivuja ei saa muokata muuten kuin ohjelmallisesti Javascript-ohjelmointikielellä. Vastauksen tasosta riippumatta tuloksena on 0 pistettä jos tätä kieltoa rikotaan.
- Kaikki funktiot jotka sallivat lisätä suoraan käsin kirjoitettua html-koodia sivun sisältöön ovat kiellettyjä. Vastauksen tasosta riippumatta tuloksena on 0 pistettä jos tätä kieltoa rikotaan. Esim. innerHTML, write tai writeln-funktioita ei saa käyttää.
- alert-funktion käyttäminen on kiellettyä
- Ulkoisten kirjastojen, kuten esim. jquery, angularjs, käyttäminen on kielletty.
- Ulkoasun muokkaukseen saa käyttää DOM-operaatioita. Saa käyttää myös omaan CSS-tiedostoon luotuja tyylejä mutta HTML5-tiedoston sisältöä saa muuttaa vain ohjelmallisesti.
- Valmiin ohjelman pitää toimia uusimmilla Firefox -selaimilla ja Googlen Chromella. Muista selaimista ei tarvitse toistaiseksi välittää.
- Koodin oleelliset osat on oltava kommentoitu.
- Dokumentin merkistönä on käytettävä UTF-8-merkistöä. Varmista, että skandinaaviset
merkit näkyvät oikein sekä Firefoxilla että Chromella. Jos eivät näy niin luo kansioosi .htaccess-tiedosto ja kirjoita sinne rivi:
AddCharset UTF-8 .html AddCharset UTF-8 .js AddCharset UTF-8 .css
- Taulukon solujen välissä on yleensä oletuksena vähän tyhjää tilaa. Sen saa poistettua seuraavasti:
table { border-spacing: 0px; }kts. myös border-collapse - Submit-painike lähettää aina oletuksena lomakkeen sisällön www-palvelimelle eli käytännössä sivu latautuu uudelleen. Tämä täytyy estää jotta ohjelma
toimisi järkevästi. Tapahtuu seuraavasti:
function klikkasittelija(e) { e.preventDefault(); } - HTMLElement.style
- Using dynamic styling information
- CSS Properties reference
- Setting charset information in .htaccess
Taso 1
- Kirjoita Javascript-ohjelma, joka luo sivulle halutun kokoisen tammilaudan eli mustavalkoisen ruudukon (html-taulukon) (x ruutua korkea ja x ruutua leveä).
- Taulukon joka toisen ruudun taustaväri on musta ja joka toisen valkoinen.

- Ohjelmalla voi luoda uuden ruudukon niin monta kertaa kuin haluaa. Uusi ruudukko korvaa jo mahdollisesti olemassa olevan ruudukon. Sivu ei saa latautua uudelleen uutta ruudukkoa luotaessa.
- Ruudukon minimikoko on 8x8 ja maksimikoko on 16x16. Ruudukkoa ei luoda jos kooksi annetaan epäkelpo arvo. Ruudukko on luotava tavalla, joka mahdollistaa helposti ja järkevästi paljon suurempienkin luomisen.
- Jos ruudukon kooksi annetaan epäkelpo arvo niin virheestä on ilmoitettava syöttökentän vieressä näytettävällä virheilmoituksella. Mahdollinen virheilmoitus on poistettava kelvollisen syötteen antamisen jälkeen. Ohjelma ei saa kaatua käyttäjän antamiin syötteisiin.
- Sijoita ruudukkoon nappulat mallikuvan esittämiin paikkoihin. Vrt. tammipelin nappulat. Sijoita nappuloita samaan tapaan ruudukon koon muuttuessa eli aina kolme riviä laudan laitoihin.
- Viimeistele ruudukon ulkoasu CSS:n avulla
- Valmis sivupohja
- Punainen pallo
- Sininen pallo
- Vinkki
Taso 3
Laajenna Taso 1 -ohjelmaa seuraavilla ominaisuuksilla ja muutoksilla:
- Käytä samaa sivupohjaa kuin edellisellä tasolla.


- Yhden ruudun leveys ja -korkeus on 50 pikseliä
- Luo ruudukkoon nappuloita lomakkeella valittu sarakemäärä. Sijoita nappulat samalla tavalla kuin mallikuvassa. Esim. jos valitaan lukumääräksi yksi (1) niin nappuloita luodaan vain reunimmaiseen sarakkeeseen. Käyttäjän valinnasta huolimatta on pelilaudalle jätettävä 2-3 keskimmäistä saraketta tyhjiksi. Esim. jos laudan koko on 8x8 niin nappuloita piirretään enintään kolmeen sarakkeeseen kummallekin laudan laidalle vaikka käyttäjä valitsisikin 4 tai 5. Jos käyttäjä valitsee liian suuren luvun niin tästä huomautetaan virheilmoituksella nappulavalinnan vieressä. Toteuta helposti laajennettavalla tavalla.
- Mahdollista nappuloiden liikutteleminen ruudukossa seuraavan algoritmin mukaisesti:
- Valitse hiirellä nappula
- Valittu nappula muuttaa värinsä vihreäksi
- Valitse hiirellä tyhjä ruutu johon haluat nappulan siirtää.
- Jos valitsetkin ruudun jossa jo on nappula niin tästä nappulasta tulee valittu nappula ja aiemmin valittuna ollut nappula palaa alkuperäisen väriseksi. Siirry kohtaan 2.
- Nappula siirtyy valittuun tyhjään ruutuun ja sen väri palaa alkuperäiseksi
Taso 5
Toteuta taso 3:n mukainen Javascript-ohjelma seuraavilla laajennuksilla:
- Toteuta täysin toimiva kahden henkilön pelattava Tammipeli. Käytä Tammen suomenkielisellä wikipediasivulla kerrottuja sääntöjä.
- Tarjoa oletuksena sääntösivulla kerrottua ruudukon kokoa ja nappuloiden määrää mutta salli käytettävän myös muita ruudukon kokoja (vrt. taso 3) ja nappuloiden määriä (vrt. taso 3)
- Luo ruudukko siten, että se osaa hyödyntää koko selainikkunan leveyden ja käytettävissä olevan korkeuden. Ruudukko on siis niin suuri kuin ikkunaan mahtuu ilman scrollbareja. Yksittäisten ruutujen koko siis skaalautuu. Säilytä kuitenkin ruudut neliöinä. Ruudulle ei tarvitse määrätä minimikokoa.
- Lisää lomakkeelle asetus jolla voi valita miten päin nappulat sijoitetaan pelilaudalle: joko kolmostason tapaan tai
- Skaalaa myös pelinappulat ruudukon koon mukana. Älä käytä erillisiä kuvatiedostoja vaan liitä nappuloihin tarvittava svg-koodi DOM-rajapinnan kautta suoraan sivulle.
- Osoita selkeällä tavalla kumman pelaajan vuoro on kyseessä. esim. näyttämällä pelilaudan yläpuolella tai vieressä vuorossa olevan pelaajan nappulaa/väriä
- Pidä huoli, että pelaaja voi siirtää vain omia nappuloitaan
- Uuden pelin voi aloittaa milloin tahansa
Tyypillisiä virheitä
Älä tee näitä virheitä
Yleisongelmana voisi todeta, että joko tehtävään liittyviä vaatimuksia ei lueta tai sitten luetun ymmärtämisessä on ongelmia. Jos tehtävät pitää palauttaa zip-pakettina niin se myös tarkoittaa zip-pakettia eikä mitä milloinkin pakettimuotoa. Sama koskee muitakin ohjeissa mainittuja asioita eli jos jotain kielletään niin kielto on ehdoton.
- Vastaus oli vain zip-paketissa eikä suoraan testattavana sivuna
- HTML-dokumentin sisältöä oli muutettu käsin vaikka se erikseen ohjeessa kiellettiin.
On syytä ymmärtää, että aina ei pääse itse muokkaamaan dokumenttia, jonka sisältöä pitää käsitellä DOM-rajapinnan avulla. On siis osattava käydä DOM-puuta läpi muutenkin kuin vain pyytämällä ID-arvon perusteella tiettyä elementtiä.
- DOM-puun läpikäyntiä ei vissiin oikein oltu osattu, koska osa oli joutunut lisäämään id-tunnisteita HTML:ään. getElementsByTagName-funktion käyttöä on syytä opetella. Samoin window.onload ja miten sen avulla saadaan suoritettua javascriptiä sivun latauduttua taisi olla joillekin uutta.
- Älkää googlailko ohjeita satunnaisilta ö-luokan sivuilta vaan pitäytykää esim. firefoxin MDN-sivustossa. W3Schools ei ole laadukas sivusto vaikka se googlella ensimmäisenä usein pomppaakin vastaan. W3Schoolsilla ei ole myöskään mitään tekemistä W3C-organisaation kanssa.
- Vastauksia oli palautettu ties missä pakettiformaateissa. .rar ei ole zip-paketti eikä myöskään .7z.
- Oli käytetty innerHTML-funktiota vaikka se oli erikseen kielletty. innerHTML ei takaa sitä, että DOM pysyy ehjänä ja sen käyttäminen rikkoo muutenkin kaiken sen mitä DOM-rajapinnalla saavutetaan eli dokumentin rakennetta ei saada DOMin kautta rikki. innerHTML:llä voi kirjoittaa mitä tahansa tuubaa DOM-puuhun ja sitten ollaan ongelmissa. Vaikka innerHTML:llä saisi pidetty puun ehjänä niin voi silti käydä niin, että näihin lisäyksiin ei pääse enää käsiksi normaalin DOMin kautta. innerHTML:llä kikkailu ei myöskään auta jos pitää käsitellä muissa ympäristöissä XML-dokumentteja.
- Älkää palauttako linkkiä muuhun sivuun kuin suoraan tehtävään ja sen zip-pakettiin. Ei linkkejä omille koostesivuillenne tms.
- Tapahtumien käsittely kannattaa tehdä addEventListener-funktiolla eikä muokkaamalla elementin attribuutteja kuten onclick
- ID-attribuuttien arvoina käytettiin pelkkiä numeroita. ID-attribuutin arvoa koskevat samat rajoitukset kuin ohjelmointikielten muuttuja eli ei saa alkaa numerolla.
- document.writeln ei ole dom-funktio ja sotkee dokumenttipuun yhtä pahasti kuin innerHTML. Ei siis pidä missään tapauksessa käyttää.
- Merkistöongelmia:
- Käyttäkää editoria, joka osaa varmasti tuottaa UTF-8:ia. Esim. Notepad++
- Hyvä editori osaa myös näyttää mikä merkistö milloinkin on käytössä ja osaa muuntaa merkistöstä toiseksi
- Opetelkaa tavallisimmat Apache-www-palvelimeen liittyvät .htaccess-säädöt kuten jo ohjeessa annettu
merkistön määrittely:
AddCharset UTF-8 .html
Saman määrityksen voi antaa myös javascript-tiedostoille:AddCharset UTF-8 .js
- Merkistön suhteen ei pidä luottaa vain siihen mitä html-dokumentin sisään merkitään merkistöksi vaan oleeellisinta on HTTP-protokollan ilmoittama merkistö
- Jos skandit eivät toimi niin kokeilkaa firefoxilla:
- Kontekstivalikosta View Page Info niin näette mitä merkistöä palvelin on ilmoittanut dokumentin olevan
- View|Character Encoding-menusta voi kokeilla mikä on oikea ja toimiva merkistö
- Chrome arvailee merkistöä mutta Firefox käyttää juuri sitä mitä palvelin käskee. Chrome toimii siis väärin.
- Viitostason skaalausalgoritmi menisi jotenkin näin:
Selvitetään koko dokumentin korkeus ja leveys kysymällä html-elementiltä joko clientHeight/clientWidth tai scrollHeight/scrollWidth riippuen siitä halutaanko käyttää vain näkyvää aluetta vaiko koko dokumentin koko jossa luetaan mukaan myös näkyvän ruudun yli menevät osat.
Kysytään dokumentin alussa olevilta elementeiltä (h1, lomake, mitä muita sinne on mahdollisesti luotu) näiden korkeudet samaan tapaan kuin edellä.
Lasketaan paljonko ruudukolle jää tilaa (koko korkeus - muiden elementtien viemä korkeus).
Lasketaan yhden ruudun koko sen mukaan onko tilaa vähemmän pysty- vai leveyssuunnassa. Huomioidaan laskussa myös mahdolliset solujen ja taulukon marginaalit ym.

Käyttäjien kommentit