1 TÁMOP-4.1.2/A/1-11/ Egészségügyi Ügyvitelszervező Szakirány: Tartalomfejlesztés és Elektronikus Tananyagfejlesztés a BSc képzés keretében Kliens-old...
„TÁMOP-4.1.2/A/1-11/1-2011-0015 Egészségügyi Ügyvitelszervező Szakirány: Tartalomfejlesztés és Elektronikus Tananyagfejlesztés a BSc képzés keretében”
Kliens-oldali technológiák e-Book Dr. Daragó László
Tartalomjegyzék A böngésző (web kliens) programozói környezete .................................................................... 3 JavaScript ............................................................................................................................... 3 Programozási struktúra, alapszintaxis ................................................................................ 4 A JavaScript nyelvi elemei................................................................................................. 4 A HTML és a JavaScript összekapcsolása ........................................................................... 18 HTML DOM ........................................................................................................................ 20 A DOM (Document Object Model) ................................................................................. 20 A HTML DOM ................................................................................................................ 23 DOM események.............................................................................................................. 30 PHP és JavaScript közötti (egyszeri, egyirányú) adatátadás megvalósítása ........................ 33 HTML és CSS haladóbb szinten .............................................................................................. 34 A HTML5 alapjai ................................................................................................................. 34 A HTML4 és HTML5 tagjainek keresztreferenciája ....................................................... 35 CSS3..................................................................................................................................... 43 Néhány érdekes HTML5 megoldás...................................................................................... 49 XML transzformáció a kliens oldalon...................................................................................... 52 XML DOM........................................................................................................................... 52 Az XML dokumentumok szerkezete, használatuk............................................................... 53 WEB és XML................................................................................................................... 54 XML SAX ........................................................................................................................ 54 XSLT ................................................................................................................................ 55 Egyszerű XSLT elemek ............................................................................................... 56 XPATH alapok ................................................................................................................. 60 XPATH selectorok ........................................................................................................... 61
2
A böngésző (web kliens) programozói környezete JavaScript A JavaScriptet a 90-es évek IE/NN1 böngésző-háborúként emlegetett korszakában fejlesztettek ki a Netscape-nél (az IE a VBScriptet favorizálta). Nem tévesztendő össze a Java programozási nyelvvel, amely szintén interpreteres nyelv, de a Sun Microsystems (azóta már Oracle) fejlesztése. A két nyelv szintaxisa hasonló, ez talán annak köszönhető, a két fejlesztő csapat tagjai között mutatkozott átfedés, vagy talán mindannyian a C-n nőttek fel. A JavaScript, avagy Mocha, avagy LiveScript, avagy JScript, avagy ECMAScript ugyanazt jelöli. Douglas Crockford – aki állítólag nem rokona Douglas Adamsnek, bár humoruk összemérhető - szerint a JavaScript elnevezés létrejöttének valódi oka az, hogy az eredetileg kitalált Livescript név nem volt eléggé zavarba ejtő (vagy, ahogy a feltűnésre vágyók mondják: mindegy, hogy mit, csak beszéljenek rólam!). A Javascript két helyen futhat: a böngészőkben és a web-szervereken (amennyiben ott telepítették a JRE-t azaz Javascript Runtime Engine-t – vigyázat, a Java Runtime Environmentet is JRE-nek rövidítik ). A Javascript csakis, és kizárólag a WWW miatt jött létre. A kliens oldali JS3, támogatja programozási feladatok elkészítését a Weben (interaktív funkciók, animációk), a CSS3+HTML5 együttes használatával DHTML-nek is nevezik. A kliens és a szerver oldali rész alapvetően különbözik annak ellenére, hogy szintaxisuk egyező. A kliens oldali JS-kódot a böngésző végrehajtja, csak annak kimenete jelenik meg. A JS kódot a HTML kód közé, általában a és tagek közé, vagy a szekció elejére ékeljük, vagy egyszerűen csak meghivatkozzuk (ld. később, a HTML és JS kapcsolatának firtatásánál). Amikor a böngésző megjeleníti a HTML kódot, akkor a <script> és közé írt kódrészleteket nem megjeleníti, hanem értelmezi és futtatja, ezzel biztosítja az oldal dinamikus viselkedését. Mindezek után se menjen el senkinek a kedve a kurzustól, hiszen annyira mégsem reménytelen a helyzet, de azt is érdemes megjegyezni, hogy ez nem útikönyv, amit az elején szoktak kezdeni és a végén bezárni. Érdemes megbarátkozni az oda-vissza lapozgatás technikájával!
1
IE: Internet Explorer, NN: Netscape Navigator Douglas Crockford 3 Javascript, rövidítve 2
3
1. ábra Egy HTTP kliens-szerver modell
Programozási struktúra, alapszintaxis A szkriptek értéket visszaadó, vagy értéket vissza nem adó függvényeket (eljárásokat) tartalmaznak. Ezek felépítése ugyanolyan, mint az általában megismert vezérlési szerkezetek: ciklusok, feltételek, elágazások, eljárások és függvényhívások jellemzőek rá csakúgy, mint a korábban megismert (pl. PHP szkripteknél, vagy Office (VBA-moduloknál). A JS alapvető szintaxisa szerint az objektumokat { és }, a tömböket [ és ] foglalja magába, az utasításokat pedig sortörés helyett a ; zárja. az ’abc’ és ”abc” egyaránt használható, sőt egymásba is ágyazható. Az utasítások blokkokba szervezhetőek. A blokkokat { és } karakterek határolják. A blokkok tetszőleges szinten egymásba ágyazhatóak, mindegyik szinten tetszőleges számú utasítással.
A JavaScript nyelvi elemei •
Változók és adattípusok
4
A JS azonosítók (változók, objektumok, függvények) alfabetikus karakterrel, vagy _-jellel kezdődnek, a továbbiakban tartalmazhatnak számjegyet is. Az azonosítók eset-érzékenyek, azaz a kis- és nagybetűk különbözőnek tekintendőek. A deklarálást var, vagy let prediktummal lehet kezdeni. A let deklaráció lokális változót hoz létre. A JavaScript dinamikus nyelv, azaz nem kell deklaráláskor feltétlenül meghatározni egy változó adattípusát, és az adattípusok automatikusan konvertálódnak, ahogy az a szkript futása során szükséges. A JS adattípusai: Adattípus Leírás number
Egész, vagy valós (lebegőpontos) szám.
string
Karakterlánc változó. Mivel a JS-ben char-változó nincs, a karakter 1-hosszú string.
boolean
Logikai változó, ami true (igaz) vagy false (hamis) értéket vehet fel. Ha számként használjuk, akkor a true értéke 1, a false értéke pedig 0 lesz. Használható mind formális logikai, mint numerikus kalkulálásra.
undefined
A változó létre lett hozva, de még nem lett hozzárendelve érték.
null
Ez egy speciális adat, ami azt jelzi, hogy a változó nem tartalmaz semmit.
function
Függvényváltozó. Értéknek egy függvényt kaphat.
object
Objektum változó, összetett adattípus. Literál, vagy konstans lehet logikai (Boolean), numerikus vagy string adat, illetve megjegyzés, ezek közül is
// egysoros megjegyzés /* illetve több soros megjegyzés */
Az egész számokat decimális, hexadecimális és oktális formában lehet ábrázolni. A decimális számnál nem használunk vezető nullát. Ha az első számjegy 0, akkor a szám oktális, míg, ha az 0x (0X) –szel kezdődik, akkor hexadecimális. A hexadecimális számokban az ABCDEF számjegyek használata nem eset-érzékeny. A lebegőpontos számok decimálisak. Lehetnek 3.1415 -6.61E27 .1e10 9E-10 alakúak,
azaz tartalmazhatnak +/- előjelet, tizedespontot és az e/E előzi meg a karakterisztikát (szóköz nélkül).
5
A string lehet ’abc’ ”abc” ’lesz közben egy \n sörtörés’ alakúak.
Lehetnek u.n. whitespace, azaz nem ábrázolható karakterek is a stringekben, ezeket \b \f \r \n \\ \" \'
– – –
backspace form feed carriage return new line
módon jelöljük.
A logikai változó true (igaz) vagy false (hamis) értéket vehet fel. Ha számként használjuk, akkor a true értéke 1, a false értéke pedig 0 lesz. Felsorolási típus (enumerated): A nyelvben nincs explicit konstrukció felsorolási típusra, de szimulálhatóak objektum-literálokkal. Például: var szinek = {piros: 0, zöld: 1, kék: 2}; var a_szin = Colors.piros;
(Ékezetes betűt inkább ne használjunk!) Konstanst, azaz olyan „változót”, amely a szkript lefutása során nem változtatja az értékét az alábbi módon definiálhatunk: const pi = '3.1415';
Tömb Az elemi értékekből tömbök állíthatóak össze, és a tömb bármely eleme lehet tetszőleges típusú, azaz egy tömbben többféle típusú adat is előfordulhat. Tömbök létrehozása: a. Konstruktor hívás, opcionálisan paraméterként átadva:
a
kezdő
tömbméret
var longVector = new Array(100); // 100 elemű tömb var shortVector = new Array(); // 0 elemű tömb, ua., mint var shortVector = [];
b. Konstruktor hívás, a tömb elemei paraméterként átadva var evens = new Array(2,4,6,8);
6
c. Tömbliterál létrehozása, az elemek "[" és "]" között felsorolva var odds = [1,3,5,7];
d. Generátor használata ("Array comprehensions") function range(start, end) { for (let i = start; i < end; ++i) { yield i; } } var tiz_negyzet = [i * i for each (i in range(0, 10))]; var paros_negyzet = [i * i for each (i in range(0, 21)) if (i % 2 == 0)];
A tömb elemei hivatkozhatóak, indexszel (0,1,2 .. ), illetve hivatkozható az egész tömbre egyszerre is a tömb nevével. A tömb hosszát a length tulajdonság mutatja. A tömb nem minden elemének kell értéket adni, így a NewArray = [, "második elem", , "negyedik elem"];
deklarációval létrehozott tömb első és harmadik eleme undefined lesz, amíg nem kap értéket. A JS nem támogat többdimenziós tömböket, helyette a tömbök tömbje használandó: var twoDim = [ [11,12], [21,22] ];
Asszociatív tömb A tömbök indexelésére pozitív egészek helyett stringek is használhatóak. Ekkor használható a . operátor az egyes tömbelemek eléréséhez, például: var myArray = new Array(); myArray["a"] = 100; myArray["c"] = 200; myArray["a"] == myArray.a == 100
Valójában ilyenkor az "a" nevű tulajdonságra lehet hivatkozni. A tömb használata Veremként A push(), tömb végére tesz be egy elemet, és pop() elvesz onnan egyet. A verem többi jellemző művelete a tömb hosszának és az indexelésnek a használatával oldható meg.
7
A tömb használata Sorként A shift() függvény eldobja, tömbelejéről, az unshift() beszúrja a tömb elejére a paraméternek megfelelő számú elemet. Rekord A deklarálás itt is az elemek { és } közötti felsorolásával történik Az elemeknél előbb az azonosítót, majd az értéket kell megadni. A téves kulccsal (azonosítóval, vagy indexszel-) történő hivatkozás a tömb hivatkozással ellentétben nem undefined értékhez, hanem hibához vezet. A következő példában a rekord egy literált, egy függvényt és egy változót tartalmaz: var valt1; function fv1 { // fv1_visszateresi_erteke } precord = { a: "szöveg", b: fv1, 7: valt1; } // ekkor például a következő hivatkozások érvényesek: precord.a, precord.b, precord[7] // viszont ezek hibához vezetnek: precord[a], precord[0], precord.7
A rekordok a tömbökhöz hasonlóan egymásba ágyazhatóak, azaz struktúrák hozhatóak létre: rrecord = { a: { a: "p1", 2: "p2" } , 3: "k3" } // ekkor a helyes hibatkozások: rrecord.a.a, rrecord.a[2], rrecord[3]
A JS általános változóinak globális tulajdonságai tulajdonság Infinity NaN undefined •
leírás Pozitív/negatív végtelen (pl. 0-val való osztás eredménye) "Not-a-Number" azaz nem szám A változóhoz (még) nem rendeltek értéket.
Kifejezések és operátorok A kifejezés literálok, változók, operátorok és utasítások kombinációja, amely kiértékelése egyetlen értéket eredményez.
8
A JS kifejezéseinek értékei: Aritmetikai: szám String: stringet Logikai: igaz vagy hamis érték Operátorok Értékadási operátor (=) Az értékadás a hagyományos, illetve a C-hez, illetve Java-hoz hasonlóan bal-, illetve jobboldali operandusokkal végzett változata is elfogadott. Például az x*=y ugyanaz, mint az x=x*y. Az egyelőség előtti műveleti jel megismétli a baloldali operandust a jobb oldalon. A jobb oldali operandus változás értéke a műveletben attól függ, hogy a műveleti jel előtte, vagy utána szerepel. Példa: y=5; z=2; x=y+z;
hagyományos módon az x értéke 7 lesz. Nézzük, milyen esetek fordulhatnak még elő: operátor + * / % ++
úgy az alábbiak lesznek a kifejezések értékei: = +=
x=y x+=y
x=x+y
9
x=5 x=15
-= *= /= %=
x-=y x*=y x/=y x%=y
x=x-y x=x*y x=x/y x=x%y
x=5 x=50 x=2 x=0
Összehasonlítás Az összehasonlítások eredménye igaz, vagy hamis logikai érték. Ha csak az értéket kell megvizsgálni (==), a JS önmagától összehasonlítható alakba konvertálja az operandusokat, míg alaposabb esetben a típust is egyezteti (===). Aritmetikai inkrementáció (++), dekrementáció (--), negálás (logikai, illetve aritmetikai változónál) (-), valamint modulus (%) Bitenkénti műveletek A bitenkénti operátor az operandusokat 32 bites számokként kezelik. AND OR XOR NOT Bal léptetés Előjel-megőrző léptetés
a & b a a ~ a
jobb a
Nulla-feltöltő jobb léptetés a
bitenkénti ÉS kiértékelés | b bitenkénti VAGY kiértékelés ^ b bitenkénti KIZÁRÓ VAGY kiértélés a bitenkénti negálás << b a baloldal felé lépteti a b-vel lépteti a bitjeit, a jobboldalon 0-k lépnek be >> b a jobboldal felé b-vel lépteti a bitjeit, a baloldalon 0-k lépnek be, az előjel bit megmarad >>> b a jobboldali felé b-vel lépteti a bitjeit, a baloldalon 0-k lépnek be
Logikai Rövid (lusta) kiértékelést használ, azaz ha balról jobbra haladva biztosra vehető az eredmény, nem számol tovább. Operátorok: ! (negálás) && és || vagy
10
String A stringekre az összehasonlító operátorokon kívül a konkatenáció operátort (+) is lehet használni. Ez az operátor két stringet összekapcsol és a két operandus uniójaként tér vissza. A rövidített értékadó operátort (+=) itt is használható. Különleges operátorok (ami a fentiekbe nem illik) o
feltételes kiértékelés (a ? b : c): a logikai értékétől függően b-t, vagy c-t adja, pl: túlsúlyos = (bmi >= 30) ? "igen" : "nem”
o o o o o o o o
,: tömbelemek felsorolása delete: objektumtörlése in: objektum bejárása instanceof: objektum típusának lekérdezése new: új objektum létrehozása this: saját objektum typeof: objektum típusának lekérdezése void: kifejezés kiértékelése visszatérési érték nélkül
Az operátorok precedenciája:
•
1. hivás,tag: () [] . 2. negáció/növelés: ! ~ - ++ -3. szorzás/osztás: * / % 4. összeadás/kivonás: + 5. eltoló (shift): << >> >>> 6. viszony: < <= > >= 7. egyenlőség: == != === 8. bitenkénti és: & 9. bitenkénti kizáró vagy: ^ 10. bitenkénti vagy: | 11. logikai és: && 12. logikai vagy: || 13. feltételes ?: 14. értékadó: = += -= *= /= %= <<= >>= >>>=&= ^= |= 15. vessző: , Elágazások Címke A vezérlési szerkezetek fontos eleme, a label (címke) itt is használatos, elsősorban a continue és a break töréspontok adják át ide a vezérlést a
11
program normál folyamatából. Mindez persze csak egyetlen függvényen belül érvényes, a JS programkódja önmagában nem képez összefüggő szerkezetet a <script> blokkon belül. 4 Ha-akkor-egyébként Az if-then-else (elseif) szerkezet gyakorlatilag minden programozási nyelvben, így a JS-ben is működik. (A JS a then szavacskát megspórolja, de attól még ugyanúgy működik). Amennyiben az if után (zárójelek között) megadott logikai kijezeés értéke igaz, a { } között leírt blokk hajtódik végre. Ha van else-ág, akkor ellenkező esetben az, különben az if-blokk utáni parancsok. Abban az esetben, ha több, mint két eset lehet, egyenként felsorolhatóak, kiértékelhetőek a feltételek, vagy tömörebb megoldás az else if használata, bár a hatékonyság szempontjából semmivel sem jobb, mint az előző. Példa, amikor egy függvény kiértékelésének három eredménye is érdekes lehet: var a = someFunction(b, c); if ( a <= 1) { alert("Sajnos nem sikerült!"); } else if (a == 5 ) { alert("Gratulálok, kiváló!"); } else { alert("Sikeres vizsga!"); }
Többirányú elágazás Amennyiben sok, és nemcsak logikai lehet a kifejezés értékelhető kimeneteinek száma, az if-ek ismételgetése, vagy egymásba ágyazása eléggé megbonyolíthatja az olvashatóságot és a szerkezetet5. A switch éppen erre való: ha több kimenetele lehet egy kifejezésnek, amely azonban nem csak logikai, de tetszőleges értéket vehet fel, az egyes értékek esetén külön-külön programblokk futtatható. Ezeket a case direktívák azonosítják. Az itt használatos programblokkok annyiban különböznek a megszokottaktól, hogy itt nem használunk "{" illetve "}" 4
Megjegyzem, hogy Assembly szinten valójában csak a címke-ugrás művelet létezik, az összes többi (ciklus, elágazás) csak magasabb szinten konstruált absztrakció. Magasabb szintű nyelvek esetén azért kerülik a közvetlen vezérlés átadást (azaz a goto utasítás használatát), mert a programozó kivételesen durva kárt képes okozni, amennyiben nem megfelelően használja. 5
Az olvashatóság alapvető! Ne feledjük: egyszer írunk egy programot, de talán százszor kell módosítanunk!
12
jeleket a blokkok azonosításához, ezt a case jelek megteszik. Amennyiben egyik érték (címke) sem felel meg a kifejezésnek, akkor írhatunk egy alapértelmezett (default) viselkedést, hasonlóan az if parancs else ágának megfelelően. Amennyiben nincs ilyen ág, a program a az if-blokk utáni utasításon folytatódik. Ha bármelyik blokk ráfut a break parancsra, ugyanez történik. Példa: switch (gyümölcs) { case ’alma”: utasítások; break; case ’körte’: utasítások; break; case ’dinnye’: utasítások; break; default: utasítások; }
Például, ha egy gyümölcsöt adunk el webzöldségesnél, átadhatjuk az elágazásnak a kiválasztott gyümölcsnevet paraméterként: switch (expr) { case "Alma": document.write("Alma 400 Ft/kg."); break; case "Körte": document.write("Körte 450 Ft/kg."); break; case "Dinnye": document.write("Dinnye 650 Ft/kg."); break; default: document.write("Bocsi, kifogytunk ebből: " + expr); }
•
Ciklusok A ciklusok esetén, nagyon sok nyelvhez hasonlóan megtalálhatóak az előre meghatározott, valamint a feltételes ciklusok is. A feltételes ciklusok esetén az elől-tesztelő és hátul-tesztelő ciklus egyaránt használatos a JS-ben. A ciklusmagoknak nincs terjedelmi korlátja, tetszőleges számú utasításokból (blokkokból) állhatnak A ciklusfeltétel logikai kifejezés, vagy ennek aritmetikailag logikai megfelelője (0, azaz false, illetve nem 0 ) lehet. For ciklus Az elől-tesztelő for addig ismétli a ciklusmagot, amíg a feltétel igazzá nem válik. Működéséhez három paraméter kell, inicializálás, inkrementálás és ciklusfeltétel. Az inicializálásban megadható egy, vagy több értékadás, akár olyan is, amelyek a későbbiekben ciklusváltozóként is használhatóak. A ciklusváltozó – hasonlóan más programnyelvekhez nem csak egyesével, hanem tetszőleges léptékben növelhető. A ciklusfeltétel lehet valamilyen határ, vagy logikai kifejezés is.
for ( inicializálás, ciklusfeltétel, inkrementálás ) { ciklusmag }
13
Ettől nagyszerűbb, hogy a for each...in ciklus egy objektumváltozó értékeire is hivatkozhat a programkód tulajdonságainak Például: var sum = 0; var obj = {t1: 5, t2: 13, t3: 8}; for each (var item in obj) { sum += item; } print(sum); // az eredmény "26", ami 5+13+8
While ciklus Az elöl-tesztelő ciklus először a feltételt ellenőrzi, majd ennek teljesülése esetén végrehajta a ciklusmagban foglalt parancsokat. Ennek teljesítése után úrja ellenőrzi a feltételt és kezdi elölről a (megváltozott paraméterek melletti) ciklust. Ezek szerint ez a ciklus a ciklusmagot (legalább egyszer) csak akkor hajtja végre, ha a feltétel igaz, azaz lehetséges, hogy ez egyszer sem történik meg. while ( feltétel ) { ciklusmag }
Egy példa 10! kiszámítására: var x = 1; var faktorialis = 1; while { x<=10) { faktorialis*= x; x++; }
Do...while ciklus A hátul-tesztelő ciklusban mindenképpen lefut egy ciklusmag, majd ellenőrzi ciklusfeltételt. Ha a feltétel igaz, akkor ismét lefuttatja a ciklusmagot. do { ciklusmag } while ( feltétel )
Egy másik példa 10! kiszámítására: var x = 0; var faktorialis = 1; do { x++; faktorialis*= x; } while ( x <= 10 );
Vezérlésátadó utasítások A végtelen ciklusok elkerülése a break és continue utasítások használatával válik elkerülhetővé a JS-ben. Míg a break kilép a
14
ciklusmagból és azután folytatja a program végrehajtását, a continue6 a ciklus elejéről kezdi a megváltozott környezetnek megfelelően (új esély). Hibakezelés, kivétel-kezelés Ahogy minden programnyelvben, a JS-ben is megoldották a hibakezelést, vagy kivételkezelést. Erre a try-catch-finally trió szolgál. A try utáni blokk a program normál futása esetére szól, a catch egy paraméterben átveszi a hibát, így kezelhetővé, feldolgozhatóvá válik. A finally blokk minden esetben lefut, akár volt hiba, akár nem: try { // Futó program rész } catch (error) { // Hiba esetén lefuttatott rész } finally { // Minden esetben lefutó program rész }
Időnként nem elégszünk meg azzal, hogy a böngésző döntse el mi a hiba, mi magunk is generálhatunk, erre szolgál a throw metódus: a try blokkban generálunk egy hibát, amit majd a catch kezel. A throw eldobja, a catch elkapja a kivételt/hibát7. Ez a megoldás kiváló pl. a funkciógomb lenyomása, mint kivétel kezelésére. <script type="text/javascript"> function checkAge() { try { /* ha nem megengedett értéket vinnénk be, hibaüzenet generálódik */ if (document.forms[”eletkor”].kor.value > 99) { throw RangeError; } } catch (e) { // elkapja és kiíratja a dobott hibát if (e.name=RangeError) alert("Szép kor, gratulálunk!"); } }
6 7
A jó öreg Fortran visszainteget Ügyvitelszervezők: ugyanezt a filozófiát alkalmazzák az üzleti modellezésben, ld. pl. BizAgi Process Modeler.
15
Egyébként, miután a JS mostanára alapértelemezett szkriptnyelvvé vált a böngészők számára, tulajdonképpen elegendő a <script> …
jelölés is. Hibák típusai • • • • • •
•
EvalError - Az eval() funkció helytelen használata RangeError – Egy szám meghaladja a korlátját ReferenceError - Helytelen hivatkozás SyntaxError - Szintaktikai hiba TypeError - A változó típusa nem létezik URIError – Az encodeURI() vagy decodeURI() funkciót függvények helytelen használata Függvények A JS egyetlen alprogramot ismer, a függvényt. Amennyiben a függvénynek nincs visszatérési értéke, eljárásként viselkedik. Hogy minél kevesebbet kelljen gépelni, a függvény deklarálásakor minden kihagyható, ami nélkül is egyértelmű a programozói szándék: a visszatérési érték opcionális, a bementi paramétereknek elegendő a nevét megadni, a típusára nincs szükség. Egyszerű példa annak eldöntésére, hogy két szám, logikai változó, vagy string közül melyik a kisebb:
function min(a, b) { return a < b ? a : b ; }
Mindig a function kifejezéssel kell kezdeni, azután a függvény neve után a bemeneti paraméterek felsorolása következik. A visszatérési értéket a return utasítás adja. Amennyiben nincs bemeneti paraméter, visszaadott érték, abban az esetben a function f1() { // utasítások }
alak tökéletesen megfelel. A függvény meghívásához elegendő egyszerűen megadni a nevüket. Bemeneti paraméter lehet bármilyen változó, vagy objektum, így függvény (merthogy, az is objektum) is. Az
16
objektum a JS-ben valójában egy névvel, vagyis hivatkozási alappal és tulajdonságokkal ellátott valami. Arguments A függvényhez tartozik egy arguments nevű tömb, amely a függvény végrehajtása során elérhető és kiolvasható. Ez nagyon hasznos pl. olyankor, amikor a függvény deklarálásakor leginkább akkor hasznos, ha nem tudjuk a függvény deklarálásakor még nem ismert a bemeneti paraméterek száma: function osszefuz(elvalaszto) { var kimenet = ""; for (var i=1; i< arguments.length; i++) { // arguments.length a bementi paraméterek száma kimenet = kimenet + arguments[i] + elvalaszto; } return kimenet; } osszefuz("-", "össze", "fűzött", "string", "készült"); // kimenet: össze-fűzött-string-készült
Fontos, hogy az argumentumlista indexelése itt is 0-val kezdődik! Az ellenkező véglet, amikor több bemeneti paraméter lett deklarálva a függvény számára, mint ami a híváskor meg lett adva. Ilyenkor a meg nem adott paraméterek értéke egyszerűen undefined lesz, ugyanakkor ez semmilyen problémát nem okoz a függvény lelkivilágának. Kezelhető ez a kérdés alapértelmezett paraméter értékekkel: function kivagy(arg0, arg1){ arg1 = arg1 || "Senki"; // itt ”Senki” a default érték return arg0+” ”+arg1; } Nev=kivagy(”Nevem”); // Nev: Nevem Senki
A függvény saját magát is meghívhatja (rekurzív hívás). Jó példa erre a egy egész szám faktoriálisának kiszámolása. function faktorialis(n) { if ( n==0 || n==1 ) return 1; else { var eredmeny = ( n * faktorialis(n-1) ); return eredmeny; }
17
} faktorialis(5); eredmény 120
//
ekkor
4
rekurzív
hívás
után,
az
A JS globális és speciális függvényeit és eljárásait érdemes a http://www.w3schools.com/jsref/jsref_obj_global.asp oldalon tanulmányozni.
A HTML és a JavaScript összekapcsolása A JavaScript erőssége a HTML-lel való harmonikus együttműködés - a bépített függvényeket, vezérlési szerkezeteket más nyelvek is tudják. A JS a HTML-lel ellentétben - megkülönbözteti a kis- és nagybetűket, erre mindenképpen oda kell figyelni! A JS a HTML-hez az egyes objektumok tulajdonságai révén kapcsolódik. A HTML-objektumok észlelnek eseményeket, amelyek aktiválnak metódusokat – a JS esetében függvényeket. Innen pedig nincs megállás, hiszen a függvény újabb függvényt hívhat, deklarálhat változót, műveleteket végezhet rajtuk, stb. Az események beköveztekor a hozzájuk rendelt függvényt a futtató környezet, azaz a böngésző által támogatott eljárásokat, függvényeket használja. A JavaScript a következő módszerekkel használható a HTML dokumentumon belül: A <script> tagba beírva a kódot: <script> function f1() { alert('Meghívták az f1-függvényt!'); }
Egy másik példa, amikor az oldal teljes betöltődéséről fontos információt kapni, mert valamely eseményt ehhez kell időzíteni (a túl sok objektumot tartalmazó oldal esetén fontos lehet):
18
<script> function betoltve() { alert("A lap végre betöltődött!"); }
Szép napunk van!
Ugyanez az esemény JS függvényen belül a window.onload=fv()