JavaScriptillä voidaan saada aikaan Web-sivuja, jotka "vastaavat" käyttäjän toimenpiteisiin kuten hiiren klikkauksiin, syöttötietojen kirjoittamiseen ja sivulla liikkumiseen. Yleisemmin JavaScriptillä voidaan ohjelmoida erilaisia toimintoja, jotka selain suorittaa - mahdollisesti.
Tämä kappale on esimerkki siitä, miten HTML-dokumenttiin saattaa tulla mukaan selaimen lisäämää sisältöä. Tässä tapauksessa JavaScript-koodi lisää päiväyksen:
Voi tietysti kysyä, mitä iloa moisesta on. Oletetaanko käyttäjä typerykseksi, joka ei osaa itse katsoa (esim. tietokoneestaan), mikä päivä on? Yleensä tällaiset päivämääräntulostukset ovatkin pelkkää peeloilua. Mutta jos teet esimerkiksi lomakkeen, josta käyttäjä voi valita päivämäärän, haluat ehkä asettaa "nykyisen" (siis lomakkeen täyttämishetken) päivän oletusarvoksi; siinä voisi olla järkeä. Se vaatiikin sitten jo vähän enemmän.
Suuri osa JavaScriptiä sisältävistä Web-sivuista käyttää sitä erilaisiin ärsyttäviin efekteihin kuten uusien ikkunoiden pulautteluun käyttäjän ruudulle ja käyttäjän sivulla liikkumisen rajoittamiseen. Lisäksi JavaScript-toteutuksista löytyy aina uusia turvallisuusaukkoja. Näistä ja muista syistä onkin syytä varautua siihen, että monet fiksut käyttäjät ovat disabloineet JavaScriptin eli käskeneet selaintaan olemaan suorittamatta JavaScript-koodia tai että JavaScript muutoin jää suorittamatta.
Toisaalta JavaScriptillä on monenlaista hyvinkin hyödyllistä
käyttöä. Ks. kirjoitusta
JavaScript: mukavuutta, mutta myös riskejä.
Sivulle voidaan kirjoittaa
noscript
-elementti,
jonka sisällössä kuvataan, mitä hyötyjä voisi saavuttaa käyttämällä
selainta, jossa JavaScriptin suoritus on sallittu.
JavaScript on ohjelmointikieli, jota yleensä
käytetään selainskriptien tekemiseen (client-side
scripting):
jos HTML-dokumenttiin on sopivalla tavalla liitetty
JavaScript-ohjelma, niin
Web-selain mahdollisesti suorittaa tämän ohjelman, kun
sitä on käsketty näyttämään kyseinen HTML-dokumentti.
Ohjelma voi olla hyvin yksinkertainen, esimerkiksi
alert('heippa')
, joka luo ruudulle ikkunan ja siihen tekstin
heippa ja odottaa, että käyttäjä "kuittaa" tämän
klikkaamalla ikkunassa olevaa OK-painiketta.
Toisella tapaa (ja paljon harvemmin) JavaScriptiä käytetään
palvelinskriptien tekemiseen.
JavaScript on sinänsä vain yksi monista selainskriptien tekemiseen käytetyistä kielistä. Se on kuitenkin ehdottomasti laajimmin selainten tukema ja sen takia yleisimmin käytetty. (Toiseksi yleisin lienee VBScript, jota IE tukee.) Selainskriptien liittämistä HTML-dokumentteihin käsittelee yleisesti, siis ohjelmointikielestä riippumattomalta osin, HTML-spesifikaation luku Scripts.
Koska kielen toteutus perustuu tulkintaan (interpretation) eikä kääntämiseen (compilation) ja koska JavaScript-ohjelmat ovat tyypillisesti aika pieniä, puhutaan JavaScriptin yhteydessä usein skripteistä (scripts) eikä ohjelmista (programs). Kyse on kuitenkin vain sananvalinnasta.
JavaScript on suhteellisen monipuolinen ohjelmointikieli.
Muita ohjelmointikieliä tuntevalle sanonee jotain se,
että JavaScriptissä on melko tavanomainen funktiokäsite,
rakenteiset ohjauslauseet (esim. while
toiston
toteuttamiseen), taulukkorakenne, joustava merkkijonojen käsittely ja
suuri joukko valmiita funktioita, jotka liittyvät etenkin
selaimen toimintojen ohjaamiseen.
Toisaalta hyvinkin yksinkertaisilla JavaScript-ohjelmilla - joita
siis kaikki eivät edes ohjelmiksi kutsu - voi tehdä
monenlaisia asioita.
JavaScriptin liittäminen HTML-dokumenttiin voidaan tehdä useilla tavoilla:
<li onclick="alert('heippa!')">Tämä toimii toistaiseksi vain IE 4:ssä ja uudemmissa, mutta mm. normaaleihin linkkeihin liitetyt
onclick
-määritteet toimivat kaikissa JavaScriptiä
tukevissa selaimissa.
.js
ja joka pannaan sellaiseen hakemistoon, että siihen voidaan viitata
URLilla; koodi sitten "otetaan mukaan"
HTML-dokumentissa seuraavasti:
<script type="text/javascript" language="JavaScript" src="URL"></script>"Mukaan ottaminen" tarkoittaa koodin suorittamista siinä vaiheessa, kun selain dokumenttia käsitellessään tulee kyseiseen kohtaan. Jos koodi sisältää funktioita, niin ne vain tallentuvat selaimen muistiin myöhempää kutsumista varten. Valitettavasti tämän menetelmän käytössä on eräitä selainten virheistä johtuvia ongelmia.
<script type="text/javascript" language="JavaScript"><!-- JavaScript-koodi tulee tänne //--></script>
Seuraavassa on pari yksinkertaista esimerkkiä. Runsaasti muita esimerkkejä löytyy esimerkiksi Website Abstractionin Free JavaScripts! -sivuilta. Kannattaa kuitenkin muistaa, että useimmiten JavaScriptillä pilataan sivuja eikä paranneta niitä. Ajattelu ja harkinta kannattaa, samoin esimerkkien katselu ideoiden saamiseksi. Sensijaan kopioimalla koodia ymmärtämättä, mitä se tekee ja miten ja milloin, onnistuu yleensä vain sotkemaan asioita.
Olettakaamme, että haluaisimme, että Web-sivulla oleva kuva
vaihtuu toiseksi, kun kursori viedään sen päälle.
Luonnollinen tapa tehdä tämä
JavaScriptillä olisi seuraava:
<img alt="" src="1.gif" name="kuva1" width="148" height="109" onmouseover="if(document.images) document.kuva1.src='2.gif'">
Tässä onmouseover
on tapahtumamäärite,
ja sitä vastaava tapahtuma (kursorin vieminen kuvan alueelle
hiiren tai vastaavan laitteen avulla) aiheuttaa määritteen
arvona olevan JavaScript-ohjelman suorittamisen. Jos selain
tukee JavaScriptiä ja tuki on enabloituna; muuten ei tapahdu mitään.
Kyseessä on toki erittäin yksinkertainen ohjelma, joka muuttaa
dokumenttia - sellaisena kuin se on selaimen muistissa - siten,
että kyseisen img
-elementin src
-määritteen
arvoksi tulee 2.gif
. Hyvään
JavaScript-ohjelmointityyliin kuuluu tarkistaa, tukeeko käytössä oleva
kielen toteutus tarvittavia "olioita" ennenkuin niitä "olioita" yritetään
käsitellä, tässäkin on ehto if(document.images)
. (Tämän
nimenomaisen varmistuksen käytännöllinen merkitys on suhteellisen pieni,
koska lähes kaikki JavaScript-toteutukset tukevat kuvaolioita.
Yleisesti tällaiset tarkistukset ovat hyvinkin tarpeellisia.)
Edellä kuvattu luonnollinen rakenne kuitenkin toistaiseksi toimii
vain joissakin selaimissa, lähinnä IE 4:ssä ja uudemmissa.
Huomattavasti laajemmin tuettu on rakenne, jossa
onmouseover
on liitetty linkkiin eli a href
-elementtiin eikä
img
-elementtiin. Tässähän ei sinänsä ole ongelmaa, jos
haluammekin kuvan olevan linkki. Mutta jos emme, niin sitten
pitää temppuilla, jotta rakenne joka (teknisesti) on linkki ei
näyttäisi linkiltä ja jotta mitään ei tapahtuisi, jos sitä kuitenkin
yritetään seurata:
<a href="#" onmouseover= "if(document.images) document.kuva2.src='2.gif'"><img alt="" src="1.gif" name="kuva2" border="0" width="148" height="109"></a>
Tässä on kirjoitettu href
-määritteen
arvoksi "#"
, mikä on periaatteessa väärin
(virheellinen URL-viittaus)
mutta
ei tässä yhteydessä aiheuta ongelmia. Linkkiä ei ole tarkoituskaan
seurata, eikä yritys seurata sitä johda mihinkään.
Jos halutaan, että kursorin poistuessa kuvan päältä kuva palautuu
ennalleen, kirjoitetaan onmouseover
-määritteen lisäksi
onmouseout
-määrite samaan tapaan.
Kun JavaScriptillä muutetaan dokumentin sisältöä, niin muutettavan kohdan ei tarvitse olla sen elementin sisällä, johon tapahtumamäärite liittyy. Voimme esimerkiksi tehdä tekstilinkin, jota ei ole tarkoitettukaan seurattavaksi vaan toimimaan vain seuraavasti: kun kursori viedään linkkitekstin päälle, kaksi jossain muualla olevaa kuvaa vaihtuvat, ja kun kursori viedään pois, kuvat palautuvat ennalleen.
Tässä tapauksessa JavaScript-ohjelmalla on jo sen verran pituutta, että se kannattaa kirjoittaa funktioksi. Silloin tapahtumamääritteiden arvoiksi kirjoitetaan vain funktioiden kutsut:
<a href="#" onmouseover="vaihda2()" onmouseout="vaihda2tak()">teksti</a>Funktioiden määrittelyt voidaan kirjoittaa erilliseen tiedostoon, sanokaamme
vaihda.js
, ja dokumenttiin
kirjoitetaan viittaus siihen aiemmin kuvatulla tavalla.
Koodi voisi olla seuraava:
function vaihda2() { if(document.images) { document.kuva1.src = '2.gif'; document.kuva2.src = '3.gif'; } } function vaihda2tak() { if(document.images) { document.kuva1.src = '1.gif'; document.kuva2.src = '1.gif'; } }
JavaScriptissä aaltosulut {
ja }
toimivat
ryhmittelymerkkeinä. Koko funktion runko kirjoitetaan niiden väliin.
Lisäksi niitä käytetään tarvittaessa ryhmittelyyn funktion sisällä.
Esimerkiksi tässä tapauksessa if
-lauseen sisällä pitää
olla olla sijoitusta, joten ne "kootaan yhteen" aaltosuluilla.
Sekä JavaScriptissä että HTML:ssä tarvitaan
lainausmerkkejä erilaisten merkkijonojen
rajoittimina. Tilannetta hankaloittaa mm. se, että HTML:n
määritteen arvo kirjoitetaan lainausmerkkeihin ja toisaalta
usein sisältää JavaScript-merkkijonovakion.
Asioita helpottaa, kun omaksuu sen käytännön, että HTML:ssä
käytetään varsinaisia lainausmerkkejä
(kaksoislainausmerkkejä, "
) ja
JavaScriptissä puolestaan lainausmerkkien heittomerkkejä
(yksinkertaisia lainausmerkkejä, '
).
Huomaat varmaan, että funktiot ovat hyvin samanlaisia. Voisimmekin tehdä asian tyylikkäämmin käyttämällä funktion argumentteja, jolloin selviämme yhdellä funktiolla. (Isommissa hommissa argumenttien käyttö yksinkertaista ja helpottaa ohjelmointia vielä paljon enemmän.) Funktio olisi tällöin esim. seuraava:
function vaihdane(eka,toka) { if(document.images) { document.kuva1.src = eka; document.kuva2.src = toka; } }ja dokumentissa olisi:
<a href="#" onmouseover="vaihdane('2.gif','3.gif')" onmouseout="vaihdane('1.gif','1.gif')">teksti</a>
Jos suurin piirtein ymmärsit, mistä edellä esitetyssä on kyse, tiedät JavaScript-ohjelmoinnin perusteista luultavasti enemmän kuin useimmat, jotka yrittävät sitä räpeltää.
Jotta lomakkeen kenttään voisi kirjoittaa, täytyy yleensä selain saada "fokusoimaan" siihen eli tekemään kyseinen kenttä aktiiviseksi. Tämä tapahtuu tavallisesti viemällä kursori kentän alueelle ja klikkaamalla hiiren nappia. Tämä ei ole kovin suuri vaiva, mutta JavaScriptillä voimme ehkä auttaa käyttäjää välttämään sen.
Eräs tapa ilmenee seuraavasta esimerkistä (jota voi
kokeilla erikseen).
Lomakkeelle name
-määritteellä annettava nimi
on vapaasti valittavissa.
<form action="http://www.google.com/search"
name="lomake">
<div><a href="http://www.google.com/">Google</a>:
<input type=text name=q size=40>
<input type=submit value=Search>
</div></form>
<script type="text/javascript" language="JavaScript"><!--
document.lomake.q.focus();
//--></script>
Lomakkeelta syötetty data pitää aina tarkistaa palvelinskriptissä, ennen kuin se rupeaa sitä muutoin käsittelemään - ellei sitten koko lomaketta ole tarkoitettukin vain selaimessa toimivaksi, kaikin siitä johtuvin rajoituksin.
Mutta etukäteistarkistus voi olla käyttäjälle mukava. On parempi saada mahdollisimman nopeasti "valitus" siitä, että jokin kirjoitettu data oli väärässä muodossa. Tällöin tietojen korjaaminen käy yleensä helpommin.
Ennakkotarkistus voidaan tehdä siten, että form
-tägiin
liitetään onsubmit
-määrite, jonka arvona on
JavaScript-funktion kutsu. Kyseinen funktio kirjoitetaan siten, että
se palauttaa arvon true
(tosi), jos datat ovat
hyväksyttäviä, ja arvon false
(epätosi) muutoin.
Jos lomake täytetään siten, että JavaScript on toiminnassa,
niin arvo false
aiheuttaa sen, että lomakkeen
lähetystä ei tapahdukaan, vaan lomakkeen sisältävä sivu jää
näkyviin. Jotta käyttäisi ymmärtäisi, mitä häneltä edellytetään, niin
funktion on syytä antaa virheilmoitus tai -ilmoituksia esim.
alert()
-funktiolla.
Seuraava esimerkki käyttää erästä laajahkoa lomakkeentarkistuskirjastoa. Tarvittavat tarkistusrutiinit eivät olisi kovin vaikeita itse koodata, mutta ainakin harjoittelussa ja kokeiluissa on mukava käyttää valmiita rakennuspalikoita. (Vakavammissa jutuissa on syytä ainakin lukea niiden palikoiden koodi ja katsoa, että se tekee sen mitä todella halutaan, kaikissa tapauksissa!).
|
Oletetaanpa, että meillä on tilauslomake, jolta käyttäjä voi asetusnapeilla (checkboxes) valita erilaisista osista koostuvan tuotteen. Haluamme näyttää käyttäjälle "juoksevan summan" eli paljonko siihen mennessä valitut osat yhteensä maksavat. Tämän tulee toimia niin, että jos käyttäjä poistaa valinnan, summa vastaavasti laskee.
Tehty lomake on toteutettu seuraavasti:
onclick
-määrite
seuraavaan tapaan:
<input type="checkbox" name="hinta1" onclick="laske()" value="25">Tämä aiheuttaa sen, että kun käyttäjä klikkaa asetusnappia muuttaakseen sen tilan, selain suorittaa JavaScript-funktion
laske()
-
jos nimittäin selaimessa on JavaScript enabloituna.
sum
uuden kokonaishinnan sen mukaan, mitkä asetusnapit ovat
valittuina, ja sitten sijoittaa tämän muuttujan arvon lomakkeen
kenttään; tämän sijoituksen selain tulkitsee siten, että
sen tulee muuttaa näytössä näkyvän tekstikentän sisältö:
var perushinta = 500; function laske() { var sum = perushinta; if(document.lomake.hinta1.checked) sum += eval(document.lomake.hinta1.value); if(document.lomake.hinta2.checked) sum += eval(document.lomake.hinta2.value); if(document.lomake.hinta3.checked) sum += eval(document.lomake.hinta3.value); document.lomake.summa.value = sum; }Tässä käytettävä muuttuja
document.lomake.summa.value
on JavaScriptille hyvin
tyypillinen. Se muodostaa osaltaan
liitynnän HTML:n ja JavaScriptin välille. HTML-dokumentti kokonaisuutena
"näyttäytyy" JavaScript-ohjelmalle document
-oliona
(objektina), jossa on erilaisia kenttiä.
Dokumentin kukin erikseen (name
-määritteellä) nimetty
lomake taas esiintyy document
-olion osana, jolle
käytetään pistenotaatiota, esim.
document.lomake
, ja lomakkeen (nimetyt) kentät vastaavasti
tyyliin document.lomake.summa
. Jotta voitaisiin
viitata kentän arvoon (sisältöön),
pitää loppuun lisätä vielä .value
.
Kentällä nimittäin on muitakin ominaisuuksia kuin arvo.
"(ei laskettu)"
. Näin vältytään näyttämästä käyttäjälle
väärää informaatiota. Erikseen sitten sellaisella JavaScript-koodilla,
jonka selain suorittaa automaattisesti dokumentin latautuessa,
asetetaan kyseiseen kenttään arvoksi tuotteen hinta ilman
lisukkeita.
readonly
.
Toistaiseksi tätä tukee vain IE 4+ (siten, että se ei anna
käyttäjän kirjoittaa kenttään). Tästä ja useasta muusta syystä
ei pidä luottaa kyseiseen määritteeseen!
Palvelinskriptin, joka käsittelee lähetetyn lomakkeen,
pitää joka tapauksessa tarkistaa data. Datassa olevaa kenttää, joka
ehkä sisältää JavaScript-koodin laskeman summan, ei ole syytä käyttää
muuhun kuin tarkistuksiin: jos se poikkeaa palvelinskriptin
laskemasta summasta, jotain on mennyt pieleen.
Olisi myös mahdollista kirjoittaa sivu niin, että
summan näyttävää tekstikenttää ei lainkaan näy silloin, kun
JavaScript on disabloituna. Tämä hoituisi sillä, että kyseinen
HTML-elementti (input type="text"
-elementti) ei ole
sivun kiinteä osa vaan JavaScript-koodi kirjoittaa sen
(document.write
-funktiolla).
Esimerkki on toki kovin alkeellinen, mutta havainnollistanee erästä
ideaa. Sen sujuvaksi soveltamiseksi isompiin lomakkeisiin kannattaa
tutustua mm.
JavaScript-fakin kohtaan
How do I display the value of each text field using a for
loop?.
JavaScript muistuttaa joissakin omituisissa yksityiskohdissa Perl-kieltä ja Java-kieltä sekä eräitä muita kieliä. Taustalla on yhteinen pohja, nimittäin C-kieli, joka suunniteltiin alkujaan ammattilaisten työkaluksi mutta joka pääsi karkuun laboratoriosta.
Näitä omituisuuksia, joihin lähes jokainen kieltä opiskeleva kompastelee ja jotka vaivaavat kokeneempiakin, ovat mm. seuraavat:
a
on taulukko, jossa on n alkiota, niin a
:n viimeinen
alkio on siis a[
n-1]
.
selectedIndex
. Sekaannuksia lisää, että jotkin
selaimet hyväksyvät myös esim. kirjoitusasun
SelectedIndex
mutta mm. Netscape ei.
short
. Yritys
käyttää sellaista muuttujannimenä
onnistuu joissakin versioissa mutta johtaa sekaviin ongelmiin toisissa.
=
ei koskaan tarkoita yhtäsuuruusvertailua
(jonka oikea symboli on ==
). Testi
if(i=1)
sijoittaa i
:n arvoksi ykkösen
ja antaa aina tuloksen tosi.
!
tarkoittaa ei.
%
ei ole mitään tekemistä prosenttien kanssa,
vaan m%
n antaa jakojäännöksen,
joka saadaan, kun m jaetaan n:llä
(esim 15%2
antaa tuloksen 1).
Lisäksi JavaScriptissä on sille ominaisia sudenkuoppia.
Niistä mainittakoon, että 2+2=22, mikä johtuu siitä, että
JavaScriptissä "+" on ensisijaisesti merkkijono-operaattori.
(Muuttujien a
ja b
summa saadaan
esim. lausekkeella (a-0)+(b-0)
.)
Erityisen suositeltava jokaiselle JavaScriptiä kirjoittavalle on kokeneen asiantuntijan Martin Webbin ohje JavaScript Guidelines and Best Practice. Martin ylläpitää myös laajaa fakkia: JavaScript FAQ Knowledge Base. Se on mm. laajuutensa takia osittain sekava: vaikka se on jaettu aihepiireittäisiin osiin, yhdessä osassa voi olla kymmenien kysymysten lista, eivätkä kaikki vastaukset ole tasoltaan yhtä hyviä. Aloittelijalle onkin avuksi erityisesti lista vastauksia kaikkein useimmin esitettyihin kysymyksiin: JavaScript Very Frequently Asked Questions. Lisäksi sivuilla on käytännöllinen hakulomake (joka itse asiassa hakee koko irt.orgista).
Fakit eivät suinkaan ole erehtymättömiä eikä niitä pidä
lukea kritiikittömästi. Esim. edellä mainittu
VFAQ sisältää
salasanasuojausta koskevaan kysymykseen
vastauksen, joka on varsin harhaanjohtava. Ks.
sfnet.viestinta.www
VUKK:n
vastausta salasanakysymykseen.
Kirjoitukseni JavaScript and HTML: possibilities and caveats esittää eräitä esimerkkejä (mm. uuden ikkunan avaaminen, josta myös Jouni Heikniemi on kirjoittanut jutun: Uudet ikkunat web-sivuilla - puolesta ja vastaan) ja yleisiä periaatteita JavaScriptin käytöstä etenkin lomakkeiden yhteydessä.
Netscapen JavaScript-dokumentaatio sisältää oppikirjatyyppisen JavaScript Guiden sekä käsikirjan JavaScript Reference (jossa on erittäin käyttökelpoinen hakemisto). Niistä on myös versiot, jotka voit ladata omaan koneeseesi. Ne soveltuvat JavaScriptin järjestelmälliseen opiskeluun, kunhan muistat edellä mainituissa muissa dokumenteissa olevat varoitukset. Internet Explorer tukee JScriptiä, joka on Microsoftin versio JavaScriptistä; siitä on laaja dokumentaatio Microsoftin sivuilla, mutta lisäksi tarvitaan Web Workshop -aineisto, jossa kuvataan eri objektit ja menetelmät, joita JScriptillä voi käsitellä. Etenkin etsittäessä vastineita Netscapen JavaScriptin rakenteille on kyseisen aineiston hakemisto erittäin hyödyllinen. ECMA on standardoinut osan JavaScriptistä (kielen eräät perusrakenteet) nimellä ECMAScript.