JavaScript alapok
Szükséges előismeret: Mostantól a teljes Alapok rész
A JavaScript nyelv
Ha itt tartasz, akkor feltételezem, hogy ismered a HTML és a PHP nyelveket (legalább alapszinten). Ha más nyelveket is ismersz, még nagyobb vállveregetés jár :). Hogy felhasználóbarátabb űrlapokat tudjunk készíteni, ebben a leckében kicsit belenézünk egy másik webes programozási nyelvbe is, amit javascript-nek hívnak. A cél ugyanis az lenne, hogy az ezen az oldalon lévő fórumhoz hasonló cuccot tudj készíteni, erősen leegszerűsített formában. Ott javascript kód csinálja például azt, hogy mikor egy gombra vagy smiley-ra kattintasz, beszúr a szövegmezőbe valamilyen karakterláncot. Ezen kívül persze néhány más problémát is meg fogunk nézni, mert igen hasznos dolgokat lehet csinálni ezzel a nyelvvel.
A javascript arra való, hogy az oldal HTML kódját dinamikusan változtassa bizonyos események bekövetkezésekor. Ez a PHP-tól teljesen független. Amikor egy weboldalt meg akarunk nyitni, a böngésző egy kérést indít a szerver felé, amin a weboldal található. Ha ez egy HTML oldal, a szerver egyszerűen visszaküldi a böngészőnek a HTML kódot, aminek a belsejében lehet javascript is. A benne lévő javascript kód értelmezése a böngésző feladata. Ha php fájlt akar a böngésző megnyitni, akkor a szerver előbb lefuttatja a PHP kódot, aminek a hatására előáll egy HTML kód (amiben szintén lehet javascript), majd a böngésző ezt kapja meg. Miután a böngésző megkapta a kódot, elkezdi megjeleníteni az oldalt a HTML kód alapján. A javascript kódok általában a HTML kód <head> részében vannak, és mikor ezeket beolvasta, elkezdi futtatni a javascipt kódot is, az oldal megjelenítésével párhuzamosan. Mivel a javascriptet a böngésző értelmezi és futtatja, nincs szükség hozzá webszerverre (mint például a wamp), mint a PHP esetében, elegendő egy böngésző.
Nézzük meg egy konkrét példán a javascript futását! Hozzuk létre az alábbi HTML kódot:
<html>
<head>
<title>Cím</title>
</head>
<body>
<script type="text/javascript">
document.write("Üdv az oldalon!");
</script>
<h1>Ez HTML!</h1>
</body>
</html>
A javascript kódot a HTML-en belül <script></script> tegek közé kell írni, és a fenti módon be kell állítani a type attribútumát. A fenti javascript kód egy egyszerű kiíratás, az utasítás az "Üdv az oldalon!" karakterláncot írja ki. A HTML kódot a böngésző értelemszerűen felülről lefelé olvassa be, és amint javascript utasítással találkozik, végrehajtja, majd olvassa tovább a HTML-t. Így a böngészőben megjelenik az "Üdv az oldalon!" szöveg, alatta pedig az "Ez HTML!" felirat.
A <script> tegek szerepelhetnek a <head> és a <body> belsejében egyaránt, például ha a <h1>Ez HTML!</h1> alá rakjuk, akkor a javascript által kiírt szöveg az "Ez HTML!" alatt jelenik meg.
A javascript nyelv nyelvtana nagyon hasonló a PHP-hoz. Itt is utasítások követik egymást, amiket ciklusokkal és elágazásokkal vezérelhetünk, változókat és függvényeket hozhatunk létre, és nagyrészt ugyanazokat az operátorokat használhatjuk. A ciklusok, elágazások és függvények létrehozása teljes egészében megegyezik a PHP alapok részben leírtakkal. Egészen a 13. leckéig bezáróan csak néhány fontos különbség van. Az egyik a változók létrehozása és elnevezése. A különbség az elnevezésben annyi, hogy nem kell $-jellel kezdődnie (bár lehet $-jelet használni a változónevekben, de általában nem szokás).
A változók létrehozása annyiban különbözik, hogy itt van egy tényleges létrehozásra szolgáló utasítás. A változót először létre kell hoznunk, utána használhatjuk (értékadásra, kifejezésben, kiírásra, stb). Létrehozni úgy kell, hogy a változó neve elé írjuk a var kulcsszót. Ezután értéket adhatunk neki (2. sor), de a létrehozás sorában is megtehetjük ezt (4. sor):
var count; count = 5; var n = 2;
A var kulcsszót csak a változó létrehozásakor kell használni, később már nem. Változó létrehozása akárhol előfordulhat, például gyakori, hogy egy for-ciklus ciklusváltozóját a kerek zárójelek közt hozzuk létre:
for (var n = 0; n < 10; n++){
...
}
Ha egyszerre több változót akarunk létrehozni, vesszőkkel elválasztva felsorolhatjuk egy sorban:
var i, j, k; var html = "<div>valami</div>", count, n = 0;
Ha olyan változót próbálunk használni, amit nem hoztunk létre (a használat nem értékadást jelent, hanem pl kiírás), akkor a PHP-vel ellentétben nem null értékű változót használsz, hanem hibát fogsz kapni. A javascriptben is létezik null érték, de azt csak mi tudjuk értékül adni a változónak. A létrehozott, de értéket még nem kapott változó értéke itt undefined.
Egy másik különbség a PHP nyelvhez képest, hogy itt karakterláncok összefűzésére nem a . (pont) operátor, hanem a + (összeadás) szolgál, valamint a logikai értékek neveit (true és false) csak kisbetűvel írhatjuk. További fontos különbség, hogy itt is vannak előredefiniált függvények, de azok neve és funkciója nem egyezik a PHP függvényeivel. Látható, hogy a kiírásra se egy print nevű függvény szolgál. Nézzünk egy példát:
<script type="text/javascript">
var n = 1;
while (n < 20){
if (n % 2 == 0){
document.write(n);
document.write(", ");
}
++n;
}
</script>
Ez a javascript kód a 20-nál kisebb páros számokat írja ki. Annyi a különbség az ennek megfelelő PHP kódhoz képest, hogy a változó neve előtt nincs $-jel, és a kiírásra egy másik függvényt használunk. Ha összefűzéssel akarjuk kiírni a változót és a vesszőt, akkor:
<script type="text/javascript">
var n = 1;
while (n < 20){
if (n % 2 == 0){
document.write(n+", ");
}
++n;
}
</script>
Magát a kódot pedig a HTML-en belül oda rakhatjuk, ahol a kiírást el szeretnénk végezni.
A HTML kód módosítása
Mint említettem, a javascript elsősorban arra szolgál, hogy a HTML kódot módosítsuk különféle események hatására. Az események érzékeléséről később, most nézzük meg, hogyan tudunk hozzáférni a HTML kód egyes részeihez, és ezeket hogyan tudjuk megváltoztatni! Fontos, hogy egy HTML elemet csak akkor tudunk olvasni és írni javascriptel, ha az már megjelent, így ezeket a kódokat egyelőre rakjuk közvetlenül a záró </body> teg elé!
A javascriptben sokféle módszer van arra, hogy egy adott HTML elemet elérjünk, most csak a legegyszerűbb, minden esetben használható módszert mutatom meg. Elem alatt itt most egy html tegre gondolok, az attribútumaival és a benne lévő tartalommal együtt. Ahhoz hogy egy elemre tudjunk hivatkozni a javascript kódban, egy egyedi azonosítót kell neki adni, a HTML-ben erre használható az id attribútum. Például van egy kép a HTML kódban, ami ugyebár egy <img /> teg. Ennek így adhatunk azonosítót:
<html> <head> <title>Cím</title> </head> <body> <img id="kep1" alt="" src="kep.jpg" /> <script type="text/javascript"> // ... </script> </body> </html>
Az id attribútum értéke bármi lehet, annyi kikötés van, hogy az angol abc kis- és nagybetűi és számjegyek használhatóak, valamint az első karakternek betűnek kell lennie. Néhány írásjel is használható, az _ (aláhúzás) és - (kötőjel) használata gyakori. Ezenkívül lényeges, hogy két tegnek nem lehet azonos az id attribútuma (különben javascriptben se tudunk egyértelműen hivatkozni rá)! A javascript kódban ezután így lehet hivatkozni a fenti img elemre:
document.getElementById("kep1")
Mostantól nem írom ki mindig a <script> tegeket, az a kód, ami nem HTML, nyilván javascript (legalábbis ebben a leckében). Oda kell figyelni a kis- és nagybetűkre, mert nem egyenértékűek!
A document.getElementById("...") kifejezéssel hivatkozhatunk egy id-vel megjelölt elemre, ahol a ... helyére kell írni az id attribútum értékét. A hivatkozásnál az elem többi tulajdonsága lényegtelen, az is mindegy, hogy éppen egy img tegről van-e szó, vagy másról, mindegyikre így lehet hivatkozni. Ezzel így önmagában nem sokat tudunk kezdeni, az a kérdés, hogy tudjuk elérni a teg nevét, egy adott attribútumának értékét, és a belsejébe írt HTML kódot. Ha ez a három dolog megvan, akkor nagyjából mindent tudunk az adott HTML elemről. A teg nevét így kapjuk meg:
document.getElementById("kep1").tagName
Ennek a kifejezésnek az értéke egy karakterlánc, ami csupa nagybetűkkel tartalmazza a teg nevét, jelen esetben az értéke "IMG".
Az attribútumokra általában a document.getElementById("...").attribútumnév formában hivatkozhatunk (részletesebben lásd egy kicsit később), pl.:
document.getElementById("kep1").src
Ez szintén egy karakterlánc, aminek az értéke az elem src attribútuma, jelen esetben "kep.jpg". Talán kicsit furcsának tűnnek ezek a kifejezések, de ugyanúgy használhatóak, mint bármilyen más változó. Értékül adhatjuk őket más változóknak, kiírathatjuk, vagy egy egyszerű értékadással megváltoztathatjuk. Például, ha meg akarjuk változtatni a képet, akkor ennyit kell csinálnunk:
document.getElementById("kep1").src = "masikkep.jpg";
Mivel ez már egy utasítás, pontosvesszővel le kell zárni. Az img egy üres teg, így a belsejében nincs HTML kód. De nézzük például ezt:
<p id="bekezdes" align="left">Hosszú <b>szöveg</b></p>
akkor a javascriptben így érhetjük el a benne lévő HTML kódot:
document.getElementById("bekezdes").innerHTML = "Rövid <i>szöveg</i>";
A document.getElementById("...").innerHTML kifejezés tartalmazza karakterlánc formában a teg és a zárópárja közti HTML kódot, amit például a fent látható módon változtathatunk meg. Mivel ez egy változó, ezért bonyolultabb műveleteket is végezhetünk, például ha a belsejében lévő HTML kód végére akarunk fűzni valamit, akkor ezt például így csinálhatjuk:
document.getElementById("bekezdes").innerHTML += " (vagy mégse?)";
Ezt végrehajtva a <p> teg tartalma ez lesz: Hosszú <b>szöveg</b> (vagy mégse?). Mivel az összefűző operátor itt . helyett +, az értékadó változata is ennek megfelelően .= helyett a += operátor. Vagy például be akarjuk színezni (az egyszerűség kedvéért font teggel) a bekezdés szövegét:
var text = document.getElementById("bekezdes").innerHTML;
document.getElementById("bekezdes").innerHTML =
'<font color="red">'+text+'</font>';
Hogy ne legyen olyan hosszú a sor, előbb beraktam a teg tartalmát egy text nevű változóba (amit létre kellett hozni), majd ennek a segítségével változtattam meg, de a 2. sorban természetesen lehet az eredeti kifejezést is használni. A javascriptben is lehet aposztrófokkal határolt karakterláncot használni, de escape karakterrel is kiírhatjuk az idézőjelet (\") ugyanúgy, mint a PHP esetében.
A fenti példában többször is hivatkoztunk ugyanarra az elemre. Mivel az elemre hivatkozó kifejezés is csak egy változó, megtehetjük azt, hogy berakjuk egy változóba, és utána nem kell mindig leírni ezt a hosszú kifejezést. Például:
var elem, text;
elem = document.getElementById("bekezdes");
text = elem.innerHTML;
elem.innerHTML ='<font color="red">'+text+'</font>';
Kivételes esetek
Az élet sajnos nem mindig olyan egyszerű, mint ahogy eddig felvázoltam (főleg ha az eddigiek sem tűntek egyszerűnek). Az egyik probléma, hogy van néhány teg a HTML-ben, aminek nem adhatunk id attribútumot, nevezetesen: base, head, html, meta, param, script, style, és title. Ezek közül egyedül talán a title elem lehet az, aminek a tartalmát javascripttel változtatni szeretnénk, de ezt könnyen megtehetjük. Az oldal <title> és </title> közötti részét a document.title kifejezéssel érhetjük el, megváltoztatni például így tudjuk:
document.title = "Új cím";
Ez id nélkül is egyértelmű, mivel az oldalon csak egy title teg lehet. A másik dolog, hogy némelyik attribútumra nem tudunk document.getElementById("...").attribútumnév módon hivatkozni. Például a class szó egy lefoglalt kulcsszó a javascript nyelvben, így nem hivatkozhatunk rá class néven, helyette a className használandó:
document.getElementById("bekezdes").className = "piros";
Továbbá, ha az attribútum neve eredetileg két különálló angol szó egybeírásával jött létre, akkor a második szó első betűjét nagybetűvel kell írni. Ilyen attribútumok például a readonly, maxlength vagy accesskey. Ezekre a javascriptben readOnly, maxLength és accessKey módon kell hivatkozni. Az érték nélküli attribútumok azok, melyek csak egy értéket vehetnek fel, ami megegyezik az attribútum nevével. Ilyet láthattunk az Űrlapok 1. leckéjében, például multiple="multiple", readonly="readonly", vagy selected="selected", stb. Ezeknek új értéket adni javascriptben logikai értékkel lehet, illetve logikai érték lesz a rájuk hivatkozó kifejezés értéke:
<input id="input" type="text" value="szöveg" /> <textarea id="text" disabled="disabled">hosszabb szöveg</textarea>
<script type="text/javascript">
var input, textarea;
input = document.getElementById("input");
textarea = document.getElementById("text");
input.readOnly = true;
if (textarea.disabled == true){
input.value = "";
}
</script>
Ebben a példában az input kap egy readonly="readonly" attribútumot, és mivel a textarea-ra vonatkozó feltétel teljesül, az inputban lévő szöveg törlődik, mert a value attribútumának üres karakterláncot adtunk értékül.
Amennyiben egy attribútum nem létezik, és úgy adunk neki értéket, akkor létrejön, ha pedig már létezett, akkor értelemszerűen megváltozik az értéke. Néha szükség lehet attribútum eltávolítására, ezt úgy tudjuk megtenni, hogy az elemre történő hivatkozás után írjuk, hogy removeAttribute(), és a zárójelek közé írjuk az eltávolítandó attribútum nevét karakterlánc formában, pl.:
document.getElementById("input").removeAttribute("class");
Vagy ha a fenti módon beraktuk az elemre való hivatkozást egy változóba:
input.removeAttribute("class");
Ez a kód eltávolítja a class attribútumot, ha létezett. Mivel ez egy karakterlánc, itt az attribútum HTML-beli nevét kell megadni, nem azt hogy className. Az érték nélküli attribútumokat is el lehet így távolítani, de úgy is, hogy false értéket adunk nekik.
Eseménykezelés
Ha kipróbáltad a fenti kódokat, eddig mindössze annyit láthattál, hogy a weboldal nem úgy jelenik meg, ahogy a HTML kódban van megadva, mivel az utána lévő javascript kód megváltoztatta. A weboldalunk látogatója ettől még biztos nem fog hanyattesni, a javascriptnek igazán akkor vesszük hasznát, ha ezeket a műveleteket bizonyos események bekövetkezésekor futtatjuk le. Például akkor változtassa meg a javascript egy bekezdés színét, ha rákattintok egy gombra, vagy akkor változtassa a kép elérési útját, ha ráviszem a képre az egeret, stb. Már csak két lépésre vagyunk ettől! Az első lépés az, hogy el kell érnünk, hogy ne futtassa le a böngésző ezeket a műveleteket a weboldal betöltésekor, viszont utána könnyen elérhetőek legyenek. A megoldás az, hogy berakjuk őket függvényekbe, és majd az esemény bekövetkezésekor hívjuk meg ezeket a függvényeket. A jobb áttekinthetőség kedvéért most visszarakjuk a javascript kódjainkat a <head> tegbe, mivel ott most csak függvénydefiníciók lesznek, azok pedig nem futnak le, amíg nem hívjuk meg őket. Azok az események amik bekövetkezésekor változtatni kell a HTML-t (kattintás, egérmozgatás), pedig úgyis csak azután következnek be, miután betöltődtek ezek a HTML elemek. Tegyük fel, hogy van egy kép, és azt akarom, hogy ha ráviszem az egeret, változzon meg. Készítsük el a javascript függvényt, ami ezt megcsinálja:
<html>
<head>
<title>Cím</title>
<script type="text/javascript">
function chimg(){
document.getElementById("kep").src = "kep2.jpg";
}
</script>
</head>
<body>
<img id="kep" src="kep1.jpg" />
</body>
</html>
Függvényeket ugyanúgy kell javacriptben definiálni és hívni, mint PHP-ben, ezen a téren szinte semmilyen különbség nincs köztük, és a nevük természetesen itt is tetszőleges. Tehát a böngésző a kep1.jpg képet jeleníti meg, ha lefuttatjuk a függvényt, akkor viszont a kep2.jpg-t. Ha azt akarjuk, hogy akkor váltson át a kép, ha az egeret a kép fölé viszem, akkor meg kell adni egy eseménykezelő attribútumot az img tegnek a következő módon:
<img id="kep" src="kep1.jpg" onmouseover="chimg();" />
Minden HTML tegnek (a head-et és a benne lévőket kivéve) meg lehet adni eseménykezelő attribútumokat, amik értéke nem egy sima karakterlánc, hanem javascript utasítás. Ez az utasítás akkor kerül végrehajtásra, ha az adott esemény megtörténik. Az onmouseover-be írt utasítás az egér fölévitelekor lesz lefuttatva. A "fölévitel" arra az elemre vonatkozik, amelyiknek megadtuk ezt az attribútumot, nem feltétlenül kell egyeznie a megváltoztatandó elemmel, a kettőnek semmi köze egymáshoz. Sok eseménykezelő attribútum van, melyek mindegyike egy meghatározott esemény hatására futtatja le az értékéül adott javascript kódot. Ide nem csak függvényhívást helyezhetünk el, hanem tetszőlegesen hosszú kódot, de azzal általában az áttekinthetőséget rontjuk. A fenti példában, miután rávittük egyszer az egeret a képre az megváltozik, és úgy is marad. Ha azt akarjuk, hogy mikor levisszük róla az egeret, visszaváltson az eredeti képre, akkor el kell készíteni egy függvényt, ami visszaállítja, és ezt az onmouseout eseménykezelőben kell meghívni:
<html>
<head>
<title>Cím</title>
<script type="text/javascript">
function chimg(){
document.getElementById("kep").src = "kep2.jpg";
}
function reimg(){
document.getElementById("kep").src = "kep1.jpg";
}
</script>
</head>
<body>
<img id="kep" src="kep1.jpg" onmouseover="chimg();" onmouseout="reimg();" />
</body>
</html>
Lehetőségünk van arra is, hogy paramétereket adjunk át a függvénynek. Mivel a két függvény szinte teljesen ugyanúgy néz ki, megtehetjük, hogy csak egy függvényt írunk, ami arra cseréli a képet, amit paraméterként kap. A függvény ekkor így néz ki:
function chimg(ujkep){
document.getElementById("kep").src = ujkep;
}
A pareméter neve tetszőleges, csakúgy mint a PHP esetén, de itt nem kell $-jellel kezdődnie. A paramétert nem kell a függvény belsejében létrehozni (főleg, hogy egy azonos nevű változó létrehozásával felül is írnánk), azonnal használhatjuk. A paramétert karakterláncként kell átadnunk a HTML kódban:
<img id="kep" src="kep1.jpg"
onmouseover="chimg('kep2.jpg');" onmouseout="chimg('kep1.jpg');" />
A karakterláncot aposztrófokkal kell határolnunk, mert az idézőjel a HTML attribútum értékét határolja. Escape karaktert pedig nem használhatunk a <script> tegeken kívül, mert a HTML nem ismeri ezeket.
Ha már idáig eljutottunk, előfordulhat, hogy egy olyan menüt akarunk készíteni, melyben a linkek képekből állnak, és ha ráviszem valamelyikre az egeret, akkor egy olyan kép jön be, ami kissé különbözik az eredetitől, majd he leviszem, visszaáll. Persze mindegyik kép különbözik, és mindegyikhez tartozik egy kép, amire le kéne cserélni. Az eddigi ismeretek alapján mindegyikhez külön függvényt kellene írni, hacsak nem adjuk át paraméterként az img id attribútumának értékét a kép nevén kívül (amire a jelenlegit kell lecserélni). Ekkor valami ilyesmit kapunk:
function chimg(id, ujkep){
document.getElementById(id).src = ujkep;
}
A HTML rész pedig:
<img id="menu1" src="kep1.jpg"
onmouseover="chimg('menu1', 'kep1_masik.jpg');"
onmouseout="chimg('menu1', 'kep1.jpg');" />
<img id="menu2" src="kep2.jpg"
onmouseover="chimg('menu2', 'kep2_masik.jpg');"
onmouseout="chimg('menu2', 'kep2.jpg');" />
Könnyen lehet, hogy az adott elem valamelyik adatát fel kell használni a függvényben, mint itt az id értékét. Ilyenkor kényelmesebb lehet, ha átadjuk magát a HTML elemet paraméterként. Az aktuális HTML elemet (amelyikben éppen van a javascript függvényhívás) a this kulcsszóval érhetjük el. Ha ezt átadjuk paraméterként a függvénynek, akkor a document.getElementById("...") hivatkozás helyett az átadott paramétert használhatja:
function chimg(elem, ujkep){
elem.src = ujkep;
}
<img id="menu1" src="kep1.jpg" onmouseover="chimg(this, 'kep1_masik.jpg');" onmouseout="chimg(this, 'kep1.jpg');" /> <img id="menu2" src="kep2.jpg" onmouseover="chimg(this, 'kep2_masik.jpg');" onmouseout="chimg(this, 'kep2.jpg');" />
A this egy javascript kulcsszó, ami az aktuális HTML elemre hivatkozik, így nem karakterláncként kell átadni, hanem úgy mint egy változót.
Oldjuk meg a másik említett problémát is, miszerint ha rákattintok egy gombra, történjen valami. Mondjuk ne egy bekezdés színe változzon, hanem fűződjön hozzá egy karakterlánc egy textarea-ban lévő szöveghez. A textarea esetén a jelenleg benne lévő szöveget a value tulajdonságával tudjuk elérni és módosítani. A kattintáshoz tartozó eseménykezelő attribútum pedig az onclick.
A javascript függvény és a hozzá tartózó HTML kódrészlet:
function addtext(text){
document.getElementById("ta").value += text;
}
<textarea id="ta">Eredeti szöveg</textarea>
<input type="button" value="OK" onclick="addtext('\nmég egy kicsi');" />
Ez meg mi? A textarea-nak nincs is value attribútuma! Ellenben a beleírt szöveg a nyitó és záró teg között van, akkor elvileg innerHTML-lel kellene elérni...
A textarea ilyen szempontból kicsit különbözik a többi elemtől. Az innerHTML-je azt a szöveget tartalmazza, ami eredetileg bele volt írva, tehát ami a HTML kódban szerepel a két teg között. Ennek a módosítása azonban hatástalan. Az éppen beírt szöveget a value segítségével lehet elérni, ami ebben az esetben nem egy attribútum, hanem az elem egy "tulajdonsága". Az éppen beírt szöveg módosítását is úgy tehetjük meg, ha a value-t módosítjuk.
A \n itt is újsor-karaktert jelent, mint a PHP-ben, de azzal ellentétben itt aposztrófokkal határolt karakterláncban is használhatóak az escape karakterek. Ha rákattintunk a gombra, a textarea addigi szövegének a végére hozzáfűződik egy sortörés és a "még egy kicsi" karakterlánc.
Ezek után nem túl megerőltető dolog rájönni, vajon a fórumban hogy van megvalósítva a smiley-k beszúrása. A különbség annyi, hogy a gomb helyett img elemeken van az onclick attribútum, meg a kurzor poziciója le van kérdezve, így a beszúrás a kurzor helyére történik, nem az addig írt szöveg végére.
Egyéb műveletek
A javascript segítségével sok olyan problémát meg tudunk oldani, amit önmagában a HTML-lel nem lehet, vagy körülményes lenne. A HTML például nem ad lehetőséget arra, hogy egy űrlap elküldéséhez tetszőleges elemet használjunk. Az elküldéshez kétféle HTML elem használható, az egyik az Űrlapok 1. leckéjében megismert <input type="submit"> elem, a másik:
<input type="image" alt="Küldés" src="kep.jpg" />
Ez a weboldalon ugyanúgy néz ki, mint egy img elem a megadott alt és src attribútumokkal, annyi a különbség, hogy ha rákattintunk, elküldi azt az űrlapot, amelyikben szerepel. Így egy képet használhatunk űrlap elküldéséhez.
Azonban ha más elemet akarunk erre használni, vagy az űrlapelküldő elemet nem tudjuk a megfelelő <form> teg belsejébe rakni (mondjuk az oldalon több űrlap is van, és az oldal szerkezete ezt nem teszi lehetővé), akkor javascripttel kell elküldeni az űrlapot. A form teget azonosítani kell egy id attribútummal, majd ezzel az utasítással el kell küldeni az űrlapot:
document.getElementById("urlap1").submit();
Ez elküldi az "urlap1" id-jú űrlapot. Csak annyit kell tenni, hogy ezt berakjuk egy függvénybe, majd az általunk kiválasztott elküldő elemre egy onclick eseménykezelőt rakunk:
function sendform(urlapid){
document.getElementById(urlapid).submit();
}
<form id="urlap1" method="post" action="...">
...
</form>
...
<a onclick="sendform('urlap1');">Elküldés</a>
Fontos megjegyezni, hogy ha javascript segítségével küldjük el az űrlapot, akkor nem fog létrejönni a feldolgozó kódban olyan $_POST tömbelem, aminek a kulcsa a submit gomb name paraméterével egyezik (függetlenül attól, hogy van-e submit gomb az űrlapon). Az ugyanis csak akkor jön létre, ha a submit gombra kattintva küldtük el az űrlapot. Ha javascripttel küldjük el, akkor egy másik űrlapelemhez tartozó $_POST változót kell megvizsgálnunk, hogy létezik-e, ha ki szeretnénk deríteni hogy az űrlap el lett-e küldve. Ha az image űrlapelemmel küldjük el az űrlapot, akkor létrejön a megfelelő változó, feltéve ha adunk neki name és value attribútumot, ugyanúgy mint a submit esetén, pl.:
<input type="image" name="kuld" value="1" alt="Küldés" src="kep.jpg" />
Ebben az esetben a feldolgozó kódban a $_POST["kuld"] változó értéke "1" lesz. Általában ezt arra használjuk, hogy megvizsgáljuk egy feltétellel, hogy el lett-e küldve az űrlap, így a value-ba akármit írhatunk. Minderre persze csak akkor van szükség, ha a feldolgozó kód ugyanabban a fájlban van, mint az űrlap.
Postosabban: a szabvány azt írja elő, hogy a feldolgozó oldalon a $_POST["kuld"] változó értéke "1" legyen! Sajnos egyes böngészők ezt a szívességet nem teszik meg nekünk, nem fog létrejönni a feldolgozó oldalon ilyen változó (és érdekes módon most nem konkrétan az IE-ről van szó, mint általában, amikor böngészők közti különbségekről kell szót ejteni).
Ha azt akarjuk hogy minden böngészőben működjön a kód, a $_POST["kuld"] változó helyett a $_POST["kuld_x"] vagy $_POST["kuld_y"] változó értékét vizsgáljuk, mert ezek minden böngészőben létezni fognak a feldolgozó oldalon, feltéve ha image típusú elemmel lett elküldve. Ezek egyébként a képre történt kattintás koordinátáit adják meg, de ez általában nem lényeges, elég ha leellenőrizzük valamelyik létezését. Ha létezik, az űrlap el lett küldve.
A javascript lehetővé teszi azt is, hogy egyedi űrlapelemeket készítsünk. Tegyük fel, hogy ki kell választani egy űrlapon három lehetőség közül egyet. Ezt meg lehet oldani legördülő menüvel vagy rádiógombbal, de tegyük fel, hogy mindhárom lehetőséget szimbolizál 1-1 kép, és a fejünkbe vettük, hogy ennek az alábbi módon kell működnie:
A képre való kattintgatással tudod kiválasztani a megfelelő opciót. Eredetileg beadja az első lehetőséget, ha rákattintasz, megjelenik a második, majd a harmadik, utána ismét az első. Most mindenkire rábízom, hogy valamilyen funkcionalitást képzeljen mögé, a lényeg az, hogy az űrlapfeldolgozó kódnak valahogy továbbítani kell, hogy melyik opció lett kiválasztva. A legegyszerűbb, ha a 0, 1, 2 számok jelzik majd a kiválasztott opciót (0: narancssárga i betű, 1: kék + jel, 2: piros x). Ennek megfelelően a képek nevei is legyenek kep0.png, kep1.png és kep2.png, hogy egyszerűbb legyen leprogramozni. Ahhoz, hogy az űrlap továbbítani tudja az adatot, mindenképp létre kell hoznunk neki egy űrlapelemet. Van egy olyan input típus, amiről még nem esett szó, ez a rejtett űrlapelem:
<input type="hidden" name="tipus" value="0" />
A PHP kód szempontjából olyan, mint a text elem, azzal a különbséggel, hogy nem jelenik meg a weboldalon, így a felhasználó nem is tudja megváltoztatni az értékét. Ha elküldjük az űrlapot, amiben ez szerepel, a feldolgozó PHP kódban a $_POST["tipus"] változó értéke az elem value attribútuma lesz (vagyis ebben az esetben a "0" karakterlánc).
A feladat tehát az, hogy egy ilyen rejtett elemet rakjunk az űrlapba (azon belül mindegy hova, mert úgyse jelenik meg), majd a képre történő kattintással ennek a value attribútumát változtatjuk. A HTML kód tehát így fog kinézni:
<img id="kep" src="images/kep0.png" onclick="imgchange();" /> <input id="tipus" type="hidden" name="tipus" value="0" />
Mindkettőnek adtunk id-t, hogy hivatkozni tudjunk rá a javascript kódból. Az imgchange() függvénynek tahát az lesz a feladata, hogy változtassa meg a kép elérési útját, valamint a rejtett mező value attribútumát. Ha 0, 1 és 2 számokon kell végiglépkedni, akkor legegyszerűbb, ha a függvény a jelenlegi értékhez egyet hozzáad, majd a 3-mal vett osztási maradékát veszi. Így a 2 után a 0-s érték fog következni, mivel (2 + 1) % 3 = 0. A javascript kód tehát ez lesz:
function imgchange(){
var tipus, kep, ujertek;
tipus = document.getElementById("tipus");
kep = document.getElementById("kep");
ujertek = (tipus.value + 1) % 3;
tipus.value = ujertek;
kep.src = "images/kep"+ujertek+".png";
}
Előbb érdemes berakni változókba a két elemet, aminek az attribútumait változtatni kell, így áttekinthetőbb lesz a kód többi része.
Házi feladat
Adott az alábbi HTML kód:
<input type="button" value="+" /> <input type="button" value="-" /> <input type="button" value="reset" /> <br /><br /> <img alt="" src="kep.jpg" />
Vagyis van egy kép, felette 3 gomb: "+", "-" és "reset". Valósítsd meg, hogy ha a "+" gombra kattintunk, akkor nagyítsa a képet (mondjuk 10%-kal, a méretarányt megtartva), a "-" pedig kicsinyítse ugyanígy. Ha a "reset"-re kattintunk, kapjuk vissza az eredeti méretet. Működjön úgy, hogy a felhasználó ne tudja egy bizonyos maximális szélességűnél nagyobbra nagyítani a képet, nehogy szétnyomja az oldalt! Próbáld meg megvalósítani egyetlen javascript függvénnyel.
A méretarány megtartása azt jelenti, hogy elég csak a width attribútumot változtatni, a height ne legyen megadva, ekkor ugyanis a böngésző megtartja a szélesség és magasság arányát.
Infó: Tudni kell, hogy minden HTML attribútumnak van valamilyen alapértelmezett értéke, és ha az attribútum nincs megadva, akkor az a javascript szempontjából olyan, mintha az alapértelmezett értékkel lenne megadva. Jelen esetben a width attribútum értéke (mivel nincs megadva) megegyezik a kép valódi szélességével. Erre nem nehéz rájönni, ha észrevesszük, hogy ha nem adjuk meg a paramétert, akkor a böngésző a képet az eredeti méretében jeleníti meg.
A program itt látható működés közben (illetve le is tölthető): img.html
Mindenekelőtt a HTML kódot egészítsük ki eseménykezelő attribútumokkal. A feladat kérése, hogy csak egy függvényt használjunk, így mindegyik esemény hatására ugyanazt a függvényt futtatjuk le, így paraméterként kell átadni neki, hogy melyik műveletet kell elvégezni:
<input type="button" value="+" onclick="zoom('+');" />
<input type="button" value="-" onclick="zoom('-');" />
<input type="button" value="reset" onclick="zoom('reset');" />
<br /><br />
<img id="kep" alt="" src="kep.jpg" />
A képnek is adnunk kell egy id-t, mivel erre kell hivatkoznunk a javascript kódban. A függvény pedig a paramétere alapján eldönti (egy else-if vagy switch szerkezettel), hogy a kép width attribútumának értékét hogyan módosítsa. Ha a paraméter "+", akkor 1.1-gyel kell szorozni (ugyanis ezt jelenti a 10%-kal való növelés), ha "-" akkor pedig osztani kell ugyanezzel. Ha a paraméter "reset", akkor pedig el kell távolítani a width attribútumot, és így a böngésző a képet az eredeti méretében jeleníti meg. A függvény például így nézhet ki:
function zoom(mode){
var kep = document.getElementById("kep");
switch (mode){
case "+":
if (kep.width < 600){
kep.width *= 1.1;
}
break;
case "-":
kep.width /= 1.1;
break;
case "reset":
kep.removeAttribute("width");
break;
}
}
A "+" esetén van egy plusz feltétel, mivel a feladat kérése volt, hogy egy bizonyos maximális méretnél ne lehessen nagyobb a kép. Itt a feltétel azt csinálja, hogy csak akkor növeli a kép méretét, ha a szélessége (width attribútum értéke) 600 pixelnél kisebb.







