You are on page 1of 294

Informatika „tankönyv”

Gál Zoltán

2006. január 25.


Előszó
Ez a dokumentum nem igazi tankönyv. Több okból sem tekinthető tankönyvnek.
Egyrészt azért nem tankönyv, mert – egyenlőre – még nem tartalmaz minden témakört, amely az Informatika tantárgy
követelményrendszerében szerepel. Az egyes témakörökkel folyamatosan fog bővülni a könyv, amelynek a mindenkori
legfrissebb változatát a kiskunfélegyházi Móra Ferenc Gimnázium honlapján lehet megtalálni a
http ://szerver3.moragimi.sulinet.hu/downloads/jegyzet.pdf címen.
Másrészt ez a könyv olyan témaköröket is tartalmaz, amelyek nem szerepelnek az Informatika tantárgy érettségi
követelményei között, bár ismeretük hasznos lehet bárki számára, aki az informatikai ismereteket munkája során használni
kívánja. Mivel jelenleg a – felháborítóan alacsony – kötelező óraszám miatt ezeknek megtanítására informatika órán nincs
lehetőség, hiszen jelenleg még arra sem feltétlenül van idő, hogy amit az érettségin tudni kell, azt a megfelelő mélységig
meg lehessen tanítani, így amíg ezek a témakörök nem válnak a hivatalos tananyag részévé, addig másképpen nem lehet a
diákokkal ezeket az informatikai eszközöket megismertetni. Ugyanakkor bizonyos, az érettségi követelményrendszerben
szereplő eszközöknél hasznosabb lehet ezek ismerete.
Hogy az érettségin mégsem szerepel ez, annak egyik legszomorúbb oka, hogy az érettségi követelményeinek össze-
állítói sem ismerik ezeket az eszközöket, így nem csoda, hogy a korszerű eszközök helyett elavult technológiát kell a
diákoknak az érettségin használniuk. Talán, ha ezeket az eszközöket ilyen módon mégis sikerül megismertetni a diákok-
kal, akkor van esély rá, hogy a jövőben mégis lehetségessé válik ezek tanítása is a rendes tananyag keretei között.
Azoknál a témaköröknél is, amelyek szerepelnek a hivatalos tananyagban, sokkal mélyebb ismereteket is igényel-
hetnek azok, akik az informatikával komolyabban foglalkozni szeretnének. Így e könyvben megpróbálom a szereplő
témakörökben a legteljesebb információt nyújtani – amely miatt viszont más témakörökre sokáig nem lesz időm.
A könyv azért sem tekinthető tankönyvnek, mert egy nagyon fontos feltételnek nem felel meg a tankönyv feltételei
közül : sem tematikailag nem igazodik az iskolai 45 perces órákra bontáshoz, sem pedig gyakorló feladatokat nem tar-
talmaz. Inkább egy háttérinformációkkal alaposan megtömött referenciakönyvnek lehet tekinteni, amely minden olyan
témakört szeretne felölelni – valószínűleg nem fog sikerülni teljesen –, amelyet érdemes ismernie annak, aki a későbbi-
ekben informatikával kíván foglalkozni, és nem csupán a bizonyítvány miatt akar informatikából érettségizni. . .
Fontos tudni : a gimnázium honlapján található többi oktatási anyaghoz hasonlóan erre is érvényesek az ott feltün-
tetett szerzői jogi korlátozások. Ez így szól: Minden a Móra Ferenc Gimnázium oktatási webszerverén elérhető
dokumentum az azt elkészítő szerző és a Móra Ferenc Gimnázium tulajdona. A gimnázium diákjai (akár nappali,
akár felnőtt képzésben vesznek részt) tanulmányaikhoz az anyagokat szabadon felhasználhatják. Harmadik sze-
mély részére való továbbadásához a dokumentum szerzőjének engedélye szükséges. Bármely más módon történő
publikálás csak a szerző írásbeli engedélyének birtokában lehetséges.

i
Tartalomjegyzék

Első rész: Weboldalkészítés — Alapok 1


1. A hipertext dokumentumok 2
1.1. Weboldal készítését segítő programok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2. A weboldal általános szerkezete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2.1. A HTML nyelv szerkezete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2.2. A stíluslapok szerkezete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2.3. További alapfogalmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.3. A jó weboldal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.3.1. Válasszuk külön a weboldal szerkezetét és megjelenését ! . . . . . . . . . . . . . . . . . . . . . . 7
1.3.2. Általános elérhetőségre törekedjünk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.3.3. Segítsünk a böngészőknek a megjelenítésben . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.4. Rövid bevezető az SGML-be . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.4.1. Elemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.4.2. Paraméterek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.4.3. Karakterreferenciák . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.4.4. Megjegyzések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.4.5. A HTML DTD értelmezése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.4.6. Alapvető HTML típusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2. Egy egyszerű weboldal 16


2.1. A verzió megadása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.2. Fejléc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.2.1. A dokumentum címe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.2.2. Metaadatok megadása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.2.3. Metaadat-profilok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.2.4. A dokumentum kódolása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.2.5. Karakterreferenciák . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.2.6. Csatlakozó referenciák . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.3. A dokumentum törzse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.3.1. Elemazonosításra szolgáló paraméterek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.3.2. Blokk- és szövegszintű elemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.3.3. A dokumentum szakaszokra bontása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.3.4. Az ADDRESS elem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

ii
3. Stíluslapok használata 31
3.1. A stíluslapok megadásának lehetőségei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.2. A stíluslap szerkezete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3.3. Hogyan dolgozza fel a böngésző a stíluslapot ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.3.1. A „vászon” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.4. Szelektorok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.4.1. Univerzális szelektor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.4.2. Elem (típus) szelektorok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.4.3. Leszármazott elemre mutató szelektor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.4.4. „Gyermek” megadása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.4.5. Közvetlen szomszédok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.4.6. Elem paraméterei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.4.7. Osztályozó szelektor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.4.8. Egyedi azonosítók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.4.9. Pszeudo elemek és pszeudo osztályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.5. Tulajdonságok lehetséges értékei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.5.1. Számok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.5.2. Hosszmérték . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.5.3. Százalékok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.5.4. Címek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.5.5. Színek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

4. Szöveg megadására szolgáló elemek 40


4.1. Szóköznek számító jelek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
4.2. Struktúrált szöveg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
4.3. Idézetek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
4.3.1. Idézőjelek beállítása a stíluslap segítségével . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
4.4. Alsó és felső index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
4.5. Bekezdések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
4.6. A szöveg formázása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.6.1. Betűtulajdonságok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.6.2. Betűméret beállítása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
4.6.3. A betűformázások egyszeri megadása, a font tulajdonság . . . . . . . . . . . . . . . . . . . . . . 51
4.6.4. A sor magassága . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.6.5. Az első sor behúzása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.6.6. A bekezdés igazítása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
4.6.7. Szövegdekorációk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
4.6.8. Betűköz és szóköz beállítása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
4.6.9. Kisbetű, nagybetű . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
4.6.10. A tördelés szabályozása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
4.7. Szövegváltozások jelzése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

5. A weboldal megjelenítése 60
5.1. A doboz modell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
5.1.1. A dobozok méretei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
5.1.2. A margókra vonatkozó tulajdonságok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
5.1.3. A belső margó tulajdonságai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
5.1.4. A keret tulajdonságai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
5.2. A szöveg és a háttér színére vonatkozó tulajdonságok . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
5.2.1. A szöveg színe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

iii
5.2.2. A háttér beállítása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
5.3. A doboz méretei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

6. Listaelemek és formázásuk 72
6.1. Számozott, számozatlan lista és a listaelem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
6.2. Definíciós listák . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
6.3. A listák megjelenése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

7. Hivatkozások 78
7.1. A link fogalma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
7.2. Az egységes címzési rendszer felépítése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
7.3. Hivatkozás és célpont létrehozása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
7.3.1. A célpont-azonosítóra vonatkozó szabályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
7.3.2. Célpont létrehozása id paraméterrel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
7.3.3. A LINK elem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
7.4. Az alapértelmezett URI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
7.5. A hivatkozások megjelenése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

8. Képek és egyéb külső objektumok beillesztése 85


8.1. Képek beillesztése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
8.2. Általános objektum beillesztés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
8.3. Képek formázása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
8.3.1. Képek keretezése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
8.3.2. Képek mérete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

9. A vizuális megjelenés modellje 93


9.1. A dobozok típusai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
9.1.1. Blokk-szintű dobozok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
9.1.2. Szöveg-szintű dobozok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
9.1.3. Kompakt dobozok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
9.1.4. „run-in” dobozok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
9.1.5. A display tulajdonság . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
9.2. A pozícionálási lehetőségek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
9.3. Úsztatás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
9.4. Lapokra bomló megjelenítés (nyomtatás) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
9.4.1. Oldalmargók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
9.4.2. Oldalvágás-jelek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
9.4.3. Oldalfajták . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
9.4.4. Oldaltörések szabályozása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103

10. Táblázatok készítése 105


10.1. A táblázat létrehozásához szükséges elemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
10.1.1. A táblázat létrehozása: a TABLE elem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
10.1.2. Táblázat címének megadása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
10.1.3. Sorok csoportosítása, fejléc és lábléc a táblázatban . . . . . . . . . . . . . . . . . . . . . . . . . 107
10.1.4. Oszlopok csoportosítása és előzetes formázása . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
10.1.5. A táblázat sorai: a TR elem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
10.1.6. A táblázat cellái: a TH és a TD elem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
10.2. A táblázatok megjelenésének szabályozása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
10.2.1. A táblázat címének pozícionálása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

iv
10.2.2. A táblázat belső elemei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
10.3. A táblázat keretei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
10.3.1. A „separate” modell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
10.3.2. A „collapse” modell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
10.3.3. A keretek stílusával kapcsolatos megjegyzések . . . . . . . . . . . . . . . . . . . . . . . . . . . 122

11. Több weboldal megjelenítése egyszerre: keretek alkalmazása 123


11.1. Keretek definiálása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
11.1.1. A sorokra és oszlopokra osztás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
11.1.2. Adatmegosztás a keretek között . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
11.1.3. A keretek leírása: a FRAME elem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
11.2. Hivatkozás a keretre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
11.3. Mikor a böngésző nem jeleníti meg a kereteket . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
11.4. Dokumentum beágyazása másik dokumentumba kerettel . . . . . . . . . . . . . . . . . . . . . . . . . . 129

Második rész : Weboldalkészítés haladó szinten 131


12. A JavaScript programozási nyelv 132
12.1. A nyelv alapjai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
12.1.1. A JavaScript nyelv kialakulása, feladata és fejlődése . . . . . . . . . . . . . . . . . . . . . . . . 132
12.1.2. A JavaScript beillesztése a weboldalba . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
12.1.3. Egy egyszerű példa JavaScript programra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
12.2. A JavaScript nyelv szabályai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
12.2.1. Adattípusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
12.2.2. Változók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
12.2.3. Megjegyzések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
12.2.4. Kifejezések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
12.2.5. A JavaScript utasításai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
12.2.6. Függvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
12.2.7. Objektumok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
12.2.8. Tömbök . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
12.2.9. Dátumkezelés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
12.2.10.Matematikai eszközök . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
12.2.11.Megyjegyzések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
12.3. Alapvető algoritmusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
12.3.1. Adott elem keresése tömbben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
12.3.2. Keresés intervallumfelezéssel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
12.3.3. Legkisebb és legnagyobb elem megkeresése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
12.3.4. Rendezések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149

13. Interaktív weboldalak készítése 155


13.1. A Document Object Model (DOM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
13.1.1. A böngészőablakhoz kapcsolódó objektumok . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
13.1.2. A dokumentum objektumai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
13.1.3. A meglátogatott oldalak története . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
13.1.4. Location . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
13.2. Események és eseménykezelők . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
13.2.1. Az eseménykezelők létrehozása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
13.2.2. Eseménykezelők módosítása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159

v
13.2.3. Billentyűzet-események . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
13.2.4. További események . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
13.3. Ablakok kezelése JavaScript-tel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
13.3.1. Ablak nyitása és bezárása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
13.3.2. Ablak mozgatása és átméretezése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
13.3.3. Párbeszédablakok megjelenítése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
13.3.4. Keretek kezelése JavaScript-ben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
13.3.5. Időzített tevékenységek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
13.4. HTML elem beazonosítása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
13.4.1. A DOM: Document Object Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
13.4.2. Az egyes csomópontok elérése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
13.5. Stílus módosítása JavaScript-ben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
13.5.1. Elemek helyzetének és méretének befolyásolása . . . . . . . . . . . . . . . . . . . . . . . . . . 167
13.5.2. Az objektumok átfedésének szabályozása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
13.5.3. Példa a stílus változtatásra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171

14. Egyéb HTML lehetőségek 178


14.1. Űrlapok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
14.1.1. A FORM elem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
14.1.2. Beviteli mezők: INPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
14.1.3. Button: általános célú gomb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
14.1.4. Kapcsolók: checkbox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
14.1.5. Állományfeltöltés: FileUpload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
14.1.6. Rejtett adatmezők: hidden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
14.1.7. Legördülő lista készítése: Select . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
14.1.8. Szövegbeviteli mező: Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
14.1.9. Jelszó beírása: Password . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
14.1.10.Választógombok: Radio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
14.1.11.Többsoros szövegablak: Textarea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
14.1.12.Alaphelyzetbe hozás: Reset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
14.1.13.Az űrlap lezárása, elküldése: Submit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
14.1.14.Címkék készítése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
14.1.15.Az űrlapok szervezése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
14.1.16.Az űrlapok használata JavaScript-ben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
14.2. Képtérképek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
14.2.1. A képtérkép létrehozásához szükséges HTML elemek . . . . . . . . . . . . . . . . . . . . . . . 195

Harmadik rész : Adatbáziskezelés 199


15. Elméleti alapok 200
15.1. Alapfogalmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
15.1.1. A tranzakció fogalma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
15.2. Adatmodellezés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
15.2.1. Mire figyeljünk a tervezés során ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
15.3. Az egyed-kapcsolat modell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
15.3.1. Kapcsolatok fajtái . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
15.3.2. Egyedhalmazok több szerepben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
15.3.3. Kapcsolat attribútumai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
15.3.4. Alosztályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208

vi
15.3.5. Megszorítások . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
15.3.6. Gyenge egyedhalmazok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
15.4. A relációs adatmodell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
15.4.1. Az egyed-kapcsolat modell átalakítása relációsémákká . . . . . . . . . . . . . . . . . . . . . . . 214
15.5. Példa az adatbázis tervezésre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217

16. Az SQL nyelv 218


16.1. Az SQL alapvető szintaxisa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219

17. Adatdefiníciós utasítások 221


17.1. Adattáblák létrehozása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
17.1.1. Pár szó az adattáblákról általában . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
17.1.2. A CREATE TABLE utasítás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
17.1.3. Az oszlopok lehetséges típusai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
17.1.4. Alapértelmezett mezőértékek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
17.1.5. Feltételek megadása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
17.1.6. Az ALTER TABLE utasítás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
17.2. Egyéb adatbázis objektumok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236

18. Adatmanipulációs utasítások 237


18.1. Adatfelvitel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
18.2. Adatok módosítása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
18.3. Törlés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240

19. Lekérdezések 241


19.1. A SELECT utasításról általában . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
19.2. Egyszerű lekérdezések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
19.2.1. A SELECT záradék elemei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
19.2.2. A WHERE záradék használata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
19.2.3. Az eredmény rendezése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
19.3. Lekérdezések több táblával . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
19.3.1. A Descartes-szorzat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
19.3.2. A Descartes-szorzat megvalósítása a lekérdezésekben . . . . . . . . . . . . . . . . . . . . . . . . 248
19.3.3. A FROM záradék . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
19.3.4. Unió, metszet és különbség megvalósítása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
19.4. Alkérdések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
19.4.1. Skalár értéked adó lekérdezések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
19.4.2. Relációkat tartalmazó alkérdések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
19.4.3. Korrelált alkérdések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
19.5. Halmazok és multihalmazok különbsége . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
19.6. Összesítések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
19.6.1. Csoportosítás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257

Negyedik rész : Dinamikus weboldalak készítése 260


20. A PHP nyelv 262
20.1. A PHP szintaxisa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
20.1.1. A PHP scriptet jelölő szimbólumok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
20.1.2. A PHP és a JavaScript szintaxisának összehasonlítása . . . . . . . . . . . . . . . . . . . . . . . . 263

vii
20.1.3. Vezérlési szerkezetek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
20.1.4. Függvények használata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
20.2. További információk a PHP nyelvről . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274

21. Űrlapok feldolgozása PHP-vel 275


21.1. A GET metódus által generált URL szerkezete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
21.2. Az értékek elérése a PHP-scriptben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
21.3. Állományfeltöltés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
21.3.1. Több állomány egyidejű feltöltése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
21.3.2. Feltöltés a PUT metódussal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279

22. Adatbáziskezelés PHP-n keresztül 281


22.1. Csatlakozás és kapcsolatbontás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
22.2. SQL-kérés küldése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
22.3. Egy példa a PHP-n keresztüli adatbáziskezelésre : bolti árukészlet . . . . . . . . . . . . . . . . . . . . . 284

viii
Első rész

Weboldalkészítés — Alapok

1
1. fejezet

A hipertext dokumentumok

Manapság egyre fontosabb szerepet játszik az információszerzésben az internet, és annak legelterjedtebb szolgáltatása, a
WWW, vagyis a World Wide Web. Ez az angol kifejezés magyarra értelmesen nem fordítható le. Valójában itt egy olyan
típusú adatszolgáltatásról van szó, ahol szöveges dokumentumokat olvashatunk ; amelyek azonban a szöveges információn
kívül egyre többféle más formátumú anyagot is magukban foglalhatnak.
Ilyen egyéb formátum lehet a kép, hanganyag, mozgókép, vagy valamilyen program, amelyen keresztül például egy
adatbázishoz lehet hozzáférni, vagy valamilyen árut lehet rendelni. Ezek a hivatkozások lehetővé teszik, hogy a hivatko-
zott dokumentumot azonnal le is töltsük az internetről, és elolvassuk, vagy megnézzük, meghallgassuk.
Az ilyen dokumentumokat nevezik szaknyelven hipertextnek, ami azt jelenti, hogy szövegen (text) kívül egyéb objek-
tumok is találhatóak benne, és más dokumentumokkal is kapcsolatban állhat. Éppen ezek gyors népszerűvé válása teszi
szükségessé, hogy az emberek már az iskolából kikerülve is ismerjék az ilyen dokumentumok előállításának módját is,
ne csak a már létező dokumentumokhoz tudjanak hozzáférni.
Egy hipertext dokumentum több állományból is állhat, amelyek speciális formában tárolják azokat az információkat,
amelyeket a dokumentummal készítője mások számára elérhetővé szeretne tenni. Ezen állományok feldolgozásával állítja
azután a dokumentumot megjelenítő program (egy böngésző) elő azt a dokumentumot, amit ténylegesen látunk. Ezt az
utóbbit nevezzük weboldalnak.
Tehát a weboldal és a hipertext kifejezések nagyjából azonos jelentésűek. A mögöttük rejlő állományok pedig a
különböző formában tárolt információtól függően egyéb elnevezéssel is rendelkeznek. Vegyük röviden sorra ezeket :

HTML Hypertext Markup Language, azaz hipertext-leíró nyelv a neve annak nyelvnek, amelyen a weboldal tartalma,
logikai felépítése van megadva. Ezt nevezhetjük emiatt HTML-dokumentumnak is. Sokan úgy gondolják – és nem
kevesen másoknak is így tanítják –, hogy ez azonos a weboldallal, holott ez csupán az egyik, bár nagyon fontos
eleme a weboldalnak, hiszen ez tartalmazza a weboldal szövegét.
Ezek a HTML-állományok tehát szöveges állományok, amelyek a weboldal tartalmát, és szerkezetét adják meg
(ezért is nevezik Markup, azaz leíró nyelvnek).
CSS stíluslapok, amelyek definiálják a weboldal kinézetét, megjelenési stílusát. Ez is szöveges állomány, amit egyszerű
szövegszerkesztővel lehet szerkeszteni. Ezek a weboldalon szereplő objektumok formázására vonatkozó utasításo-
kat tartalmazzák. Bár általában önálló állományban célszerű elhelyezni, mert akkor több weboldalhoz is alkalmaz-
ható, elhelyezhető a HTML-dokumentumban is.
JavaScript olyan programozási nyelv, amely kifejezetten a weboldalak interaktívvá tételére készült. A C/C++ progra-
mozási nyelv mintájára, annak jelentős egyszerűsítésével keletkezett. Segítségével a böngészőt utasítani lehet a
felhasználó bizonyos akcióira való reagálásra, vagy attól függetlenül egyszerű műveletek végrehajtására. Általában
a HTML-kódba építik bele a JavaScript kódját.

2
Szerver oldali scriptek olyan programok, amelyeket a webszerver dolgoz fel, majd a feldolgozás eredményeként egy
HTML-kódot generál, amelyet, mint HTML-dokumentumot küld el a böngészőnek. Segítségükkel dinamikus web-
oldalak hozhatók lére. Jellemző programozási nyelv a Perl vagy újabban a PHP ; mindkettő a C/C++ nyelvre jelen-
tősen hasonlító programozási nyelv.
Egyéb erőforrások csatolhatók a weboldalhoz: képek, hanganyagok, animációk stb.

Ebben a részben a HTML és a CSS nyelv megismerése a cél, míg későbbi fejezetekben a JavaScript és a PHP hasz-
nálata is szerepelni fog.

1.1. Weboldal készítését segítő programok


A HTML-dokumentumok tehát valójában egyszerű szöveges állományok, amelyek tartalma a HTML nyelv szabályainak
megfelelő szöveg. Ez azt jelenti, hogy egy weboldal elkészítéséhez elegendő egy egyszerű szövegszerkesztő, és a HTML
– illetve CSS – nyelv szabályainak ismerete. Ezek elsajátítását teszik lehetővé majd a következő fejezetek.
Azonban léteznek olyan szoftverek, amelyek arra hivatottak, hogy megkönnyítsék a weboldalak előállítását. Ezek két
különböző kategóriába sorolhatóak akár aszerint, hogy mennyire használhatóak, akár a weboldal elkészítéséhez biztosí-
tott felületük alapján. (Sajnos a legtöbb szoftvernél a két csoportosítási szempont szerint nincs különbség. . . ) Az egyik
kategória a weblap-készítő, a másik a HTML-szerkesztő.
A weblap-készítő szoftverek használatára sajnos az interneten rengeteg példát lehet látni : Rengeteg weboldalon lát-
szik, hogy készítője nem ismeri a HTML nyelvet, csak fogott egy WYSIWYG rendszerű webszerkesztőt, néhány kat-
tintással összedobott valamit, amit nem szégyellt mások számára elérhetővé tenni. Persze az ilyen weboldal a készítőjét
minősíti, de ha igazán igényes akar lenni az ember, akkor célszerű tökéletes munkát kiadni a kezéből. Erre pedig az ilyen
WYSIWYG webszerkesztők ritkán képesek. Ha pedig a forráskódba való belenyúlást nem engedik, akkor kizárt, hogy
jó minőségű dokumentumokat lehessen velük készíteni, ugyanis ezek a programok a legritkább esetben felelnek meg a
szabványoknak.1
A HTML-szerkesztők sem felelnek meg tökéletesen a szabványoknak, azonban ezek esetében a weboldal forráskód-
ját tudjuk közvetlenül szerkeszteni, így ha maga a program el is térne a szabványtól, aki a szabványt ismeri, az gond
nélkül felülbírálhatja a program megoldását. Persze attól, hogy a forráskódot szerkeszthetjük, a program még kínál esz-
közöket a gyorsabb munkához például beszúrható elemek paramétereinek párbeszédablakon keresztül való megadásával
vagy a kép méreteinek automatikus megvizsgálásával. Ezenfelül a jobb HTML-szerkesztők a weboldal megjelenését is
megmutathatját kérésre.
A következő felsorolás korántsem teljes, de tartalmaz néhány hasznos szoftvert – elsősorban UNIX/Linux környezet-
ben elérhetőeket.
MS Frontpage lásd a lábjegyzetet. . . Kizárólag Windows alatt érhető el, kifejezetten Internet Explorer-hez optimalizált,
nagyon ronda forráskódú weboldalt állít elő. Használata minőségi munka esetén kerülendő.
Mozilla A Mozilla ugyan böngészőprogram, de van webszerkesztő része is, amely aránylag szabványos, de néha nagyon
nehezen átlátható forráskódot előállító WYSIWYG szerkesztő. A szerkesztés során át lehet állítani az üzemmó-
dot olyanra, hogy a forráskódot lássuk, azonban a forráskódból mentéskor automatikusan visszalép a WYSIWYG
üzemmódba, ráadásul hiába bíráljuk felül a generált kódot, azt újra átírja a saját, néha bizony elég hibás kódjára.
Előnye azonban például az előbbivel szemben, hogy már ismeri – és alkalmazza is – a stíluslapokat, és azokhoz a
1 Különösen igaz ez a MS Frontpage-re, amely kifejezetten arra alkalmas, hogy az Internet Explorer-ben való megjelnésre optimalizált dokumentu-

mokat készítsenek vele. Azonban jelenleg a böngészők közül éppen az Internet Explorer tartalmazza a legtöbb szabványt sértő, sőt egyenesen semmibe
vevő megoldásokat: sok szabványos weboldalt hibásan jelenít meg, az Internet Explorerre optimalizált oldalakat pedig a többi, szabványosan működő
böngésző jeleníti meg hibásan. Ha belegondolunk, hogy a világon használatos operációs rendszerek közül az egyetlen, amin elérhető, a Windows, akkor
ebből következik, hogy az Internet Explorerre optimalizált oldalakkal a felhasználók többségét zárjuk el a dokumentumaink helyes megjelenítésének
lehetőségétől. Alapszabályként célszerű megjegyezni: mindig olyan weboldalt készítsünk, amely a szabványnak teljesen megfelel, mert így garantált a
legtöbb böngészőn a helyes megjelenítés.

3
feladatokhoz, amelyek nem valódi weboldalak készítésére, hanem például az érettségin megkövetelt feladat elké-
szítésére irányul, tökéletesen megfelel a tudása. Mivel a Mozilla gyakorlatilag minden grafikus felületű operációs
rendszeren elérhető, ezért bármely operációs rendszeren használható.
Quanta A KDE2 saját HTML-szerkesztője. A forráskód szerkesztését különböző eszköztárakkal segíti, amelyek gya-
korlatilag a WYSIWYG szövegszerkesztőknél megszokott kényelmet jelentik annak hátrányai nélkül. A legújabb
változata már arra is képes, hogy a weboldal kinézetét ne csak megnézhessük, hanem akár azon is szerkeszthetünk.
Akár párhuzamosan használhatjuk a két felületet, és miközben az egyiket szerkesztjük, a másik időről időre követi
a változásokat.3 A Quanta legújabb változata ráadásul immár képes a stíluslapokat is kezelni, így azok szerkesztése
is kényelmessé vált.
BlueFish Egy másik Linuxos HTML-szerkesztő, amely még nem olyan fejlett, mint a Quanta, de még a Quanta előtt
képes volt a stíluslapok létrehozására. A Quanta korábbi változatai esetén ajánlatosabb volt a stíluslapot a BlueFish-
sel megszerkeszteni, míg a HTML-oldalakat a Quanta tudta jobban kezelni.
OpenOffice, MS Word Használatuk kerülendő, mert valójában csak a saját szöveges dokumentumaik weboldal formá-
tumban való mentését ismerik, és ez a mentés bizony nagyon áttekinthetetlen, rosszul felépített forráskódot hoz
létre. Az így készült weboldalak messziről felismerhetők a rossz formázási megoldásokról, amelyek egy szöveges
dokumentumban természetesek, a weboldalaktól azonban idegenek. Ha Word vagy OpenOffice formátumú szö-
veget akarunk felhasználni weboldalon, akkor inkább sima szöveges formátumba mentsük el a szöveget, és azt
felhasználva alkossuk meg a weboldalt például a Quantában vagy a Mozillával. Másik megoldás ha PDF formá-
tumba konvertáljuk a szöveget, és változtatás nélkül elhelyezzük a weben. (Az OpenOffice közvetlenül tud menteni
PDF formátumba.)

1.2. A weboldal általános szerkezete


A weboldal, mint említettük, több részből áll. A középpontban mindenképpen maga a HTML-dokumentumot tartalmazó
állomány áll, mivel ez írja le a weboldal tartalmát. Minden olyan további állományt, amelyre a weboldal megjelenítéséhez
szükség van (vagy szükség lehet), a HTML kód ad meg.
Maga a HTML-dokumentum logikailag két részre osztható :
1. Az első része a dokumentumnak a böngésző számára tartalmaz információkat.
• Itt kell megadni, hogy a dokumentum a HTML nyelv melyik változatának előírásai szerint értelmezendő.
• Ebben kell megadni a külső állományban található, a weboldal formázását megadó információkat tároló stí-
luslapo(ka)t.
• Itt adható meg a dokumentum megjelenítéséhez használandó kódkészlet és a dokumentum készítésének nyel-
ve.
• Itt adhatók meg olyan információk, amelyek az internetes keresők munkáját segítik a dokumentum kategori-
zálásánál: szerző, témakör kulcsszavai.
• Az interaktív elemek leírására használt nyelvet, illetve az ehhez szükséges kezdeti tevékenységek megadására
is ez a rész használható.
A weboldal ezen részét nevezzük a weboldal fejlécének.
2. A további rész tartalmazza a megjelenítendő objektumok leírását, vagyis a weboldal tartalmát. Ezt a részt nevezzük
a weboldal törzsének.
2 KDE: K Desktop Environment, a Linux-hoz fejlesztett egyik legelterjedtebb (és legnagyobb erőforrásigényű) ablakkezelő rendszer, amely a Linux

mellett UNIX-on is elérhető. . .


3 Tapasztalatom szerint ez veszélyes lehet, mert a folyamatos újraolvasás nem csupán időigényes lehet, de valamilyen hibás programrész miatt akár

el is szálhat tőle a program, a mentetlen változtatások teljes elvesztése mellett, ezért érdemes ezt a szolgáltatást egyenlőre nagyon óvatosan használni !

4
1.2.1. A HTML nyelv szerkezete
A HTML valójában az SGML egy alkalmazása. Az SGML a Standard Generalized Markup Language, amelyet elsősorban
más nyelvek definiálására használnak. A HTML szabvány is az SGML-t használja a nyelv pontos definiálására. Ebben
a dokumentumban a teljesség kedvéért ezek a definíciók is szerepelnek (az értelmezésüket lásd egy későbbi fejezetben),
azonban a fő célnak ez a leírási mód nem felel meg, így a lehető legtöbb magyarázat fog szerepelni minden egyes elemnél.
A weboldalkészítés elsajátításának azonban az egyetlen járható útja a sok gyakorlás: minél több weboldalt készít az ember
(forráskódban), annál jobban megismerheti a nyelvet.
A HTML nyelv alapvetően objektumokra bontja a weboldalt, mint dokumentumot. Minden objektumhoz a HTML
kódban egy elem tartozik.4 Az elem általában három részből áll, amelyek közül az első rész minden elem esetén létezik,
míg a másik kettő bizonyos elemek esetében hiányzik :
1. Nyitótag : egy < után az elem neve, amelyet egymástól (és az elem nevétől) szóközzel elválasztva az attribútumai –
magyarul paraméterei – követhetnek. Amennyiben van paraméter, annak értéke a paraméter neve utáni egyenlőség-
jel utáni szimpla vagy dupla idézőjelek között, számérték esetén esetleg idézőjelek nélkül adandó meg. A nyitótagot
minden esetben a > jel zárja. Például a következő két sor egy-egy helyes nyitótagot mutat :

<p>
<a href="http://www.valaki.hu">

2. Tartalom : az elem tartalma lehet – az elemtől függően – szöveg, vagy más elem(ek), vagy ezek tetszőleges kombi-
nációja.
3. Zárótag : az elem tartalmának végét jelző, a nyitótagra hasonlító szimbólum. A </ jelekkel kezdődik, amit az elem
neve, majd a > jel követ (sehol nem lehet benne szóköz!). A fentebb szereplő két elemre egy egy teljes példa :

<p>Ez itt egy bekezdés szövege.</p>


<a href="http://www.valaki.hu">Itt pedig valakire hivatkozunk...</a>

A HTML nyelv pontos leírása megtalálható (angolul) a [1]-ben.

1.2.2. A stíluslapok szerkezete


A stíluslap szabályok sorozatából áll, amely szabályok mindegyike a weboldal egyes elemeinek megjelenését szabályozza.
Ennek megfelelően egy szabály két részből áll:
1. Szelektor : meghatározza azokat az elemeket, amelyre a szabály érvényes.
2. A szelektor utáni kapcsos zárójel tartalmazza pontosvesszővel elválasztva a tulajdonságokat, amelyeknek az értékét
be kell állítani. Minden tulajdonságra szerepel a neve, majd egy kettőspont után a tulajdonság értéke.
Elképzelhető, hogy több szabály szelektorába is beleesik valamely elem. Ebben az a szabály lesz alkalmazva az
elemre, amelyik utoljára szerepel a stíluslapon. Emiatt célszerű a stíluslapot úgy felépíteni, hogy először az általános,
sok elemre vonatkozó értékeket állítjuk be, majd külön, percízebb szelektort alkalmazó szabállyal a speciálisabb eseteket
lehet megadni.
A szelektorok pontos fajtáit, és a stíluslap alkalmazását majd a későbbiekben vesszük sorra, amikor már több ismere-
tünk lesz a weboldalon használható elemekről, és azok struktúrájáról.
A stíluslapok pontos ismertetése megtalálható a [2]-ben.
4 Sok HTML készítéssel foglalkozó tankönyv az elemeket a tag névvel illeti, amely már régen hibás fordításnak számít.

5
1.2.3. További alapfogalmak

1. Erőforrások
A World Wide Web (Web) tulajdonképpen nem más, mint információs erőforrások – a weboldalkészítésről szóló fejeze-
tekben a továbbiakban röviden erőforrások – hálózata. Ahhoz, hogy ezekhez az erőforrásokhoz hozzá lehessen férni,
a Web három eljárást használ fel:
1. Egységes elnevezési rendszert az erőforrásoknak a Weben való megtalálásához. Ezt nevezik URInak (lásd kicsit
később. . . ).
2. Az erőforrásokhoz hozzáférést biztosító protokollok (a protokoll fogalmát lásd a hálózatoknál (??. fejezet)), a mi
esetünkben elsősorban a HTTP, azaz a HypertText Transfer Protocol.
3. A hiperszöveg, amellyel az erőforrások között navigálni lehet.

2. Az URI
Minden a Weben található erőforrás – legyen az HTML dokumentum, kép, videoklip (akár egész filmnyi), program
vagy bármi egyéb – rendelkezik egy teljesen egyedi címmel, amelyet az Univerzális Erőforrás Azonosító, angolul
Universal Resource Identifier, rövidítve URI ad meg. Az az URI alapvetően a következő három részből áll :
1. A protokoll megnevezése, amelyen keresztül az erőforrást el lehet érni.
2. Az erőforrást szolgáltató gép neve.
3. Magának az erőforrásnak a neve az elérési útvonalával együtt.

Íme egy példa az URI-ra:


http://moragimi.sulinet.hu/index.html
A fenti cím első része, a protokollt meghatározó így néz ki : http://. Ez azt jelenti, hogy a HTTP protokoll hasz-
nálatával lehet elérni az erőforrást (ami tehát egy weboldal). A második rész : moragimi.sulinet.hu/, azt mondja,
hogy a HTTP protokollal a moragimi.sulinet.hu nevű gépet kell megszólítani, annak webszerverén található a kért erőfor-
rás. A harmadik rész, amely magát az erőforrást azonosítja a gépen belül a példában a index.html, azt jelenti, hogy
a webszerver által használt könyvtárfa gyökerében levő index.html nevű állományt keressük. Ennél persze sokkal bonyo-
lultabb is lehet egy URI által megadott cím, ha az erőforrás nem a webszerver dokumentumkönyvtárának gyökerében
található.
Másik példa:

mailto:valaki@valahol.com
Ebben az esetben az első rész a mailto:, azt jelenti, hogy levelet lehet küldeni az utána álló címre – feltéve, hogy a
böngésző tudja, hogy milyen programot és hogyan indítson el ebből a célból.
Az URI részletesebb ismertetésére majd még visszatérünk a hivatkozások ismertetésénél. Most egyenlőre elégedjünk
meg ennyivel.

6
1.3. A jó weboldal
Hogyan készítsünk jó weboldalakat? Persze erre többen többféle választ adnának kapásból, azonban ha igazán megfelelő
weboldalakat akarunk készíteni, akkor – túl azon, hogy megfelelő eszközöket (pl. Quanta és nem MS Frontpage. . . )
használunk – fogadjuk meg a HTML-szabványban megfogalmazott tanácsokat :

1.3.1. Válasszuk külön a weboldal szerkezetét és megjelenését!


A HTML nyelv a weboldal tartalmát és szerkezetét hivatott leírni. Igaz ugyan, hogy a korábbi verziókból még – a ré-
gebben készült weboldalak használhatóságának megőrzése céljából – megmaradtak azok a nyelvi elemek, amelyekkel
befolyásolni lehet a weboldal kinézetét, azonban ezek használatát kerüljük !5
Amennyiben ezt a tanácsot valaki megfogadja, akkor egy már elkészült weboldalt sokkal könnyebben tud majd más
megjelenítő eszközre adaptálni, hiszen elég lesz elkészíteni az új megjelenéshez szükséges stíluslapot, és már lehet is
nyomtatni, felolvastatni a weboldalt.
Másik előnye az elkülönítésnek a sok weboldalból álló (általában ez a valós helyzet) dokumentumok készítésénél
érződik, hiszen ekkor nem kell minden weboldalon külön újra és újra beállítani a háttérszínt, a szövegszínt stb. : egyszer
el kell készíteni a stíluslapot, és minden weboldal ezt használja. Képzeljük el, ha van több száz weboldalunk egyforma
színösszeállítással, és a megrendelőnek az a kívánsága, hogy a fekete hátteret változtassuk meg sötétzöldre ! Ha a webol-
dalban van megadva a háttérszín, mehetünk végig a több száz állományon. Ha viszont stíluslapban : egyetlen állomány
egyetlen során kell csak módosítani, és máris kész. . . ! Ugye, mekkora különbség !

1.3.2. Általános elérhetőségre törekedjünk


Ez ma már nem csupán azt jelenti, hogy minden böngészőn egyformán jelenjen meg. Ez a szabvány használata esetén
már majdnem tökéletesen lehetséges: ha az Internet Explorer végre eltűnne, vagy szabványossá válna, nem lenne ezzel
többé gond. Ha eleve nem foglalkozunk az Internet Explorerrel, a probléma már nem probléma többé.
Van azonban egy másik nézőpontja is a kérdésnek : Manapság egy weboldalt már nem csak a böngészőprogramok ké-
pesek megjeleníteni. Egyre jobban terjednek azok a mobiltelefonok (van még egyáltalán olyan, amely ezt nem tudja. . . ?),
amelyekkel lehet az interneten böngészni. Azonban egy mobiltelefon képernyőjén nem fér el egy akkora dokumentum,
mint a számítógép képernyőjén. A WAP egy más megjelenítő eszköz, amely a weboldalakat a mobiltelefon képernyőjére
igazítva jeleníti meg. A legtöbb weboldal esetében más stíluslapot kell megadni ehhez. Még nagyobb probléma lehet
olyan weboldalat készíteni, amelyet a vakok illetve a gyengénlátók is használhatnak egy szövegfelolvasó rendszer segít-
ségével. Ebben az esetben a problémát úgy lehet megoldani, ha a felolvasást lehetővé tevő és szabályozó elemeket építünk
a weboldalba.
Persze egy átlagos weboldal nem valószínű, hogy megfelel minden feltételnek, de az elvárható mindenkitől, aki we-
boldalakat készít, hogy gondolja végig, hogy amit csinál, az milyen formában lesz elérhető. Az esetleges nyomtatásra
szánt változat, például mindenképpen egy meggondolandó alternatív megjelenés lehet. Ha másra nem is, legalább arra
gondoljunk, hogy egy weboldal kinyomtatásánál a menüt nem szeretnénk látni, de a sorok végeit sem szeretnénk, ha a
nyomtató lehagyná, mert az előre formázás miatt nem fér el a lapon. . .
Alapvető dolog ebből a szempontból, hogy a dokumentumaink tartalmazzák az információt, hogy milyen nyelven író-
dott a dokumentum, és milyen karakterkészletet használva kell azt megjeleníteni. Ennek fontosságát mutatja a következő :
a latin-1 kódkészletben õ szerepel ott, ahol a latin-2 kódkészletében ő, és ugyanígy ha latin-2 helyett latin-1 kódkészlettel
jeleníti meg a weboldalunkat a böngésző, akkor ű helyett û fog megjelenni a szövegben !
5 Kivétel ez alól, ha például az érettségi során olyan feladatot kapnak a vizsgázók, amelynek szövege pontosan ezeknek az elavult eszközöknek a

használatát írja elő. Erre sajnos nem elegendő azt mondani, hogy miért nem tanulja meg a HTML nyelvet rendesen, aki a feladatokat kitalálja, ha a
feladat az elavult eszközök használata, hát használjuk azt. Azonban valódi, az interneten közzéteendő weboldalak esetében semmi esetre se használjuk
már ezeket!

7
1.3.3. Segítsünk a böngészőknek a megjelenítésben
Vannak olyan böngészők, amelyek nem képesek a már kirajzolt elemek mozgatására a képernyőn, ezért amíg nem ismerik
egy-egy elem méreteit, addig inkább nem jelenítik meg. A régebbi Netscape-ek voltak például olyanok, amelyek képesek
voltak akár egy órát is várni (lassú hálózat esetén), mielőtt bármit is megjelenítettek volna, aztán egyszercsak végleg
úgymaradtak. Ennek oka az volt, hogy a weboldal készítője a szöveget a margók beállítása helyett táblázat cellájába tette.
A böngésző nem tudta, milyen széles lesz a táblázat, ezért addig várt a megjelenítéssel, amíg az egész meg nem érkezett.
A memóriában összegyűlt szöveg alapján azután utólag próbálta a táblázat méretét kiszámolni a megjelenítéshez. Ha
azonban a memória kevésnek bizonyult ehhez, akkor abból a felhasználó csak azt vette észre, hogy már nem mozog a
töltést jelző jel, de még mindig üres a képernyő, sőt a program sem reagál semmire – mivel már régen lefagyott.
Ennek elkerülésére célszerű a táblázatokat (de néhány más elemet is) úgy megadni, hogy már az elején kiderüljenek a
méretei. Főleg a táblázat oszlopainál lényeges, hogy az oszlopszélességek ismertek legyenek a betöltés kezdeténél is. Így
a böngésző képes a teljes tartalom megérkezése előtt is megjeleníteni a már megérkezett tartalmat. (Más kérdés, hogy a
táblázat alkalmazása formázási megoldásra inkább kerülendő. . . )

1.4. Rövid bevezető az SGML-be


Bár a HTML nyelv ismeretéhez nem szükséges az SGML ismerete, most mégis – igaz, nagyon röviden – következik
egy ismertető az SGML egy részéről. Ennek oka az, hogy így az egyes HTML szabályoknak a szabványban szereplő
(SGML-ben megadott) definícióját könnyebb lesz értelmezni, amely lehetővé teszi, hogy ne kelljen mindent túl részlete-
sen elmondani minden HTML elem esetén.
Az SGML egy rendszer a leíró nyelvek definiálásához. Rengeteg leíró nyelv létezik, amely tehát a dokumentum
tartalmának, szerkezeti felépítésének megadását szolgálja. Ezek közül csupán az egyik a HTML. További példa leíró
nyelvre az XML vagy a LATEX. Minden leíró nyelv, amit az SGML-ben definiáltak, nevezhető SGML-alkalmazásnak. Egy
SGML-alkalmazás általában meghatározott a következő elemekkel :
1. Egy SGML-deklaráció határozza meg, mely karakterek és elválasztójelek szerepelhetnek az adott alkalmazásban.
Ez a mi esetünkre lefordítva: megadja azokat a karaktereket és speciális célú szimbólumokat, amelyeket a HTML
dokumentumban alkalmazhatunk.
2. Egy dokumentum típus definíció (document type definition : DTD): A DTD definiálja a nyelv szintaxisát (vagyis a
HTML nyelv nyelvtani szabályait). A DTD tartalmazhat további definíciókat, mint például a karakterreferenciákat.
3. Egy leírást, amely megadja az egyes nyelvi elemek jelentését (szemantikáját). Ez tartalmazhat további szintaktikai
megkötéséket, amelyek a DTD-ben nem adhatóak meg.
4. Dokumentumok, melyek tartalmazzák az adatokat (dokumentumtartalmat) és a leíró elemeket. Ez tulajdonképpen
maga a HTML dokumentum a mi esetünkben. Minden ilyen dokumentum az elején tartalmaz egy referenciát arra
a DTD-re, amelyben megadott szabályoknak a dokumentum megfelel.
Tulajdonképpen bennünket az SGML annyiban érdekel, hogy a DTD az SGML segítségével definiálja a HTML nyelv
szintaxisát. Ha tehát ismerjük az SGML-t, akkor a DTD-t értelmezni tudjuk, ami lehetővé teszi a nyelv szabályainak
megismerését további magyarázatok nélkül is. Lássunk hozzá!

1.4.1. Elemek
Egy SGML DTD deklarál elemtípusokat, amelyek a szerkezetet vagy az elvárt viselkedést írják le. A HTML olyan elem-
típusokat használ, mint a bekezdés, hiperhivatkozás, lista, táblázat, kép, stb. Mint már említettük, minden elem áll egy
nyitótagból, egy tartalomból és egy zárótagból. Nos, az elemtípus deklaráció általában ezt a három részt írja le.
Az elem neve szerepel a nyitó és a zárótagban (a zárótagban egy perjel után). Bizonyos HTML elemek lehetővé teszik
a zárótag elhagyását. Néhány elem esetén a nyitótag hagyható el – vagy akár egyszerre a nyitó- és a zárótag is. A DTD-nek
lehetővé kell tennie ennek feltüntetését is.

8
Egyes HTML elemeknek nincs tartalmuk. Például a sortörést előíró BR elemnek nincs tartalma, hiszen egyetlen
feladata megmondani a böngészőnek, hogy kezdjen új sort a szövegben. Az ilyen üres elemeknek soha nincs zárótagjuk.
A DTD megadja, hogy egy elemnek van-e tartalma, és ha igen, akkor az mi lehet.
Az elemek neve méretfüggetlen: a kisbetűvel írt elemnév és a nagybetűvel írt elemnév jelentésben megegyezik, épp-
úgy mint a vegyesen kis és nagybetűkkel írt elemnév : IMG, img és ImG ugyanazt az elemet jelenti.
Az elemeknek mindig egymásba ágyazottnak kell lenniük. Ez azt jelenti, hogy nem fordulhat elő olyan, hogy egy elem
nyitótagja egy másik elem belsejében van, míg zárótagja annak a másik elemnek a zárótagja után. Azoknak az elemeknek
az esetében, amelyeknek a zárótagja elhagyható, az elemet tartalmazó elem zárótagja automatikusan a beágyazott elem
végét is fogja jelenteni. Az elemet lezárhatja azonban egy olyan elem nyitótagja is, amely nem ágyazható bele az adott
elembe. Például a bekezdést megadó P elem zárótagja gond nélkül elhagyható abban az esetben, ha egy blokkot megha-
tározó elem jön utána, mivel az új blokk automatikusan lezárja az előző bekezdés blokkját. (A blokkokról még később
bőven szót ejtünk.)
Megjegyzés. Sokan – még az informatika tanárok között is – összekevernek két fogalmat : az elemet és a tagot, ez utóbbit
ráadásul angolosan ejtik („teg”-nek). Az angol nyelvben is megvan azonban e két fogalom különböztetve : element és tag.
Az előbbi a teljes HTML elem, míg a „tag” (akár angolul, akár magyarul beszélünk) az elemnek a nyitó- vagy a zárótagja.
Elképzelhető, hogy az elem nyitó- is zárótagja egyaránt hiányzik – a HEAD elem lehet ilyen –, azonban ettől maga az
elem még szerepel a dokumentumban.

1.4.2. Paraméterek
A paraméterek vagy „külföldiesen” attribútumok az elem egyes tulajdonságait határozzák meg. Minden elemnek egy
maghatározott paraméterhalmaza van, amely mindegyikének van valamilyen értéke még akkor is, ha a dokumentumban ez
nem szerepel. Ha a szerző nem adja meg az értéket, akkor az alapértelmezett értéket kapja. További tulajdonságai lesznek
az elemeknek, amelyeket a stíluslapon kell megadni, de ezekkel most nem foglalkozunk egyenlőre. A paraméterek és
értékeik a nyitótagban annak záró csúcsos zárójele előtt szerepelnek, tetszőleges sorrendben felsorolva.
Az SGML előírja, hogy minden paraméter értékét dupla vagy szimpla idézőjelek közé kell tenni. Hogy kétfajta idéző-
jel használható, az azért hasznos, mert így megadható olyan érték is, amely idézőjelet tartalmaz : ilyenkor a másik idézőjel
használható az egész érték körülhatárolására. Ezeken felül az idézőjeles szövegben numerikus karakterreferenciákat is le-
het használni az egyes karakterek kódjának megadására (lásd : 1.4.3. szakasz), vagy nevesített karakterreferenciákat.
Egyes esetekben az idézőjelek elhagyhatóak. Ez akkor lehetséges, ha a paraméter értéke csak a következő kategóriákba
eső karaktereket tartalmazza:

• az angol ABC kis- és nagybetűit;


• számjegyeket a tízes számrendszerből (0-9) ;
• kötőjel (ASCII kódja 45), pont (46), aláhúzás (95) és kettőspont (58).
Azonban a biztonság kedvéért ekkor is célszerűbb kitenni az idézőjeleket.6
A paraméterek neve – az elemek nevéhez hasonlóan – méretfüggetlen. A paraméterek értéke azonban lehet méretfüg-
gő, hiszen előfordulhat, hogy a megadott szöveg valahol megjelenik, és nem mindegy a betűméret. Általában azonban a
paraméterek értéke is méretfüggetlennek van definiálva, az ettől való eltérést az egyes elemek definíciója tartalmazza.

1.4.3. Karakterreferenciák
A karakterreferenciák szimbólummal, vagy a karakternek a használt kódtáblában érvényes kódjának a megadása révén
megadott karakterek. Olyankor hasznos, ha egy olyan jelet akarunk beírni, amely nem szerepel a billentyűzeten, vagy az
adott karakternek a HTML szintaxisban speciális jelentése van.
6A Quanta használata esetén ha használjuk az automatikus kiegészítést, akkor a program automatikusan kiteszi az idézőjeleket. Hogy a dupla vagy
a szimpla idézőjelet használja, az beállítható.

9
Minden karakterreferencia & jellel kezdődik és ; jellel ér véget, közben pedig sehol sem lehet szóköz. Íme néhány
példa karakterreferenciára:
• &lt; jelenti a más funkciója miatt közvetlenül nem beírható < jelet.
• párja, a > jel így adható meg: &gt;.
• &quot; jelenti a " dupla idézőjelet.
• &#229; decimális kóddal adja meg å jelet.
• &#1048; decimális kóddal – a Unicode kódtábla szerint – a cirill ábécé nagy I betűjét adja.
• &#x6C34; hexadecimális kóddal adja – a Unicode kódtábla szerint – a vizet jelentő kínai betűt.
A karakterreferenciák bővebb ismertetése majd a 24. oldalon szerepel. . .

1.4.4. Megjegyzések
A HTML dokumentumban elhelyezhető megjegyzések a következő szabályt követik :

<!-- ez egy megjegyzés -->


<!-- ez szintúgy,
de ezúttal több sorban elhelyezve -->

A nyitó <! és a tényleges megjegyzéskezdő -- között nem lehet szóköz, de lehet a záró -- és a > között. Ebből az is
következik, hogy a megjegyzésen belül sehol nem fordulhat elő a --, mivel az a megjegyzés végének értelmezhető !

1.4.5. A HTML DTD értelmezése


Ezen rövid – de még nem túl tartalmas – ismertető után lássuk, hogyan is kell a DTD-t értelmezni.

DTD megjegyzések
A DTD-ben a megjegyzések többsorosak is lehetnek. A DTD megjegyzései egy kötőjelpárral kezdődnek : --:
<!ELEMENT PARAM - O EMPTY -- megnevezett tulajdonság érték -->
Itt a megjegyzés a „megnevezett tulajdonság érték” megmagyarázza a PARAM elem típusát.

Paraméter-egyed definíció
A HTML DTD elején rengeteg paraméter-egyed definíciója szerepel. Ezeket a szabvány egészen pontosan parameter
entity definitionnak nevezi, és valójában a későbbiekben valahol szereplő tényleges paraméter-definíciókra utalnak. Ezek
inkább csak azért kellenek, mert a paraméterek többsége több elemnél is használható, és a definiálásuk csak úgy lehet
egyértelmű, ha mindössze egy helyen szerepel.
Egy paraméter-egyed definíciója a <!ENTITY % kulcsszóval kezdődik, amit az egyed neve, majd egy idézőjeles
sztring követ, amely az egyedet kifejti, végül egy záró >. Ezekre azután a megfelelő helyen hivatkozni a paraméter-egyed
nevének egy % utáni megadásával, és a név után egy ; megadásával lehet.
Íme példaként a %fontstyle; egyed definíciója :
<!ENTITY % fontstyle "TT | I | B | BIG | SMALL">
A sztringben további paraméter-egyedek is szerepelhetnek.
A DTD-ben nagyon gyakran fogunk találkozni két paraméter-egyeddel : %block; és &inline;. Ezek a HTML
elemek két alapvető típusát jelölik: a blokk-szintű és a szöveg-szintű elemet.

10
Elem-deklaráció
A HTML DTD legnagyobb része az egyes elemtípusok deklarálását tartalmazza, és azok attribútumait. Ezek a <!ELEMENT
kulcsszóval kezdődnek és a > kulcsszóval érnek véget. Ezek között van megadva :
1. Az elem neve.
2. Az elem nyitó-, illetve zárótagja elhagyható-e. Két kötőjel az elem neve után azt jelzi, hogy mindkettő szükséges.
Egy kötőjel és utána egy „O” jelzi, hogy a zárótag elhagyható. Két „O” betű azt jelzi, hogy mindkét tag elhagyható.
3. Az elem tartalmát, ha az létezik egyáltalán. Egy elem megengedett tartalmát nevezzük tartalom-modellnek. Azokat
az elemeket, melyeknek nincs tartalmuk üres elemeknek nevezzük. Az ilyen üres elemekre a EMPTY kulcsszó utal.
Íme egy példa :
<!ELEMENT UL - - (LI)+>

• Az elem neve UL.


• A két kötőjel azt jelzi, hogy mind a nyitótag (<UL>), mind a zárótag (</UL>) kötelező.
• A tartalom-modell ennél az elemnél azt jelenti, hogy „legalább egy LI elem”. Az alábbiakban következik a tartalom-
modell értelmezéséhez szükséges szabályok ismertetése.

Előbb azonban egy példa az üres elemre, amelynek csak nyitótagja van :
<!ELEMENT IMG - O EMPTY>

A tartalom-modell definíciói A tartalom-modell megadása egy reguláris kifejezéssel történik. Ez megadja, hogy mit
tartalmazhat az elem. Ebben a definíciók a következőket adhatják meg :
• A megengedett vagy a tiltott elemek nevét.
• DTD egyedeket (pl. a LABEL elem a %inline paraméter-egyedet tartalmazza).
• Szöveget, amelyet a dokumentum tartalmaként adhatunk meg. Ezt az SGML #PCDATA nyelvi eleme adja meg. Az
ilyen szöveg tartalmazhat karakterreferenciákat is.
Az esetleges többféle elem megadására szükséges a reguláris kifejezések használata. Ez a következő szintaktikai szabá-
lyokat tartalmazza:
(. . . ) Egy csoport zárójelbe foglalása.
A Az A elemnek elő kell fordulnia a tartalomban, pontosan egyszer.
A+ Az A elemnek egy vagy több alkalommal elő kell fordulnia.
A ? Az A elemnek nulla vagy egy alkalommal kell előfordulnia.
A* Az A elem akárhány alkalommal előfordulhat.
+(A) Az A előfordulhat.
-(A) Az A nem fordulhat elő.
A | B Az A és a B közül pontosan az egyiknek kell előfordulnia.
A,B Az A, majd ezt követően a B elemnek elő kell fordulnia (ebben a sorrendben).

11
A & B Tetszőleges sorrendben ugyan, de A-nak és B-nek is elő kell fordulnia.
Például azt, hogy az A elemben nem fordulhat elő újabb A elem, de ettől eltekintve bármilyen szöveg-szintű elem
előfordulhat, a következőképpen adja meg a szabály :
<!ELEMENT A - - (%inline;)* -(A)>

Paraméter deklarációk
Az <!ATTLIST kulcsszó kezdi a paraméterek (attribútumok) deklarációját, amelyekkel egy adott elem rendelkezhet. A
kulcsszót az elem neve követi, amelynek az attribútumairól szó van, majd az attribútumdefiníciók listája, végül a záró >
következik. Minden attribútum definíciója három részből áll :
1. Az attribútum neve.
2. Az attribútum értékének típusa, vagy a lehetséges értékek felsorolása. Az explicit értékmegadás esetén csak az itt
szereplő értékek lehetnek a paraméter értékei. Ebben az esetben az értékek betűméret-függetlenek.
3. Van-e a paraméternek alapértelmezett értéke (a #IMPLIED kulcsszó esetén), amely esetben az alapértelmezett
értéket a böngészőnek egyértelműen meg kell határoznia (akár örökölt érték is lehet) ; mindig kötelező megadni a
paramétert (a #REQUIRED kulcsszó esetén), vagy rögzített egy bizonyos értékre (#FIXED kulcsszó esetén). Egyes
attribútum definíciók megadják az attribútum alapértelmezett értékét is.
A következő példa a MAP elem számára definiálja a name paramétert, amelynek megadása nem kötelező (nincs
alapértelmezett érték):
<!ATTLIST MAP
name CDATA #IMPLIED
>
Ebben a példában a paraméter értéke CDATA típusú lehet, amely azt jelenti, hogy szöveg, amely karakterreferenciákat is
tartalmazhat.
Mielőtt ténylegesen megkezdenénk az ismerkedést a HTML nyelvvel, a lehetséges értéktípusokat is meg fogjuk is-
merni. . .
Előbb azonban íme néhány példa az attribútumdefiníciókra :
rowspan NUMBER 1 -- az összevont cellák száma egy sorban --
http-equiv NAME #IMPLIED -- HTTP válasz fejléc név --
id ID #IMPLIED -- a dokumentumban egyedi azonosító --
valign (top|middle|bottom|baseline) #IMPLIED
Az első példában a rowspan paraméter típusa szám, alapértelmezett értéke 1. Az opcionális http-equiv értéke NAME
típusú lehet, míg az id típusa ID. A valign esetében viszont a felsorolt értékek szerepelhetnek csak.
Az attribútumdefiníciókban is szerepelhetnek DTD egyedek. Ez lehetővé teszi, hogy a sokszor használt attribútumok
definícióját csak egyszer kelljen megadni:
<!ELEMENT LINK - O EMPTY -- egy média-független link -->
<!ATTLIST LINK
%attrs; -- %coreattrs, %i18n, %events --
charset %Charset; #IMPLIED -- a csatolt erőforrás
karakterkódolása --
href %Uri; #IMPLIED -- a csatolt erőforrás címe --
hreflang %LanguageCode; #IMPLIED -- a nyelv kódja --
type %ContentType; #IMPLIED -- az erőforrás típusa --

12
rel %LinkTypes; #IMPLIED -- előremutató linktípus --
rev %LinkTypes; #IMPLIED -- fordított link típusa --
media %MediaDesc; #IMLPIED -- a megjelnítő média,
aminél használni kell--
>
Értelmezés : A nyitótag kötelező, a tartalom és a zárótag tilos. Az %attrs; jelentése a következő :
<!ENTITY % attrs "%coreattrs; %i18n; %events;">
Ez ebben szereplő %coreattrs; paraméter a következő definíciókat takarja :

<!ENTITY % coreattrs
" id ID #IMPLIED -- a dokumentumban egyedi azonosító --
class CDATA #IMPLIED -- szóközzel elválasztott osztálylista --
style %StyleSheet; #IMPLIED -- stílus-információ --
title %Text; #IMPLIED -- buborékinformáció --
>
Ezek a legtöbb elemnél megadható paraméterekre definiált rövidítések.
Az %URI; definíciója elsőre talán meghökkentő lehet :
<!ENTITY % URI "CDATA"
-- a Uniform Resource Identifier
-->
Vagyis nem ad semmi plusz információt azon felül, hogy átnevezi a szöveget. Az egyetlen haszna, hogy a típusme-
gadás a DTD olvasásakor a paraméter információjáról ad többlet informcációt – ez esetben azt, hogy egy erőforrás címét
kell megadni.
Néhány paraméternek összesen annyi a szerepe, hogy egy kapcsolót kikapcsolt vagy bekapcsolt állapotba hozzon.
Ezek a kétértékű, logikai paraméterek. Megadásuk a nyitótagban azt jelenti, hogy a kapcsoló be van kapcsolva, hiányuk
azt jelenti, hogy ki van kapcsolva. Ezeknek a paramétereknek mindössze egy lehetséges értékük van : maga a paraméter
neve. Az ilyen paraméterek megadásakor az érték el is hagyható, vagy megadható az egyetlen megengedett érték. A
definíciója az ilyen logikai selected paraméternek így néz ki :
selected (selected) #IMPLIED -- option is pre-selected --
Egyes böngészők ezeket a paramétereket csak rövid alakjukban ismerik fel (amikor csak a paraméternév szerepel),
ezért nem csupán kényelmesebb, de ajánlatosabb is a rövid formában használni az ilyen paramétereket.

1.4.6. Alapvető HTML típusok


A következőkben röviden felsoroljuk az egyes alap SGML típusokat, valamint a HTML elemekben illetve paraméterek
értékeként használható szövegrészek típusát, hogy azokra a későbbikben a DTD részletekben hivatkozni lehessen. A
következő felsorolás a típusok DTD-beli definícióját tartalmazza. A CS rövidítés azt jelenti, hogy betűméretre érzékeny
(a és A különböző) típusról van szó (Case Sensitive) ; a CI jelentése Case Insensitive : betűméretre nem érzékeny ; a CN
jelentése : a betűméretnek nincs jelentősége (mert például számadatról van szó).

CDATA karakterek sorozata, amelyben szereplő karakterreferenciákat a böngészőnek fel kell tudnia dolgoznia. A benne
szereplő újsor jeleket és többszörös szóközöket (whitespace) egyetlen szóközre kell cserélni. (CS)

ID, NAME olyan „nevek”, amelyek mindenképpen az angol ábécé betűjével kezdődnek (A-Za-z), és ezt számjegy, angol
ábécébeli betű, kötőjel, aláhúzásjel, kettőspont és pont követheti.

13
IDREF(S) ID-re utaló referenciák, melyek más attribútum értékére mutatnak. Az IDREFS szóközökkel elválasztott listát
jelent.
NUMBER legalább egy számjegyet tartalmaz.
szövegek : rengeteg paraméter vár „olvasható” szöveget : &Text;.
címek : olyan szövegek, amelyek megfelelnek az URI szabályainak : &URI;.
színek : &Color; által megadott paraméterérték színkód megadását várja. Megadható néhány szín az angol nevével,
vagy megadható egy # után hat tizenhatos számrendszerbeli számjeggyel, amelyből az első kettő a piros, a követ-
kező kettő a zöld, az utolsó kettő a kék komponenst adja meg az RGB (additív) színkeverés szerint. Az ezt használó
paraméterek azonban már elavultak, és ezért kerülendőek, a stíluslapon vannak beszédesebb színmegadási módok
is.
hosszértékek : %Pixel; Egész szám, amely a képernyő illetve papír (amin megjelenik a weboldal) képpontjában érten-
dő.
%Length ; Mint az előző, vagy lehet százalékos érték, amely valamihez relatív értéket jelent.
%Multilength ; lehet %Length; vagy relatív hossz, amely azt jelenti, hogy egy egész szám után egy csillag is
szerepel. Ez a variáció a rendelkezésre álló, és több elem között szétosztandó hely egy egységéből annyit
vesz, amennyi a megadott egész szám. Az összes relatív hosszban szereplő egész szám összege az az érték,
ahány részre a felhasználható helyet egyenlő arányban szét kell osztani. Ha a szám „1” lenne, az elhagyható
(egyetlen csillag marad).

tartalom-típus (MIME type) általában erőforrásra mutató hivatkozásoknál szerepel, és az erőforrás típusát adja meg. Jel-
zése %Content-Type;. Például az érték lehet : "text/html", "image/png", "image/gif",
"video/mpeg", "text/css" stb. Mint látható, az első fele a főbb típust, a perjel utáni rész az altípust ad-
ja meg. (CI)
nyelv-kód : %LanguageCode; a dokumentum nyelvének megadására használatos kódokat jelentheti. (CI)

karakterkódolás : %Charset; a dokumentumban használt kódtábla nevének megadására alkalmas. (CI)


egyetlen karakter: %Character; használható karakterreferencia is a megadásához, de a végeredmény minden eset-
ben egyetlen karakter lesz.
dátum : %Datetime;

kapcsolattípus : %LinkTypes; (CI)


médialeíró : %MediaDesc; értéke a következők valamelyike lehet :
screen képernyőn való megjelenítés
tty karakteres képernyőn való megjelenítés
tv televízió-típusú megjelenítés (alacsony felbontás, színmélység, korlátozott görgetési lehetőség stb.)
projection kivetítőre tervezett megjelenítés
handheld kézi megjelentő (kis képernyő, monochrome, bitképes grafika, alacsony sávszélesség).
print nyomtatási változathoz, oldalakra bontottt megjelenítés
braille vakok számára készült megjelenítés braille-írással történő nyomtatásként.
aural beszédszintetizátorral való felolvasás.
all minden, fentebb felsorolt együtt.

14
Valójában a fenti értékek egy vesszővel elválasztott listája is megadható, és a későbbiekben újabb médiák is elér-
hetőek lehetnek, illetve a jelenlegiek paraméterezhetővé válhatnak. (CS)
scriptek : %Script; interaktív elemek beillesztésére alkalmas (pl. JavaScript vagy Python kód beillesztésére).
stílusdefiníciók : %StyleSheet; A STYLE elem tartalmaként vagy a style paraméter értékeként megadható stílussza-
bályok.
keretazonosítók : %FrameTarget; A keretek elnevezése azokra való hivatkozások céljára az angol ábécé betűjével
kezdődő azonosító. Néhány speciális azonosító is megadható, ezeket majd a kereteknél ismertetjük.

15
2. fejezet

Egy egyszerű weboldal

A következőkben – a még nem említett alapvető tudnivalókon felül – egy egyszerű weboldalon keresztül ismerjük meg a
gyakorlatban a weboldal szerkezetét.
Lássunk egy nagyon egyszerű weboldalt:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
<TITLE>Egy egyszerű weboldal</TITLE>
<link rel="Stylesheet" type="text/css" href="style.css">
</HEAD>
<BODY>
<P>Üdv mindenkinek!
</BODY>
</HTML>
Ha ezt az oldalt betöltjük egy böngészőbe, nem sokmindent fogunk látni – ami várható is : A böngésző címsorában
megjelenik az „Egy egyszerű weboldal” szöveg, a weboldalon pedig az „Üdv mindenkinek !” szöveg. Ehhez képest elég
sokat kellett gépelni, hogy ez megjelenjen. . .
Bővebb magyarázat nélkül most vegyük sorra, hogy mit is tartalmaz ez az egyszerű kód. Később ezek mindegyikét
részletesebben is megismerjük majd.

Verzióinformáció Az első sor (a példában a hossza miatt két sorba tördelve látható) a verszióinformációt tartalmazza. Ez
megmondja a böngészőnek, hogy a weboldal pontosan milyen szabályok szerint készült, milyen szabályokat kell a
feldolgozása során alkalmazni. A mi esetünkben ez azt tartalmazza, hogy a weboldal a HTML 4.01 szabványnak
megfelelő, azon belül is a három lehetséges DTD közül a legszűkebb, a „strict” DTD alkalmazása szükséges. A
legtöbb esetben – ha más nincs külön jelezve – a jegyzeten belül ennek a DTD-nek a használatát feltételezzük.
Fejrész A HEAD elem tartalma a dokementum feje. Ebben található a dokumentum címe (TITLE elem), valamint néhány
információ a böngészőnek:
1. Ki a szerző?
2. Milyen kódolást kell alkalmazni a dokumentum megjelenítése során ? (latin-2 jelenleg)
3. Milyen stíluslapot kell a megjelenítéshez használni ?

16
Álljunk meg egy pillanatra! Megadtuk ugyan a stíluslapot, de nem hoztuk létre. Ebben az esetben a böngésző
úgy tekinti, mintha nem is lenne stíluslap, így az alapértelmezett stíluslapot használja, amely az adott böngésző
alapbeállításait tartalmazza. (Bővebb magyarázatot lásd a stíluslapoknál.)
Törzsrész A törzs a BODY elem tartalmát jelenti. Ebben jelenleg egy P elem található, amely egy bekezdést jelent.

A következő alfejezetek az egyes elemek részletesebb ismertetését fogják tartalmazni, a következő fejezet bemutatja
a stíluslap használatát, míg az ezt követő fejezetek mutatják be a további HTML elemeket és a hozzájuk tartozó stílus-
tulajdonságokat.. . .

2.1. A verzió megadása


Korábban, a HTML nyelv SGML-definíciójánál (1.4 fejezet, 8. oldal) már megemlítettük a DTD-t, azaz a dokumentum-
típus definíciót (dokument type definicion), amelyet a szabályosan elkészített HTML dokumentum elején pontosan meg
kell adni. Ezt a megadást nevezzük dokumentumtípus deklarációnak (document type declaration). Tulajdonképpen ebből
fogja tudni a böngésző, hogy a HTML nyelv melyik vátlozata szerint kell értelmezni a HTML dokumentum tartalmát –
és a verzión belül is lehet még variáció.
A HTML 4.01 szabvány három DTD-t tartalmaz. Ezek valamelyikét kell megadni a HTML dokumentum első sorában,
a HTML elem előtt. Ez a három DTD a következő :
1. A szigorú (Strict) DTD minden olyan elemet és paramétert tartalmaz, amely nem számít elavultnak, és nem a
keretekhez tartozik. Az ebbe a DTD-be tartozó dokumentumok első sorának ezt kell tartalmaznia (csak a helyhiány
miatt van két sorba tördelve):

<!DOCTYPE HTML PUBLIC "-//W3C/DTD HTML 4.01//EN"


"http://www.w3.org/TR/html4/strict.dtd">

2. A laza (Transitional) DTD tartalmaz mindent, amit a szigorú, de ezenfelül még azokat az elavult elemeket és
paramétereket is, amelyek a régebbi HTML verziókból maradtak. Használatához a következő sorral kell a doku-
mentumot kezdeni:

<!DOCTYPE HTML PUBLIC "-//W3C/DTD HTML 4.01 Transitional//EN"


"http://www.w3.org/TR/html4/loose.dtd">

3. A keretes (Frameset) DTD a laza DTD-ben levő elemeken és paramétereken felül még azokat is tartalmazza,
amelyek a keretek alkalmazásához szükségesek. Használata a keretet definiáló, vagy a belső keretet tartalmazó
dokumentumoknál szükséges. Ehhez a dokumentum első sorának a következőképpen kell kinéznie :

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"


"http://www.w3.org/TR/html4/frameset.dtd">

A fenti mindhárom deklaráció tartalmazza a DTD internetes címét is, amely lehetővé teszi, hogy a böngésző szükség
esetén letöltse azt. Ez elsősorban a későbbi HTML szabványok bevezetésénél lesz hasznos, hiszen magát a böngészőt is
lehet fejleszteni az új szabályoknak megfelelően mindenféle újratelepítés nélkül.
A verzióinformációt követi a dokumentum teljes további részét magába foglaló HTML elem (3. elemdefiníció).

17
3. A HTML elem

<!ENITIY % html.content "HEAD, BODY">

<!ELEMENT HTML O O (%html.content;) -- document root element -->


<!ATTLIST HTML
%i18n; -- lang, dir --
>

Mint látható, a HTML elem nyitó- és zárótagja egyaránt elhagyható. Ettől azonban maga az elem még szerepel a
dokumentumban. Két lehetséges paramétere a lang (8) és a dir (9). Tulajdonképpen a verzióinformáció kivételével
minden, ami a dokumentumban található, ennek az elemnek a tartalma.

2.2. Fejléc
A fejléc tartalmazza azokat az információkat, amelyek a böngészőnek szólnak. Ezt a HEAD elemben (4. elemdefiníció)
kell elhelyezni. Ezen belül elsősorban a következő információfajták helyezhetőek el :
• A dokumentum címe
• A dokumentum kódolása
• A használandó stíluslap(ok) (lásd a következő fejezetben. . . )
• Egyéb metaadatok.

4. A HEAD elem

<!-- %head.misc; jelentése: "SCRIPT|STYLE|META|LINK|OBJECT"-->


<!ENTITY % head.content "TITLE & BASE?">

<!ELEMENT HEAD O O (%head.content;) + (%head.misc;) -- document head -->


<!ATTLIST HEAD
%i18n; -- lang, dir --
profile %URI; #IMPLIED -- named dictionary of meta info --
>

A HEAD elem tartalmazza azokat az adatokat, amelyek a dokumentumra vonatkozó, a böngészőnek vagy más fel-
dolgozó programnak szóló információk. Ilyen lehet például a dokumentum címe, kulcsszavak, amelyek segíthetnek a
keresőprogramoknak, vagy egyéb olyan metaadatok, amelyek nem a dokumentum tartalmához tartoznak. Ezeket az
adatokat a böngésző nem jeleníti meg – de általában a legtöbbhöz valamilyen formában hozzá lehet férni.
Mint a fenti definícióból látható, három paramétere lehet : lang, dir és profile. Tartalma pedig a következő
elemekből állhat: SCRIPT, STYLE, META, LINK, OBJECT, TITLE és BASE.

18
5. A profile paraméter

A profile paraméter arra szolgál, hogy egy nevesített, külön állományban tárolt metaadat-listát lehessen használni.
Értéke annak az állománynak a címe (URI), amely tartalmazza a metaadat-profilt.

2.2.1. A dokumentum címe


A dokumentum címét a HEAD elemben elhelyezett TITLE elemmel lehet megadni. Ez nem keverendő össze az egyes
elemeknek adható title paraméterrel!

6. A TITLE elem
A TITLE elem nem tekintendő a szöveg részének. Azonban a böngészők megjelenítik az elem tartalmát az ablak
címsorában. Minden dokumentumban pontosan egy TITLE elemet kell megadni, amely más formázó elemet nem,
karakterreferenciát azonban tartalmazhat.

<!ELEMENT TITLE - - (#PCDATA) -(%head.misc;) -- document title -->


<!ATTLIST TITLE %i18n; >

Mint a definícióból látható, a lang és a dir paraméterek megadhatók, amelyek a megjelenítésre használt nyelvhez
adnak útmutatást.

Minden HTML dokumentumban kell lennie TITLE elemnek – azonban a legtöbb böngésző jelenleg még nem akad
fenn az esetleges hiányán. A TITLE elem célja, hogy egy rövid, de kifejező címet adjunk a weboldalunknak. Ez nem csak
arra jó, hogy a böngésző címsorában megjelenjen, hanem arra is, hogy ha valaki a böngészője könyvjelzői közé felveszi
a weboldal címét, akkor a program automatikusan ezt a címet adja a könyvjelzőnek. Emiatt nem célszerű olyan címet
adni, mint a „Bevezető” vagy az „Első fejezet”. Helyette inkább derüljön ki a címből a teljes dokumentum, és az adott
weboldalnak az ezen belüli szerepe egyszerre.
Nagyon sok olyan weboldalt látni az interneten, amelynek minden oldala ugyanazt a címet viseli. Ilyenkor ha egy-
egy oldalt el akarunk tenni a könyvjelzők közé, vagy vissza akarunk lépni a korábban megnézett oldalak valamelyikére,
akkor sok azonos címet látunk, amiből lehetetlen megkeresni azt, amelyikre szükség van. Ezek egy részét persze nem a
gondatlan munka okozza, hanem azok a portál-rendszerek, amelyek az egész portálnak engednek egy címet beállítani, és
minden legenerált oldalnak ezt a címet adják. Persze ez a portálrendszer hibája, amit ki lehetne javítani. . .
A TITLE elem tartalmazhat karakterreferenciákat, de más HTML-elemet nem. Ennek oka érthető : szövegként fog
megjelenni, amit nem lehet már formázni. A karakterreferencia azonban lehetővé teszi, hogy bármely karaktert az elembe
helyezzünk.

2.2.2. Metaadatok megadása


A címen és a weboldal kódolásán (lásd később. . . ) felül további adatok is rendelhetők a dokumentumhoz, amelyek a
dokumentum kísérőadatai. Ezeket a dokumentumhoz rendelt adatokat szokás metaadatoknak nevezni.
Minden dokumentumfajtához léteznek metaadatok. Gondoljunk például a könyvekre : szerző, cím, terjedelem, kiadó,
kiadás ideje stb. ; vagy filmre: rendező, forgatókönyvíró, szereplők, stúdió stb. Ez mind metaadat. Weboldalnál ilyen
metaadat lehet a teljesség igénye nélkül:
szerző A weboldal szerzője.
cím A TITLE elemnél megadott címről van szó.

19
A szerző emilcíme
kulcsszavak A weboldal témáját meghatározó kifejezések, amelyek alapján az egyes internetes keresők téma szerint
kategorizálhatják a weboldalakat. Ezért ha megadunk kulcsszavakat, akkor azok tényleg feleljenek meg a doku-
mentum témájának!
lejárati idő Meddig érvényes a dokumentum tartalma.
Azokat a metaadatokat, amelyek megadására nincs speciális elem (mint amilyen a TITLE), a META elemmel (7. de-
finíció) lehet megadni. Például a szerző nevét így lehet megadni :
<META name="Author" content="sir G.">
Ebben az elemben a name paraméter értéke („Author”) határozza meg a metaadat fajtáját. (Olyan mint egy változódefi-
níció, ahol ez a paraméter adja meg a változó nevét.) A content paraméter értéke pedig a metaadat (a változó) értékét
adja meg.1
Hogy pontosan milyen metaadatok adhatók meg, azt egy profil határozza meg. Ezt a HEAD elem profile paramé-
tere (lásd : 5. definíció) beállításával lehet elérni. A HTML szabvány a metaadatokra nem tartalmaz előírást, így ha profilt
nem használunk, akkor a böngészőtől függ, hogy mely metaadatokat fogadja el, és melyeket nem.
Az alábbi példa nem csupán a szerző nevét adja meg, de azt is, hogy a név a francia nyelv szabályai szerint ejtendő
ki :
<META name="Author" lang="fr" content="Arnaud Le Hors">
Amennyiben a metaadat egy URI-t adna meg, akkor célszerűbb a META elem helyett a LINK elemet használni.
Például vegyük a következő – szokás szerint a szabványból származó – esetet :
<META name="DC.identifier"
content="http://www.ietf.org/rfc/rfc1866.txt">
Ezt írhatjuk így is:
<LINK rel="DC.identifer"
type="text/plain"
href="http://www.ietf.org/rfc/rfc1866.txt">
Másik példa a META elem használatára – és egyben a HTTP-fejléc használatára is – a lejárati idő megadása :
<META http-equiv="Expires" content="Tue, 20 Aug 1996 14:25:27 GMT">
Minden esetben, ha HTTP-fejlécbe küldendő értékről van szó, a name helyett a http-equiv paramétert kell hasz-
nálni.
Az internetes keresők dolgát is megkönnyíthetjük a META elem segítségével. Amennyiben megadjuk a weboldal
tartalmának megfelelő kulcsszavakat, akkor a keresők képesek lesznek a dokumentumot kategorizálni. Ha ráadásul a
lang paraméterrel még a nyelvet is megadjuk, akkor még pontosabb besorolást lehet elérni :
<-- Amerikai keresésekhez: -->
<META name="keywords" lang="en-us"
content="vacation, Greece, sunshine">
<-- Britteknek: -->
<META name="keywords" lang="en"
content="holiday, Greece, sunshine">
<-- Franciáknak: -->
1 A változóval való összehasonlítás nagyon is helyénvaló, mivel az így megadott adatok feldolgozása ténylegesen változókba való beíráson keresztül

szokott történni.

20
7. A META elem
A META elem a dokumentum metaadatainak megadására szolgál.
<!ELEMENT META - O EMPTY -- generic metainformation -->
<!ATTLIST META
%i18n; -- lang,dir for use with content --
http-equiv NAME #IMPLIED -- HTTP response header name --
name NAME #IMPLIED -- metainformation name --
content CDATA #REQUIRED -- associated information --
scheme CDATA #IMPLIED -- select form of content --
>

Mivel az elemnek nincs tartalma, így mindössze egyetlen nyitótagból áll. A paraméterei jelentése, és a megengedett
értékek a profile paramétertől (lásd. : 5. definíció, és a profilok leírása) függ. A paraméterek a következők :
name A metaadat nevét tartalmazza.
content A metaadat értékét tartalmazza.
scheme Ez a paraméter megnevez egy sémát a metaadat értelmezéséhez.
http-equiv Ezt a paramétert a HTTP szerverek használják a name helyett a HTTP fejlécben elküldendő információk
összegyűjtésére (mint a karakterkódolás).
A fentieken felül az elemhez rendelhető még a nyelvet meghatározó lang és az írásirányt befolyásoló dir paraméter
is. A lang paraméter megadása a content paraméter értékére vonatkozik. Például a beszédszintetizátorok számára
lehet hasznos a kiejtés meghatározásához.
Minden META elem egy tulajdonság/érték párt határoz meg, ahol a tulajdonság a metaadat nevét jelenti.
A metaadat másik megadási módja a LINK elem használata, amellyel külső állomány tartalma csatolható erőforrásként
a dokumentumhoz. Ez az állomány tartalmazhatja a dokumentum további metaadatait.

<META name="keywords" lang="fr"


content="vacances, Gr&egrave;ce, soleil">
<-- Végül magyaroknak: -->
<META name="keywords" lang="hu"
content="nyaralás, Görögország, napfény">
A keresés hatékonyságát növelheti, ha a LINK elem segítségével megadjuk az egyes nyelvekre lefordított, illetve a
más (pl. PDF) formátumban elérhető változatokat tartalmazó dokumentumok címét is.

2.2.3. Metaadat-profilok
A HEAD elem profile paramétere (5. definíció) adja meg a metaadatok definiálására szolgáló profil helyét. A paramé-
ter értéke egy cím (URI). A profilok egyik alkalmazási módja egy általános profil használata, amelyet a keresőprogramok
használnak. Ezeket a legtöbb böngésző a profil tényleges betöltése nélkül is ismerheti. Másik lehetőség új profilt létrehoz-
ni, amit a böngészőnek be kell töltenie. A profilok pontos tartalmának ismertetése nem része ennek a dokumentumnak. . .

21
2.2.4. A dokumentum kódolása
A HTML 4-es szabványa már lehetővé teszi, hogy a weboldal megjelenését a böngészők a használt nyelvhez igazítsák.
Ennek egyik eleme, hogy a dokumentum fejlécében megadható a megjelenítéshez használandó kódkészlet. Másik eleme
a karakterreferenciák használata.
Az SGML minden alkalmazásánál megkívánja a dokumentum karakterkészletének megadását. Ez pedig a következő-
ket tartalmazza :
• Egy lehetséges készletet a használható jelek halmazából.
• Egész számok halmaza, amelyek az egyes jelek kódtáblán belüli helyzetét adják meg (a karakterkódok).
Tulajdonképpen a böngésző egy oldal letöltése során byte-ok sorozatát kapja. Mivel weboldalt tölt le, ennek a típu-
sáról nagy valószínűséggel lehet tudni, hogy szöveges állomány, azonban lehet más is. A webszervernek kell tudatnia a
böngészővel, hogy mi a letöltött erőforrás típusa. Ez a HTML esetén text/html. Azonban ez még kevés ahhoz, hogy a
böngésző megállapíthassa, hogyan is kell az egyes byte-okat feldolgozni. Ehhez tudnia kell azt is, hogy milyen kódtábla
szerint kell az egyes byte-okat értelmezni. Ennek megadása tehát rendkívül fontos.
Egy angol nyelvű weboldalnál ez talán nem lenne probléma, de más nyelvek esetében az ékezetek – vagy esetleg a
nem latin betűs ábécé – miatt már bizony komoly problémák lehetnek. Ha azonban a böngésző már a letöltendő állomány
első byte-ja előtt megkapja az információt, hogy melyik kódtáblát használja, akkor ez többé nem probléma. Ha viszont
csak az első néhány byte után derül ki, akkor vigyázni kell, hogy addig lehetőleg csak az ASCII kódtábla karakterei
legyenek a dokumentumban.
Egy webszerver ugyan beállítható, hogy automatikusan a magyar ékezeteket tartalmazó Latin-2 kódolás szerint küldje
a weboldalakat, de célszerűbb a weboldal fejrészében megadni a tényleges kódolást, így akármi van is a webszerveren
alapértelmezett kódolásnak beállítva, a böngésző mindig a helyes kódolást használja.2
A fenti két információt – az állomány típusát és kódolását – tulajdonképpen a dokumentum metaadatának tekintjük,
amelyek összetartoznak, és így egyetlen adatként megadhatóak a META elem segítségével. Egy magyar nyelvű szöveg
esetén a következő sort kell a HTML dokumentumban, lehetőleg rögtön a HEAD elem nyitótagja után elhelyezni :3
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-2">
Ez a sor azt mondja meg, hogy a letöltés alatt álló dokumentumot úgy kell tekinteni, mint aminek letöltése során a
webszerver által küldött metaadatok között a Content-Type nevű adat értéke text/html; charset=ISO-8859-2
volt (ezt jelenti a http-equiv paraméter). Ennek az értéknek a második fele (charset) adja meg a dokumentum kódolását.
Az ISO-8859-1 jelenti a Latin-1 (nyugat-európai), az ISO-8859-2 jelenti a Latin-2 (kelet- és közép európai) kódtáblát.
Nekünk Magyarországon a Latin-2-re van szükségünk. Ezután még akkor is „ő” betű fog megjelenni – feltéve, hogy a
böngésző nem bírálja felül a kódtáblát –, ha a weboldal elkészítésekor a szövegszerkesztő a latin-1 kódtáblát használva
„õ” betű írt.
A fenti megoldáson felül még lehetőség van arra is, hogy néhány elem esetében a charset paramétert használva adjuk
meg az adott elem – vagy az adott elem hatására betöltendő erőforrás – kódolását.

A dokumentum nyelve
Ha már a dokumentum kódolásánál tartunk, meg kell említeni még két nyelvfüggő beállítást. Ezek egyike maga a nyelv
megadása, a másik pedig az írásirány. Ezek beállíthatók az egész dokumentumra (alapértelmezett nyelv ill. írásirány),
vagy egy-egy elemre. Ez utóbbi az alapértelmezett beállítás felülbírálását teszi lehetővé.
2 A böngészőn is be lehet állítani alapértelmezett kódolást, így ha a weboldal sem mondja meg, hogy milyen kódolású, akkor is nekünk megfelelő

kódolást használ. Azonban erre egy weboldal készítője nem építhet, mivel sokan használják olyanok is Webet, akik még ennyi beállítás elvégzésére sem
képesek. Jobb, ha maga a weboldal gondoskodik erről.
3 Tulajdonképpen mindegy, hogy a HEAD elem hányadik elemeként szerepel ez az információ, de minél közelebb van az állomány elejéhez, annál

kevesebb az esély arra, hogy túl későn (egy nem egyértelmű kódú karakter után) jut el a böngészőhöz. A legjobb ilyen információt megadni még az
előtt, hogy az alapértelmezett Latin-1 kódtáblában nem szereplő karakter kerülne elő. . .

22
Arra is alkalmas a nyelv megadása, hogy többnyelvű dokumentumot állítsunk elő. Ekkor minden elemnél, amely
szöveget tartalmaz, meg kell adni, hogy az melyik nyelvnél alkalmazandó, és a böngésző a beállított nyelvhez tartozó
elemeket használva, a többit figyelmen kívül hagyva, az adott nyelvhez tartozó dokumentumot jeleníti meg. A böngé-
sző nyelvbeállítását megváltoztatva ugyanaz a dokumentum azonnal – esetleg az oldal újraolvasását követően – az új
beállításnak megfelelő nyelven szólal meg.

8. A lang paraméter

A lang paraméter, mely szinte minden elemnél megadható, az adott elem nyelvét adja meg. Értéke a használandó
nyelv nyelvkódja. Magyar nyelv esetén ez „hu” vagy „hu-HU”. Angol nyelv esetén több lehetőség is van : „en-GB” a
britt-angol, „en-US” az amerikában használt változat. . .

Attól függően, hogy melyik elemnél szerepel és milyen módon „jeleníti” meg a feldolgozó program a dokumentumot,
a paraméter jelentése más és más lehet:
• Segítheti a keresők munkáját azzal, hogy a META elemek közül csak a használt nyelvre vonatkozóban szereplő
kulcsszavakat veszi figyelembe.
• Beszédszintetizátor esetén segíti a kiejtést.
• Egyes böngészőket a szöveg megjelenítésénél is segíthet a megfelelő betűforma kiválasztásánál. Ami ennél fonto-
sabb : segíthet abban is, hogy az egyes nyelveknél jelentősen eltérő idézőjel-megadási módot megfelelően használja
a böngésző. Hasonlóan segíthet egyéb tipográfiai szabályok helyes alkalmazásában.
• Megadja a dokumentum szövegének alapértelmezett nyelvét, amitől való esetleges eltérést külön meg lehet adni a
megfelelő elemnél.
A paraméter egy nyelvkódot kap értékül. A nyelvkódok egy külső szabványban meghatározott módon definiálják az
egyes nyelveket. Ezt a szabványt használja több rendszer is, így maga a Linux/UNIX operációs rendszer is a használandó
nyelv megadására.
Ez a nyelvkód két részből áll: az első rész magát a nyelvet adja meg (magyar, angol, portugál, spanyol stb.), míg a
másik ennek a nyelvnek egy változatát, amely az országtól függ, ahol azt beszélik. A magyar nyelv esetén ez utóbbi el
is hagyható, hiszen összesen egy változata van. Az angol, a portugál vagy a spanyol viszont olyan nyelvek, amelyeket
elég sok, egymástól messze levő országban beszélik, így azoknak több változata létezik (másképpen mondják ugyanazt az
Amerikában illetve Nagy-Britanniában élő angol anyanyelvű emberek). Az alváltozat annak az országnak a kódját jelenti,
amelyben az adott „nyelvjárás” tipikus. Íme néhány példa a nyelvkódokra :
• „en”: általában az angol nyelv. „en-US” az amerikai angol változat. „en-AU” az ausztráliában beszélt angol.
• „i-navajo” egy amerikai indián nyelv.
• „x-klingon” az x kezdetű kódok speciális nyelveket jelölnek (bizony, vannak olyan fanatikus emberek, akik a Star
Trek sorozatból ismert klingon nyelvet is definiálták. . . )
• „pt-PT” a Portugáliában használt portugál nyelv. „pt-BR” a Brazíliában használt változata a portugál nyelvnek.
• „de-DE” a németországi hivatalos (irodalmi) német nyelv. „de-AT” a német nyelv ausztriában használt változata.
Egy adott elem nyelve a következőképpen dől el :
1. Ha az elemnek van lang paramétere, akkor ennek értéke alapján.
2. Ha az elemet tartalmazó elemnek van lang paramétere, akkor ennek értékét örökli.

23
3. A dokumentum alapértelmezett nyelve, amely az előző pont alapján a HTML vagy a BODY elem lang para-
métereként is megadható, de ha ez sincs megadva, akkor a webszertől a HTTP-fejlécben a „Content-Language”
értékeként is megadható (ez beállítható a META elemmel).
4. Végül, ha még ezek után sem ismert, akkor a böngészőn beállított alapértelmezett nyelvűnek fog számítani.

Az írásirány megadása
Bizonyos nyelveknél nem elég a nyelvet megadni, hanem azt is meg kell adni, hogy merre történik az írás. Nem minden
nyelven írnak ugyanis a nálunk megszokott módon balról jobbra, hanem – mint például az arab nyelvnél – jobbról balra
halad a szöveg egy soron belül. Ezeknél a nyelveknél használatos az írás irányát megadó dir paraméter, amely ugyanott
adható meg, ahol a lang.

9. A dir paraméter

A dir paraméter az írásirány megadására szolgál. Értéke lehet LTR, amely a nálunk megszokott balról jobbra (left to
right), vagy RTL, amely az araboknál megszokott jobbról balra (right to left) irányt jelenti.

Mivel nekünk magyaroknak általában nincs szükségünk az írásirány megfordítására (kivéve az arabul vagy héberül
weboldalt készíteni szádékozóknak), ezért ennek működését nem részletezzük. Ha valakinek mégis szüksége lenne rá,
akkor keresse meg a HTML szabványban ([1]) a pontos leírását. . .

2.2.5. Karakterreferenciák
Egy adott karakterkészlet – és kódtábla – használata esetén is hozzá lehet férni azokhoz a karakterekhez, amelyek nem
elérhetőek a megadott kódtáblában, illetve amelyek valamely más ok miatt saját kódjukkal nem adhatóak meg a dokumen-
tumban. Az is lehetséges, hogy egyszerűen a billentyűzetről nem lehet bevinni az adott karaktert, mert az nem szerepel
billentyűn. Ezekben az esetekben hívhatjuk segítségül az SGML által definiált karakterreferenciákat.
Kétféle karakterreferencia használható. Egyrészt minden karakter elérhető a Unicode kódtáblában hozzá tartozó kód-
dal (numerikus), másrészt vannak olyan karakterek, amelyeknek nevesített referenciájuk is van.

Numerikus referenciák minden esetben egy &# karakterpárral kezdődnek. Ezután egy tízes számrendszerbeli számként
adható meg a karakter kódja a Unicode kódtáblában, vagy tizenhatos számrendszerben egy x után. Mindkét változatban
a ; zárja a referenciát. A referencián belül szóköz használata tilos. Pélák : &#229; decimálisan megadva a å betűt jelenti
(a norvégok használják például); &#xE5; vagy &#Xe5; ugyanez tizenhatos számrendszerben megadva.

Nevesített referenciák A gyakrabban használt karakterek számára könnyebben megjegyezhetők azok a referenciák,
amelyeknek nevük van. Ez a név valamilyen formában utal a karakterre is. A fenti példában szereplő å betű például
elérhető a következőképpen is: &aring;. A nevesített referenciák táblázata megtalálható a [1]-ben, ezért nem soroljuk
fel őket. Néhányat azonban érdemes ismerni, mert olyan karaktereket lehet velük könnyen elérni, amelyeket nem lehetne
beírni, hiszen a HTML nyelv speciális jelentésű szimbólumai :
• &lt;: <;
• &gt;: >;

• &amp;: &;
• &quot;: ";

24
2.2.6. Csatlakozó referenciák
A weboldal részét képező további erőforrásokra, illetve kapcsolódó dokumentumokra lehet utalni a LINK elem segítsé-
gével.

10. A LINK elem

<!ELEMENT LINK - O EMPTY -- a media-independent link -->


<!ATTLIST LINK
%attrs; -- %coreattrs, %i18n, %events --
charset %Charset; #IMPLIED -- char encoding of linked resource --
href %URI; #IMPLIED -- URI for linked resource --
hreflang %LanguageCode; #IMPLIED -- language code --
type %ContentType; #IMPLIED -- advisory content type --
rel %LinkTypes; #IMPLIED -- forward link types --
rev %LinkTypes; #IMPLIED -- reverse link types --
media %MediaDesc; #IMPLIED -- for rendering on these media --
>

A LINK elem külső erőforrásoknak a dokumentumhoz kapcsolására, vagy egyéb kapcsolatok (pl. alternatív dokumen-
tumváltozat) megadására szolgál.
Paramétereinek jelentése a következő:
• id és class a stílus beállítását segítő azonosítók beállítása (mivel a LINK elem nem jelenít meg semmit, igy
jelentősége nem igen van).

• dir és lang a nyelvfüggő beállításokhoz.


• title az elem rövid megnevezésére (esetleg megjelenhet valahol).
• style helyi stílusmegadásra (nem sok jelentősége van).
• eseménykezelők megadására szolgáló paraméterek.
• href a kapcsolódó erőforrás címét adja meg. A hreflang ennek a nyelvét adja meg, a type az erőforrás
típusát (például stíluslapnál lehet text/css), a rel és a rev a kapcsolat fajtáját (stíluslapnál ezért szerepel a
rel="StyleSheet").
• A target paraméter azt az ablakot nevezi meg, amelybe az erőforrást be kell tölteni.

• media megadja, hogy az erőforrást melyik megjelenítési típus esetén kell használni (stíluslapoknál lehet hasznos
az egyes esetekre vonatkozó stíluslap megadásánál).
• charset az erőforrást tartalmazó állományban használt karakterkészletet (kódolást) adja meg.

Íme a csatlakozási fajták, amelyek már léteznek (de még nem minden böngésző tud velük mit kezdeni) :

Alternate A dokumentum egy másik vátlozatát adja meg a kapcsolat, amely például egy másik nyelvet adhat meg (a
lang paraméterrel), vagy más megjelenítőre való változatot (media paraméter). Elvileg arra használható, hogy a
böngésző szükség esetén automatikusan a megjelenítéshez megfelelő változatot töltse be.

25
Stylesheet Egy külső stíluslapot ad meg a kapcsolat. Az „Alternate” értékkel együtt használható arra, hogy a felhasználó
választhasson a használható stíluslapok közül.
Start A weboldal-gyűjtemény kezdőoldalára mutat a kapcsolat. Ez elsősorban a keresőprogramoknak segít a dokumen-
tum kezdőpontjának megtalálásában.
Next A következő oldalra mutat. Egyes böngészők felhasználhatják arra, hogy előre betöltsék a következő oldalt, meg-
gyorsítva ezzel a letöltést.
Prev Az előző oldalra mutat.
Contents A web-dokumentum tartalomjegyzékét tartalmazó oldalra mutat.
Index Az indexre mutat.
Glossary A szójegyzékre mutat.
Copyright A web-dokumentumra vonatkozó szerzői jogokat ismertető oldalra mutat.

Chapter Arra az oldalra mutat, amely a web-dokumentum fejezeteként funkcionál (egy többszintű hierarchiában lehet
értelme).
Section Mint a Chapter, csak egyel alacsonyabb szinten.
Subsection Még egy szinttel lejjebb járunk, mint az előzőnél. . .

Appendix A mellékletre mutat.


Help Segítő információkat tartalmazó oldalra mutat.
Bookmark A könyvjelzőre mutat. Egy olyan oldal lehet, amely fő belépési pontként funkcionál egy terjedelmes doku-
mentumba.

2.3. A dokumentum törzse


A dokumentum törzsét általában a BODY elem tartalmazza. Ez a HTML elemben a HEAD elem után következik.

11. A BODY elem

<!ELEMENT BODY O O (%block; | SCRIPT)+ +(INS|DEL) -- document body -->


<!ATTRIB BODY
%attrs; -- %coreattrs; i18n; %events --
onload %Script; #IMPLIED -- the document has been loaded --
onunload %Script; #IMPLIED -- the document has been removed --
>

Az elem tartalma a dokumentum törzse. Amennyiben nyitó- vagy zárótagja nem szerepel, az elem akkor is jelen van.
Az elem tartalma – mint látható – blokk-szintű elem, script, esetleg a speciális szerepű INS vagy DEL elem lehet.

26
A BODY elem paraméterei a következők:4

id, class : dokumentumon belül érvényes azonosítók (magyarázatukat lásd a stíluslapoknál. . . )


lang : nyelv beállítása, megadása
dir : írásirány megadása
title : az elem megcímkézése
style : helyi stílusdefiníció (lásd ezt is a stíluslapoknál. . . )
onload, onunload, onclick, ondbclock, onmousedown, onmouseup,
onmouseover, onmousemove, onmouseout,

onkeypress, onkeydown, onkeyup: A scriptekben felhasználható események.

Megjegyzés. A scriptekről ebben a fejezetben több szót nem fogunk ejteni. Azoknál az elemeknél, ahol eseményekhez
lehet eseménykezelőt rendelni, csupán megemlítjük, hogy erre alkalmas paraméterek is vannak, mást nem adunk meg
róluk.

2.3.1. Elemazonosításra szolgáló paraméterek


A BODY elem csupán az egyik, de nem a legjobb példa olyan elemre, amelynél használható a class és az id paraméter.
Ez a két paraméter a legtöbb elemnél megadható, és a segítségükkel egy egyedi vagy egy csoportos azonosító rendelhető
az elemhez.

12. Az id paraméter

Az id paraméter egy az egész dokumentumban egyedi nevet rendel az elemhez, amelynek paramétereként szerepel. A
paraméter értékének a névre vonatkozó szabályoknak kell megfelelnie, és sem másik id, sem másik name paraméter
értékével nem egyezhet meg egy adott dokumentumban.

13. A class paraméter

A class paraméter egy nevesített halmazba teszi az elemet, amelyben szerepel. A paraméter értéke egy név, amely a
nevesített halmaz neve lesz. Megadható lista is, ekkor az egyes halmazneveket szóközzel kell elválasztani egymástól.
Egy adott halmazba többféle elem is besorolható. Használata elsősorban a stíluslapokkal együtt jellemző.

Az id paraméter többféle célra használható egy HTML dokumentumban :


• Stíluslapban olyan szabály alkotásához a szelektorhoz, amely csak egy adott elemre érvényes.
• Egy hivatkozás célpontjává teszi az elemet.
4 A BODY elem további paraméterekkel is rendelkezett a korábbi HTML változatoknál – és a laza DTD használata ezeket a paramétereket továbbra

is elérhetővé teszi –, azonban ezek a paraméterek a stíluslapoknak hála mára elavultnak számítanak, és a következő HTML szabványoktól esetleg már
végleg el is tűnhetnek. Mivel a használatuk nem túl jó megoldás, ezért ezekkel a paraméterekkel inkább eleve nem foglalkozom, abban a reményben,
hogy akkor kevesebben szoknak rá — a szerző.

27
• Scriptekben az adott elemre történő hivatkozáshoz (erre a 13.5.1. szakasz mutat példát a JavaScript ismertetésé-
nél. . . )
• Egy OBJECT elem deklarálásakor szerepelhet névként.
• A HTML feldolgozóknál például előfordulhat, hogy a más formátumra való átalakítás során használt adatbázisban
hivatkozási azonosítóként használja a feldolgozóprogram.
A class paraméter az id-vel ellentétben nem egyedi azonosítót rendel az elemhez, hanem egy csoport tagjává teszi
azt. Ennek elsődleges célja szintén a stíluslapon megadandó szabály lehet, amelyet egynél több, de nem minden elemre
akarunk alkalmazni.
Az id egyedisége alól egy kivétel van: ha két olyan elemet adunk meg, amelyeknek lang paramétere más nyelvet
jelöl meg, akkor azoknak megegyezhet az azonosítójuk, hiszen a nyelv beállításától függően valamelyik, de legfeljebb az
egyik elem fog ténylegesen szerepelni a weboldalon.

2.3.2. Blokk- és szövegszintű elemek


A BODY elem definíciójában szerepel a kitétel, hogy a tartalma blokkszintű elemekből áll. Az elemek két csoportra
oszthatók : blokk- illetve szövegszintű elemekre. Ezt a megkülönböztetést elsősorban a doboz-modell alkalmazza, amelyet
majd a stíluslapok bemutatásánál fogunk részletezni. Azonban röviden foglaljuk most össze, mi is a különbség a két
kategória között :

• Blokk-szintű elemek tartalmazhatnak szövegszintű elemeket, vagy akár újabb blokk-szintű elemeket is. Ezzel szem-
ben a szövegszintű elemek csak szöveget, vagy más szövegszintű elemet tartalmazhatnak.
• A blokk-szintű elemek általában egy téglalap alakú területet jelölnek ki a weboldalon a dokumentum törzsében,
amelyen belül helyezkedik el a tartalmuk. Előfordulhat, hogy a téglalap elsőre nem felismerhető, de ekkor is igaz,
hogy a blokk-szintű elem tartalma mindig egy új sorban kezdődik. Ezzel szemben a szövegszintű elemek tartalma
a normál szövegszedésre jellemző sorfolytonos megjelenésű, amelyben bárhol eltörhet a sor, ha éppen a jobbmar-
góhoz ért a szöveg, és a következő sorban folytatódhat.
• Azt, hogy a sornak hol kell véget érnie és hol kell kezdődnie, azaz hol van a jobb- és a balmargó, a szövegszintű
elemeket tartalmazó blokk-szintű elem méretei határozzák meg elsősorban.

Maga a BODY elem tulajdonképpen tekinthető az elemhierarchia tetején levő, minden további elemet magába foglaló
blokk-szintű elemnek. Minden egyéb elemnek a BODY által meghatározott téglalapon belül kell megjelennie.
Van két speciális elem, amelyeknek alapvetően semmi más feladatok nincs, mint egy „zárójelet” képezni valamely
HTML tartalom körül. Az egyik blokk-szintű: egy blokkba teszi a tartalmát ; a másik szövegszintű : egyszerűen csak a
szöveg egy részét kijelöli. A két „zárójelező” elem egyike sem változtat semmit a tartalma megjelenítésén. Azonban az
id és class paraméterek megadásával lehetővé teszik egy-egy tartalom vagy szövegrész önálló formázását a stíluslapon
keresztül, vagy speciális célú felhasználását például scripteken keresztül. Ez utóbbira a 13.5.1. szakasz mutat példát.
A blokk-szintű „zárójelező” elem a DIV (14. definíció), míg a szövegszintű a SPAN (15. definíció).
Mint az a két definíción is látszik, különbségük csupán annyi, hogy a SPAN elemnek csak szövegszintű tartalma lehet,
míg a DIV elemben gyakorlatilag bármilyen tartalmat be lehet zárni.
Annak, aki a fenti definícióból még nem tudja kihámozni, íme a két elem lehetséges paraméterei, egyenlőre csak
felsorolva, hiszen ez mind olyan általános paraméter, amely majdnem minden elemnél előfordul (ebből is látszik, hogy
az elemek arra jók, ha más teendőnk nincs egy adott tartalommal, mint ezen paraméterek valamelyikét beállítani bármely
célra) :
• id és class, az elemek beazonosítására;
• lang a nyelv megadására, amely az elemen belül érvényes, illetve amely nyelv esetén az elem egyáltalán megje-
lenítendő (lehet egy másik nyelvhez egy alternatívája ennek az elemnek. . . ), és az írásirány megadására a dir;

28
14. A DIV elem

<!ELEMENT DIV - - (%flow;)* -- generic language/style container -->


<!ATTLIST DIV
%attris; -- %coreattrs, %i18n, %events -->
>

15. A SPAN elem

<!ELEMENT SPAN - - (%inline;)* -- generic language/style container -->


<!ATTLIST SPAN
%attrs -- %coreattrs, %i18n, %events --
>

• style a helyi stílusdefiníciókhoz, ha nem akarunk babrálni a külön stíluslappal ;


• align az elem tartalmának igazítására (inkább csak a DIV-nél, de ott is kiváltható a stíluslappal) ;
• eseménykezelők paraméterei

2.3.3. A dokumentum szakaszokra bontása


Minden nagyobb lélegzetű dokumentumot illik struktúrálni fejezetkre és alfejezetekre bontással – ahogyan ez a doku-
mentum is teszi. A weboldalaknál is szükség lehet ilyenre – akár egy oldalon belül, akár a dokumentumok fölött. Ehhez a
HTML szabvány a rendelkezésünkre bocsát hat különböző szintű címsort, amelyet a fejezetek, alfejezetek, szakaszok ele-
jén a cím megadásához, vagy egy rövidebb oldalon a weboldal tetejént, a szöveg fölötti cím megadásához használhatunk.
Ezek az elemek a Hn elemek, ahol az n helyén 1 . . . 6 közé eső egész szám állhat : 16. definíció.

16. A H1, H2, . . . H6 elemek

<!ENTITY % heading "H1|H2|H3|H4|H5|H6">


<!ELEMENT (%heading;) - - (%inline;)* -- heading -->
<!ATTLIST (%heading;)
%attrs; -- %coreattrs, %i18n, %events --
>

A H1, H2,. . . H6 elemek hat különböző szintű címsort hoznak létre. A legnagyobb rangú címsort a H1, a legkisebbet a
H6 hozza létre. Bár tartalmuk szövegszintű, maguk az elemek blokk-szintűek : hatásukra a címsor tartalma egy külön-
álló blokkba kerül, amelynek margója elkülöníti azt a környező szövegtől, és a betűméret is eltér a normál szövegétől
(alaphelyzetben a H4, H5 és H6 betűmérete általában kisebb a normál szövegétől, de a stíluslap ezen tud segíteni. . . ).
Lehetséges paraméterei (a jelentésük nélkül): id, class, lang, dir, title, style, align és az események.

29
Jelenleg a fejezetek számozása nem lehetséges. Bár a legújabb CSS szabvány már biztosít ehhez eszközöket, a bön-
gészők még nem kezelik ezeket az eszközöket, így erre a lehetőségre még várnunk kell. . .

2.3.4. Az ADDRESS elem

17. Az ADDRESS elem

<!ENTITY ADDRESS - - (%inline;)* -- information on author -->


<!ATTLIST ADDRESS
%attrs; -- %coreattr, %i18n, %events --
>

Az elem lehetséges paraméterei: class, id (azonosítók az elemhez) ; lang (nyelv megadása) ; dir (írásirány meg-
adása) ; title (magyarázó szöveg); style (stílusmegadás) ; eseménykezelők definiálása.
Az ADDRESS elem alkalmas arra, hogy a dokumentum vagy annak egy űrlapja elején vagy végén elhelyezve a szer-
zőkről adjon meg valamilyen információt.

Ezzel a HTML nyelvről szóló – kicsit részletesebb – bevezető végére értünk. A következő fejezet bemutatja a CSS nyelvet,
amely a stíluslapok létrehozására szolgál. Az ezt követő fejezetkben azután az egyes weboldal-objektumokat megvalósító
HTML elemek és a hozzájuk rendelhető, stíluslap szabályokkal megadható formázási lehetőségek párhuzamos ismertetése
következik.

30
3. fejezet

Stíluslapok használata

Ebben a fejezetben megismerjük a stíluslapok használatának módját, és magát a CSS nyelvet. Egy weboldalhoz elvileg
többfajta stíluslapot is lehetne használni, azonban jelenleg mindössze egy olyan nyelv van, amellyel a stílust definiálni
lehet. Mivel pedig ez már olyan kiforrottá vált, hogy gyakorlatilag mindenre használható – jelenleg még a böngészők sem
valósítanak meg mident, amit lehetővé tenne –, így nagy valószínűséggel nem is lesz más nyelv erre a célra.
Mindenekelőtt célszerű egy kicsit pontosítani, mit is értünk stíluson. A stílus itt a weboldal stílusát jelenti, vagyis a
megjelenését. Általában ez nem azonos a weboldal formázásával, de bizonyos esetekben a két fogalom egymás helyett
használható. Egy weboldal a legtöbbször vizuális megjelenítővel válik elérhetővé. Ebben az esetben a stílus az oldal
formázásával egyezik meg. Azonban másképpen is fel lehet egy weboldalt dolgozni. Ha például beszédszintetizátor ol-
vassa fel a weboldal tartalmát, akkor a stílus azt határozza meg, hogy milyen beszédsebességet, milyen hangszínt kell
alkalmazni, hol kell szünetet tartani, mit kell külön is hangsúlyozni stb.
Ebben a dokumentumban a weboldalakkal mint vizuálisan megjelenített objektumokkal foglalkozunk, így csak az
erre vonatkozó stíluselemekkel fogunk megismerkedni. A mi szempontunkból tehát a stílus és a formázás azonos je-
lentéssel rendelkezik. A más megjelenítési formákhoz tartozó részei a stílusnak megtalálhatóak a CSS nyelvet definiáló
szabványban ([2]).
A stíluslaphoz tulajdonságok tartoznak, amelyeket az egyes HTML elemekhez rendelhetünk.1 A későbbiekben a
bemutatott tulajdonságok megadásánál részben követni fogjuk a szabványt, és megadjuk a tulajdonság lehetséges értékeit,
az alapértelmezett értéket, illetve azt, hogy hogyan viselkedik a tulajdonság azokra az elemekre, amelyeket az az elem
tartalmaz, amelyhez a tulajdonság tartozik: öröklik az értékét vagy esetleg újra az alapértelmezett értéket kapja.

3.1. A stíluslapok megadásának lehetőségei


Egy weboldalhoz háromféleképpen lehet stílust megadni.
1. Külső stíluslap hozzárendelésével;
2. A weboldal fejlécében elhelyezett stíluslappal ;
3. Az egyes HTML elemekhez rendelt, csak arra az elemre vonatkozó szabályok megadásával.
Mivel a stíluslapok fő ereje abban van, hogy önálló állományban található, és így akárhány weboldalhoz hozzárendel-
hető, így értelemszerűen amikor csak lehetséges, az első változatot kell használni.
A második lehetőséget arra célszerű használni, ha a külső stíluslaphoz képest néhány, csak az adott oldalra érvényes
változtatásra van szükség. Mi lehet ez a változás? Például az, ha az általános stíluslap piros címeket ír elő, de ezen az
1 Tudni kell, hogy a CSS nyelv nem csupán HTML dokumentumokhoz tesz lehetővé stílus definiálását, hanem más leíró nyelvekhez is, mint például

az XML, ebben az esetben nem HTML elemekhez tartoznak a tulajdonságok, hanem az XML elemeihez.

31
oldalon kivételesen fekete címeket szeretnénk. Bizonyos eszközökkel azonban az erre vonatkozó szabályok is megadhatók
a külső stíluslapban. . .
A harmadik változat egy adott elemnél képes felülbírálni az általános beállítást, azonban ez szintén megadható más
módon.
Általában célszerű betartani azt a szabály, hogy mindent külső stíluslapon helyezzünk el, még ha pillanatnyilag csak
egy oldalra, vagy egyetlen elemre specifikus dologról van is szó. Elképzelhető ugyanis, hogy a későbbiekben mégis
szeretnénk ugyanazt a megoldást máshol újra felhasználni. Ekkor megkeresni is egyszerűbb a külső stíluslapon, mint a
HTML dokumentumban keresgélni, de lehet, hogy keresni sem kell, csak használni. A stíluslapokat éppen azért találták
ki, hogy megszűnjön az a régebbi gyakorlat, amikor minden elem megjelenését magánál az elemnél kellett meghatározni,
ami jelentősen megnehezítette a dokumentum következetes kinézetének megvalósítását.
A CSS a Cascading Stylesheets rövidítése. Ez azt jelenti, hogy az egyszer már definiált szabályok öröklődnek a
következő szabályba. Ez lehetővé teszi, hogy először általános stílust hozzunk létre, majd az általánostól való eltérésre
további finomítást alkalmazzunk. A három stílushozzárendelési mód is ezt a logikát követi : a külső stíluslap a belsővel
felülbírálható, a belső pedig a helyi stílusmegadással.
Éppen ezért a stíluslap szerkezetében is célszerű követni ezt a logikát : először a legtöbb elemre érvényes szabályokat
megadni, azután folyamatosan haladni az egyre részletesebb, egyre speciálisabb szabályok felé.
A külső stíluslapot a weboldalhoz a LINK elemmel lehet hozzáfűzni (10. definíció, 25. oldal). Ebben az esetben a
rel paraméter értéke minden esetben „StyleSheet” legyen, hogy a böngészővel tudassuk : ez az erőforrás a dokumentum
stílusát határozza meg. A type paraméter értéke a CSS nyelvet használó stíluslapoknák „text/css”. A href paraméter
pedig a stíluslapot tartalmazó állomány címe legyen. A következő példa a HTML dokumentummal azonos könyvtárban,
main.css néven létező állományt használja stíluslapnak :
<LINK rel=’StyleSheet’ type=’text/css’ href=’main.css’>
Belső stíluslapot a HEAD elemen belül elhelyezett STYLE elemmel lehet megadni. Ennek az elemnek a type pa-
ramétere szintén a stíluslap megadására használt nyelvet határozza meg : „text/css”. Az elem tartalma pedig pontosan
úgy néz ki, mint egy külső stíluslapot tartalmazó állomány tartalma – de ez csak arra az oldalra érvényes, amelynek a
fejlécében szerepel.
Az egyes elemekhez az elem style paraméterével lehet stílust megadni. Ekkor a paraméter értékébe azt a szöveget
kell írni, amely a rá vonatkozó szabály kapcsos zárójeleiben szerepelne (lásd lentebb, a következő szakaszban).

3.2. A stíluslap szerkezete


A stíluslap szabályokat tartalmaz. Minden szabály két részből áll. Az első rész, a szelektor határozza meg azoknak az
elemeknek a körét, amelyre a szabályt alkalmazni kell. A második rész adja meg, hogy a szelektor által megadott ele-
meknek melyik tulajdonsága milyen értéket vegyen fel. Amennyiben egy adott elemre több szabály is vonatkozik, azaz
több szabály szelektora által megadott halmazba is beleesik a szabály, akkor egymás után a megadás időrendi sorrend-
jében minden szabályt alkalmazni kell rá. Amennyiben egy tulajdonság több szabályban is értéket kap, akkor az utolsó
előfordulásánál szereplő értéket kapja a tulajdonság.
Itt időrendi sorrendnek egy adott stíluslapon belül az állomány elejétől a vége felé haladás számít. Különböző helyen
szereplő szabályoknál pedig az előző szakaszban szereplő megadási sorrend számít. Ha egy weboldalhoz több külső
stíluslap is tartozik, akkor a böngészők a megadási sorrendjükben dolgozzák fel azokat – vagy esetleg csak az elsőt vagy
csak az utolsót veszik figyelembe.
A szelektorokról a következő szakaszban ejtünk szót. A szabály második fele egy kapcsos zárójelek között, egymástól
pontosvesszővel elválasztott tulajdonság-lista, amelyben a tulajdonság neve, utána egy kettőspont, végül a tulajdonsághoz
rendelendő érték szerepel. Íme egy példa a szabályra :
H1 { color: blue; font-size 150%}
Ez a H1 elemekre vonatkozik (a szelektor ezt a halmazt határozza meg), és a H1 szövegének színét kékre, a méretét pedig
a körülötte levő (általában a BODY) elem szövegméretének másfélszeresére állítja be.

32
Hogy az öröklődést is bemutathathassuk, következzék egy példa, változtatás nélkül átvéve a [2]-ből :
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD>
<TITLE>Bach’s home page</TITLE>
<STYLE type="text/css">
BODY { color: red }
H1 { color: blue }
</STYLE>
</HEAD>
<BODY>
<H1>Bach’s home page</H1>
<P>Johann Sebastian Bach was a prolific composer.
</BODY>
</HTML>

Ebben a weboldalban egy belső stíluslap található, ahol a szöveg színe pirosra van állítva, azáltal, hogy a BODY
elemhez tartozik egy szabály, amit beállítja a szövegszínt pirosra (color: red). Ennek hatására minden elem szöveg-
szín tulajdonsága ezt az értéket örökli. Kivéve a H1 elemet, amelynek a következő szabály megváltoztatja e tulajdonság
értékét, így a H1 elemek esetén kék lesz a szövegszín.
A CSS2 több, mint száz tulajdonságot definiál, ezek közül csupán az egyik a fenti példában szereplő color. A ké-
sőbbiekben a tulajdonságok egy jelentős részével találkozni fogunk, azonban nem mindegyikkel. (Az összes tulajdonság
megtalálható a [2]-ben.)

3.3. Hogyan dolgozza fel a böngésző a stíluslapot?


A CSS2 szabvány definiál egy modellt, amelyet – többé-kevésbé – a böngészők követnek, amikor a stíluslapot feldolgoz-
zák. Ez a következő lépésekből áll:
1. Végignézi a dokumentumot, és felépíti az elemek hierarchiáját. Ezt nevezük dokumentumfának. Ezt a dokumen-
tumfát több helyen használjuk, csupán az egyik felhasználása a formázás előállítása. A fa minden csúcsára igaz,
hogy egy elemnek felel meg, amely elem tartalma a fa ezen csúcsának a gyereke lesz.
2. Megállapítja a célmédiát. Ez egy adott böngészőnél eleve meghatározott. Egy vizuális megjelenítést használó bön-
gésző esetén legfeljebb az a kérdés, hogy a képernyőn történő megjelenítésről, vagy a weboldal kinyomtatása esetén
használható nyomtatott (oldalakra bomló) megjelenítésről van-e szó.

3. A dokumentumhoz csatolt stíluslapok közül kiválasztja azokat, amelyek a célmédiára vonatkoznak. A többi stílus-
lapot figyelmen kívül hagyja.
4. Minden egyes elemhez az összes hozzá tartozó tulajdonságnak az alapértelmezett értéket beállítja. Az alapértelme-
zett értékek részben a HTML nyelv szabályaiból, részben a böngésző alapbeállításaiból következnek. Tulajdonkép-
pen lehet ezt a lépést úgy tekinteni, mint a böngésző saját, belső stíluslapjának feldolgozását.
5. Következő lépésben végig megy az egyes stíluslapokon, azon belül annak elejétől a végéig haladva, és az egyes
szabályok feldolgozása során az azok által érintett elemek megfelelő tulajdonságainak értékét a szabályok által
meghatározott értékre módosítja.
6. Megalkottja a dokumentum formázási struktúráját, ami a ténylegesen megjelenő objektumokat írja le.
7. A létrehozott formázási struktúrát elküldi a kívánt médiára (képernyőre, nyomtatóra, beszédszintetizátorra stb.)

33
3.3.1. A „vászon”
Az egyes médiákhoz a CSS2 leírása különböző modelleket definiál. Minden ilyen modellben szerepel a „vászon” kifeje-
zés. Ez alatt a weboldalról szóló fejezetekben mindenhol azt a „helyet” értjük, ahol a fenti lépéseknél említett formázási
struktúra ténylegesen megjelenik. Ez egy kétdimenziós, végtelen sík, amelynek általában egy véges részét használjuk a
megjelenítés során. Képernyőn történő megjelenítés esetén a használt, látható része a megjelenő, látható ablak, angolul vi-
ewport. A vászont tekinthetjük úgy, mint a dokumentum hátterét, amire az objektumok (a szöveg betűi, a képek) kerülnek.
Nyomtatás esetén a vászon nem más, mint a papír, amire nyomtatunk.

3.4. Szelektorok
A szelektorok tehát azt határozzák meg, hogy a szabály, amelynek első részét alkotják, mely elemekre érvényes. Innen
származik az elnevezés is, hiszen a szelektor feladata kiválasztani azon elemeket, amelyekre a szabályban megadott
tulajdonság-értékadásokat alkalmazni kell. A következőkben megismerjük a lehetséges szelektorokat. Azonban most is
igaz, hogy nem minden szelektort mutatunk be, csak a lényegesebbeket.
Amennyiben több szelektorhoz ugyanaz a szabály tartozna, akkor a szabályok egyetlen szabállyá összevonhatóak,
amelynél az egyes szelektorok egy vesszőkkel tagolt listát alkotnak. Például az alábbi szabály egyszerre vonatkozik az
összes címsorra (annak színét kékre állítva):
h1, h2, h3, h4, h5, h6 {color: blue}

3.4.1. Univerzális szelektor


Az univerzális szelektor egyetlen * jelből áll, és a dokumentum valamennyi elemét jelenti. Önmagában ritkán alkalmaz-
zuk, általában valamely összetettebb szelektor részeként jelöli, hogy azon a ponton bármely elem szerepelhet. Amennyi-
ben nem önállóan áll, akkor el is hagyható. Például az alábbi két szelektor – jelentésükre később derül fény – ugyanaz :
*.uj
.uj

3.4.2. Elem (típus) szelektorok


Egy adott elem összes előfordulására érvényes szabályt adhatunk meg az elem szelektor használatával. Ez tulajdonképpen
nem jelent mást, mint az elem nevének megadását. Az alábbi szabály a dokumentum valamennyi H1 elemére (és csak
ezekre) fog vonatkozni:
H1 {font-family: sans-serif}

3.4.3. Leszármazott elemre mutató szelektor


A további szelektorok az univerzális vagy elem szelektorral megadott elemek egy bizonyos részhalmazára képesek szűkí-
teni a ténylegesen érintett elemeket. Ilyen szűkítés lehet például, amikor olyan elemekre akarunk szabályt adni, amelyek
egy másik, meghatározott elemen belül, annak tartalmában vannak. Ha például olyan szabályra van szükségünk, amely
egy A elem belsejében elhelyezett B elemekre érvényes, akkor a szelektor A B lesz. Ha ennél bonyolultabb a helyzet,
és például egy A elemben elhelyezkedő B elem belsejében levő C elemekre érvényes szabályra van szükségünk, akkor
a megoldás a A B C szelektor alkalmazása. Ebből már látható, hogy leszármazott elemre vonatkozó elem esetében a
legkülső elemtől a legbelső elem felé haladva az elemeket soroljuk fel, közéjük legalább egy szóközt írva.
Az egyes elemek megadása azonban többféle lehet : lehet elem, vagy univerzális szelektor, de akár a későbbiekben
bemutatott osztályozó szelektor is. Például ha azoknak az EM elemeknek a színét, amelyek egy DIV elemen belül úgy
helyezkednek el, hogy még egy másik elemben is benne vannak (a DIV elem „unokái”, vagy még további leszármazottai),
akkor azt az alábbi szabállyal tehetjük meg:

34
DIV * EM {color: blue}
Itt az univerzális szelektor önálló tagként szerepel, így a csillagot ki kell írni.

3.4.4. „Gyermek” megadása


Az előző példa esetleg túl általános. Előfordulhat, hogy azt kellene megadni, hogy az EM elem pontosan az „unoká-
ja”, azaz második szintű leszármazottja a DIV elemnek. Semmi vész: cseréljük a szóközöket a szelektorban > jelre :
DIV>*>EM.
A > két önállóan is értelmes szelektor között azt jelenti, hogy az előtte levő szelektor által megadott elemnek a mögötte
álló elem a „gyermeke”, azaz közvetlen leszármazottja. Ez magyarra fordítva azt jelenti, hogy az első elem közvetlenül
tartalmazza a másodikat. Például a következő szabály azokra a P elemekre vonatkozik, amelyek közvetlenül a BODY
elemben találhatóak:
BODY > P {color: blue}
Azonban például a BODY elemen belül elhelyezkedő DIV elembe zárt P elemekre a fenti szabály nem vonatkozik, míg a
BODY P szelektor használata esetén azokra is érvényes lenne.
Megjegyzés. Amennyiben az elválasztó jel nem a legalább egy szóköz, akkor az elválasztó jel előtt és után is tetszőleges
számú szóközt lehet írni. Így a BODY>P és a BODY > P ugyanazt jelenti.
Az előző két szelektortípust akár össze is lehet kapcsolni. A következő példa erre mutat lehetőséget :
DIV OL > LI P
Ez azokra a P elemekre vonatkozik, amelyek egy OL elembe közvetlenül elhelyezett LI elemen belül (akár többszö-
rösen beágyazva) találhatóak, amely OL elem egy DIV elemen belül található.
A későbbiekben látunk még lehetőséget arra is, hogy egy elem gyerekei közül a legelsőt válasszuk ki. . .

3.4.5. Közvetlen szomszédok


A legáltalánosabb tipográfiai szabályok szerint a cím után, a szakasz első bekezdésénél nincs, a többinél van az első
sornak bekezdése. Ahhoz, hogy ezt meg lehessen oldani egy weboldalon, szükség van egy olyan szelektorra, amelynek a
segítségével egy elemet közvetlenül követő elemet lehet kiválasztani. Ennek megadása a + jel alkalmazásával lehetséges.
A példában szereplő esetet a következő stíluslaprészlet oldhatja meg :
P {text-indent: 1em}
H1 + P {text-indent: 0}
Megjegyzés. Ebben a példában fontos a két szabály sorrendje : ha előbb szerepelne a H1 utáni P elemre vonatkozó
szabály, akkor a másodikként szereplő szabály felülbírálná annak beállításait, hiszen az minden P elemre vonatkozik, így
minden bekezdés, még a H1 utániak is rendelkeznének behúzással.
Másrészt a fenti példában csak a H1 utáni bekezdések nem lesznek behúzva, a H2,. . . , H6 utániak igen. Ha ezek után
is szeretnénk a behúzást megszüntetni, akkor a többi szelektort is meg kell adni vagy külön szabályban, vagy a vesszővel
összekapcsolva a szabályokat: H1 + P, H2 + P, H3 + P a három legnagyobb címsorra működik. . .
Az E1+E2 szelektor egészen pontosan azokra az E2 elemekre igaz, amelyek egy E1 elemet követnek, úgy, hogy
mindketten ugyannak az elemnek a közvetlen leszármazottai (gyerekei).

3.4.6. Elem paraméterei


Arra is lehetőség van, hogy egy adott elem előfordulásai közül csak azokra vonatkozzon a szabály, amelyek rendelkeznek
egy bizonyos paraméterrel, vagy ezen belül is azok egy adott értéket kapnak. Ilyenkor az elem neve után egy szögletes
zárójelben szerepel a paraméter neve, és esetleg egy egyenlőségjel után az értéke. Lehetőség van a paraméter értékének
további részletezésére is. Általában azonban egy ennél speciálisabb esetet szokás alkalmazni, az osztályozó szelektort.

35
3.4.7. Osztályozó szelektor
Az osztályozó szelektor az elem class paraméterének egyszerűbb felhasználását teszi lehetővé. Mint már említettük,
a class paraméter arra jó, hogy egy osztály elemévé tegye az adott elemet. Az osztály (vagy halmaz) neve a paramé-
ter értéke. A „pl” halmazba tartozó E elemre lehetne így hivatkozni : E[class=pl], de ennél rövidebb, ha az E.pl
szelektort használjuk.
Egy osztály megadása tehát az elem neve (vagy az univerzális szelektor csillaga) után írt pontból, majd az osztály
nevéből áll. Egy szelektor több osztályt is kijelölhet (ehhez persze az kell, hogy a class értékeként is meg lehessen több
osztályt adni). Ilyenkor minden osztályt a pont és az osztály neve ad meg. Az osztályok megadási sorrendje mindegy.
Amennyiben az elem neveként az univerzális szelektor szerepelne (bármely elem adott osztályba tartozó példányaira
vonatkozik a szabály), akkor a csillag elhagyható, ahogy azt már az univerzális szelektornál említettük.
Íme néhány példa:

*.pastoral {color: green}


.pastoral {color: green}

A két szabály megegyezik, és azokra az elemekre vonatkozik, amelyek class paramétere értékként tartalmazza a „pas-
toral” halmaznevet.

P.pastoral.marine {color: green}

Minden olyan P elemre vonatkozik, ahol a class paraméter értékében az osztályok nevei között szerepel a „pastoral”
és a „marine” is. A class paraméter értéke mindig vagy egyetlen azonosítóból áll, vagy azonosítók szóközzel elválasztott
listájából.

3.4.8. Egyedi azonosítók


Az id paraméterhez is van egyszerűsített hozzáférés. Emlékeztetőül : ez a paraméter egy az egész dokumentumra nézve
egyedi azonosítót rendel az elemhez. A stíluslapon ezt a # jel után az azonosító megadásával lehet elérni. Ahogyan az
osztály esetében, úgy az egyedi azonosító esetében is a # (osztálynál a pont) után azonnal az azonosítót kell írni, szóköz
nem lehet előtte.

3.4.9. Pszeudo elemek és pszeudo osztályok


A pszeudo elem olyan elem, amely valójában nem önálló elem, de valamely elemnek egy önálló formázásra igényt tartó
része. Ugyanígy a pszeudo osztályok olyan osztályok, amelyeket nem kell megadni, mégis bizonyos elemek beletar-
tozhatnak, azonban az, hogy beletartoznak-e, az a dokumentum tényleges megjelenítésekor dől csupán el. Ez talán túl
semmitmondó megfogalmazás volt, azonban hamarosan ki fog derülni, hogy miről is van szó : pszeudo osztály vonatko-
zik például arra az esetre, amikor egy hivatkozásnál el kell dönteni, hogy a hivatkozott dokumentumot a már megnézettek
közé kell-e sorolni vagy sem. Hasonlóan például egy bekezdés esetén az első sorra vonatkozhat a többitől eltérő formázás.
Erre egy pszeudo elem biztosít lehetőséget.

Pszeudo osztályok
:first-child A :first-child pszeudo osztály valamely elem tartalmán belül elsőként szereplő elemet jelenti, egé-
szen pontosan a gyermekei közül a legelsőt. Például ha egy dobozt hozunk létre bekezdések tárolására, akkor az erre
szolgáló DIV elemben az első P elemre a DIV > P:first-child szelektor hivatkozik. Azonban ebben az esetben
csak arra a P elemre fog a szelektor vonatkozni, amely legelső elemként szerepel a DIV elemben, ha bármely más elem
megelőzi azt, akkor már nem.

36
Hivatkozások pszeudo osztályai Hivatkozások esetében a böngészők lehetővé teszik a már meglátogatott címek más
színnel megjelölését, és ezen felül még egy harmadik esetként kezelhetik a hivatkozásra való kattintást is. A még meg
nem látogatott hivatkozások elemei a :link pszeudo osztályba tartoznak, a már meglátogatottak pedig a :visited
pszeudo osztályba. Hivatkozások szövegének színét ezzel a két pszeudo osztállyal tudjuk beállítani.

Dinamikus eseményekhez kapcsolódó pszeudo osztályok Amikor bármely elemre a felhasználó az egérrel rákattint,
egészen az egér gombjának felengedéséig az elem az :active pszeudo osztályba tartozik. Ezt az osztályt lehet hasz-
nálni például a hivatkozások esetében a rákattintás idején érvényes szín beállítására, de akár egy bekezdés szövegére is
használható.
Amennyiben az egér mutatója egy elem fölött található – de a felhasználó nem kattint az elemre –, az az elem a
:hover pszeudo osztályba kerül. Ez többek között alkalmas lehet arra, hogy a hivatkozás szövege csak akkor legyen
aláhúzva, amikor a felhasználó az egérmutatót a szöveg fölé viszi. Ennek pontos módját majd a hivatkozások ismerteté-
sénél (78. oldal) fogjuk bemutatni.
Amikor egy elem valamilyen esemény folytán megkapja a fókuszt2 , akkor belekerül a :focus pszeudo osztályba.

Az elem nyelve Az elemekhez lehet megadni nyelvet, amely esetén a böngészőnek az elemet figyelembe kell vennie.
Erre lehet a lang paraméteren keresztül is hivatkozni, de megkönnyíti ennek az információnak a használatát a :lang
pszeudo osztály. Ez azonban az előzőektől kicsit eltérően működik : egy zárójelen belül kell megadni a nyelv kódját, példá-
ul a magyar esetében így: :lang(hu), vagy a francia esetében így : :lang(fr). Például az idézőjelek alkalmazásánál
lehet hasznos, ha beállítjuk a nyelvnek megfelelő idézőjelek használatát (lásd : 42. oldal).

Pszeudo elemek
Első sor Egy bekezdés első sorát – általában bármely bekezdésként kezelendő szöveg első sorát – nem önálló HTML
elem határozza meg. Ezért ha el akarjuk érni, önálló formázás céljából, akkor arra a :first-line pszeudo elemet
kell alkalmaznunk. Ez – mint minden pszeudo elem – a pszeudo osztályokkal ellentétben önállóan nem szerepelhet, csak
valamely elemmel együtt, hogy annak az elemnek egy részét tegye elérhetővé. Például egy bekezdés első sorát tehetjük
csupa nagybetűssé a következő szabály alkalmazásával (ekkor az oldal összes bekezdésének első sora nagybetűs lesz) :

P:first-line {text-transform: uppercase}


Ez a pszeudo elem csak blokk szintű elemekre alkalmazható, amelyek tartalma sorokra tördelt szövegként jelenik
meg.

Első betű Az első betű is külön formázható a :first-letter pszeudo elem segítségével. Ez egy lehetséges megol-
dás lehet iniciálé készítésére. Ez is csak blokk szintű elemekre használható.

Az elem elé vagy mögé generált tartalom A ma használatos böngészők még valószínűleg figyelmen kívül hagyják
a legtöbb esetben azokat az eseteket, amelyekkel egy-egy elem tartalma elé illetve utána lehet valamit elhelyezni. Ide
tartozó, de szerencsére a legtöbb böngészőnél már működő lehetőség az idézőjelek beállítása. Szintén ide tartozó, de még
nem igazán használható lehetőség a címek, bekezdések sorszámozása.
Ezekre a :before és az :after pszeudo elemek vonatkoznak.
2 A fókuszt egy olyan fogalom a számítástechnikában, amely különböző felhasználói felületeknél előkerül. Akármilyen objektumról van is szó (ablak,

űrlap egy eleme, párbeszédablak egy egy eleme, vagy egy weboldal valamely eleme), mindig azt jelenti, hogy a billentyűzetről begépelt szöveget az
adott objektum kapja meg feldolgozásra.

37
3.5. Tulajdonságok lehetséges értékei
Minden tulajdonság értéke meghatározott típusból kerülhet ki. A következőkben az általánosabb típusokat fogjuk fel-
sorolni, amelyek több tulajdonságnál előfordulnak. Vannak olyan tulajdonságok is, amelyek értéke egy kulcsszó egy
meghatározott készletből. Ezeket itt nem lenne értelme ismertetni, hiszen egy adott tulajdonságra vonatkozó értékről van
szó.

3.5.1. Számok
A számértéket váró tulajdonságoknak tízes számrendszerben kell megadni a számot. Lehet egész, vagy valós a szám.
Ez utóbbi esetben a . jelöli a tizedespontot. A számérték lehet pozitív vagy negatív, de bizonyos tulajdonságok nem
fogadnak el negatív értéket. Ha egy ilyen tulajdonság mégis negatív értéket kap, akkor a tényleges értéke a legközelebbi
megengedett érték lesz.

3.5.2. Hosszmérték
A hosszmértékek valamilyen függőleges vagy vízszintes távolság megadására szolgálnak. Egy számból és utána a mér-
tékegységből állnak, a kettő között nem lehet semmilyen elválasztó, így szóköz sem. A mértékegység a 0 érték kivételével
kötelező.
Kétféle hosszmérték létezik: a relatív és az abszolút hossz. A relatív hossz mindig egy másik hosszt megadó tulaj-
donság értékéhez relatív, míg az abszolút önmagában ad meg egy méretet. Amennyiben a relatív méreteket (a képpont
kivételével) a dokumentumfa gyökerénél adjuk meg, úgy a dokumentum alapértelmezett méretéhez – amit a böngésző
határoz meg – lesznek relatívak ezek az értékek. A lehetséges mértékegységek a következők :
• em: relatív mértéket ad meg. Az adott elem font-size tulajdonságában mér (a betűmérethez, vagy másképpen
fogalmazva a nagy M betű magasságához relatív méret), illetve a font-size tulajdonság esetén a szülő elem
betűméretében.
• ex: relatív mértékegység, amely az adott betűméretben a kis x betű magasságával egyezik meg.
• px: relatív mértékegység, amely a megjelenítő egység (pl. képernyő) egy képpontjának méretét jelenti. Nyomtató-
nál a mérete a DPI-től függ.

• in: abszolút mérték, amely hüvelykben méri a távolságot. (1 hüvelyk = 2.54 cm.)
• cm: abszolút mérték, amely centiméterben méri a távolságot.
• mm: abszolút mérték, millimétert jelent.
• pt: abszolút mérték, nyomdai pontban mér : 1 hüvelyk = 72 pt.
• pc: abszolút mérték, a legelterjedtebb betűméretnek felel meg : egy pica (1 pc) az pontosan 12 pt.

3.5.3. Százalékok
A százalékos értékek mindig valamely más értékhez relatív mennyiséget adnak meg. A számértéket a % jelnek kell köz-
vetlenül követnie. Általában hosszméretet lehet százalékban megadni.

38
3.5.4. Címek
Néhány tulajdonság külső erőforrás címét (URI-ját) várja értékként. Ezeket egy url(" karaktersorozat előzi meg, és
egy ") karaktersorozat zárja. Valójában ez azért van, mert egy url „függvény” paramétereként, egyszeres vagy dupla
idézőjelek között kell a címet megadni, így az imént megadottól egy kicsit eltérő megadás is elképzelhető. Az idézőjelek
akár el is hagyhatóak, de ha szerepel, akkor a két idézőjelnek meg kell egyeznie. Használatukra a későbbiekben látunk
majd példát. . .

3.5.5. Színek
Színek megadására több módszer is létezik. Az egyik a korábbi HTML változatokból örökölt írásmód, amikor egy # jel
után hat tizenhatos számrendszerbeli számjegyet írunk. Ebből az első kettő a vörös, a következő kettő a zöld, míg az utolsó
kettő a kék színkomponens kódja. A CSS2 megengedi, hogy ha az egyes színkomponensek két számjegye megegyezik,
akkor csak az egyiket adjuk meg, ezzel egy mindössze háromszámjegyes színkódot előállítva.
Másik lehetőség, ha olyan színt akarunk használni, amelyhez van kulcsszó, akkor a szín nevét elég megadni. Ilyen
szín lehet a következő: aqua, black, blue, fuchsia, gray, green, lime, maroon, navy, olive, purple, red, silver, teal, white,
yellow.
Az rgb színkeveréssel előállított színnek egy a fentinél sokkal szemléletesebb módja, amikor az rgb függvény paramé-
tereként adjuk meg a három színkomponens intenzitásértékét. Ekkor vagy egyszerűen tízes számrendszerben adjuk meg
az intenzitásokat három [0; 255] intervallumba eső egész számmal, köztük vesszőt elhelyezve, vagy százalékos értékeket
adunk meg – köztük szintén vessző szerepel. Ilyen módon a fehér színt tehát a következőképpen lehet megadni :
1. white

2. #fff, #FFF
3. #ffffff, #FFFFFF
4. rgb(255, 255, 255)
5. rgb(100%, 100%, 100%)

39
4. fejezet

Szöveg megadására szolgáló elemek

Miután megismerkedtünk a HTML és a CSS nyelv alapvető nyelvtani felépítésével, elérkezett az ideje, hogy végre a
gyakorlatban is elkezdjünk weboldalakat készíteni. Mivel a hipertext is elsősorban szöveges dokumentum, ezért értelem-
szerűen a szöveg megadására szolgáló elemekkel célszerű kezdeni.
Ezek közül néhánnyal már megismerkedtünk, de van még rajtuk kívül néhány. Először ezeket vesszük sorra, egy-két
példán is bemutatva használatukat. Ezt követően a szöveg formázásához használatos tulajdonságokat vesszük sorra, és
bemutatjuk a doboz-modellt, amely a szöveg és a többi objektum formázását befolyásolja.

4.1. Szóköznek számító jelek


Kicsit furcsán hangzik a cím, de az igazság az, hogy több olyan jelet használhatunk, amelyet a böngésző valamilyen for-
mában szóközként jelenít meg. Amennyiben a HTML kódban két nem szóköznek minősülő szövegrész között bármilyen
szóköznek minősülő karakter található, mint a szóköz, tabulátorjel, újsor jel, megjegyzés, akkor azt a böngésző egyetlen
szóközként fogja megjeleníteni. Ezeket a szóköznek minősülő karaktereket az angol szaknyelvben egyszerűen a „white
space” kifejezéssel illetik.
Amennyiben ilyen „white space” karakterek egy elem nyitótagja előtt vagy zárótagja után találhatóak, akkor azok
megmaradnak (egyetlen szóközként), azonban a nyitótag utáni és a zárótag előtti szóközt a böngészők nem szokták
megjeleníteni (így van szabályozva ezek kezelése, tehát az ettől eltérő viselkedés számít hibásnak).
Van azonban másfajta szóköz is. A normál szóköznél ugyanis a sort a böngésző eltörheti, ugyanakkor vannak esetek,
amikor ez nem kívánatos. Ilyenkor nemtörhető szóközt, angolul „non-breakable space”-t kell használni. Ez a &nbsp;
karakterrefernciával adható meg. Ilyenkor az összeragasztandó szavak között normál szóközt nem szabad használni, csak
ezt a karakterreferenciát. Ekkor a böngésző ugyanolyan szóközt jelenít meg, mint rendesen, de ha ennél a szóköznél érne
véget a sor, akkor az előtte levő szó és az utána levő szó együtt kerül vagy nem kerül a következő sorba.

4.2. Struktúrált szöveg


Szöveg tipográfiai eszközökkel való struktúrálását teszik lehetővé a 18. szabályban ismertetett elemek.
Ezek közül leginkább az EM és a STRONG elemeket használjuk. A többi leginkább számítógépes technikai doku-
mentációk készítésénél használható.
A CODE, SAMP, KBD elemek alapbeállítása az írógép típusú betűkkel való megjelenés, a többi általában nem külön-
bözik a normál szöveg betűtípusától. Azonban a stíluslap segítségével könnyen egyéni megjelenést lehet mindegyikhez
adni. Ezzel azután egységes megjelenést lehet rendelni a programkódok (CODE), a program kimenete (SAMP), illet-
ve a beírandó szöveg (KBD) megjelenésének a dokumentációban. Hasonló módon lehet egyedi megjelenést rendelni a
mozaikszavak illetve a rövidítések kiemelésére, vagy a normál hivatkozások megadására.

40
18. Az EM, STRONG, DFN, CODE, SAMP, KBD, VAR, CITE, ABBR és ACRONYM elemek

<!ENTITY % phrase "EM | STRONG | DFN | CODE |


SAMP | KBD | VAR | CITE | ABBR | ACRONYM" >
<!ELEMENT %phrase; - - (%inline;)* >
<!ATTLIST %phrase;
%attrs; -- %coreattrs, %i18n, %events --
>

Az EM, STRONG, DFN, CODE, SAMP, KBD, VAR, CITE, ABBR, ACRONYM elemek szöveg szintű elemek, ame-
lyek a szöveg egy részének tipográfiai eszközökkel történő kiemelésére szolgálnak. Mint látható, mind nyitó- mind
zárótagjuk használata kötelező, aminek az az oka, hogy a nyitó- és a zárótag közé zárt szöveget (az elem tartalmát)
emeli ki valamilyen módon az elem.
Alaphelyzetben az EM elem (egyszerű kiemelés : emphasis) dőlt, azaz italic betűkkel jelenik meg. A STRONG (erős
kiemelés : strong emphasis) félkövér betűkkel jelenik meg. A CITE más dokumentumra való hivatkozást jelent (nem
a hipertextes hivatkozásról van szó!). A DFN egy kifejezés definiáló részét jelenti. A CODE egy programkód egyedi
tipográfiájának kialakítására szolgál (alaphelyzetben írógép típusú betűkkel jelenik meg). A SAMP egy program által
adott válasz megadására használható (szintén írógép betűk). A KBD a beírandó szöveg megadására szolgál (ez is írógép
betűs). A VAR egy változó nevének megadására használható. Az ABBR valamely rövidítés – pl. WWW – megadásánál
teszi lehetővé a speciális formázást, míg az ACRONYM mozaikszavak megadására szolgálhat.
A tényleges formázást a stíluslappal lehet beállítani. . .

Megjegyzés. A CITE csak a szöveget formázza, de a hivatkozott szöveg nem válik hiperhivatkozássá !
Az EM és a STRONG a szövegen belüli kiemelés bevált eszköze. Az előbbi dőlt, az utóbbi félkövér szöveget állít elő.
Együttes alkalmazása – amikor az egyikbe beleágyazzuk a másikat – félkövér, dőlt betűstílust eredményez. Amennyiben
egy szövegrészt ki kell emelni, mindig ezt a két elemet használjuk !
Megjegyzés. A régebbi HTML változatok tartalmaztak néhány olyan elemet, amelyek bedrótozott megjelenéssel rendel-
keztek félkövér, dőlt, írógép, kisebb méretű, nagyobb méretú betűk előállítására. Ezek jelenleg már elavultnak számítanak,
mivel az EM és a STRONG, illetve a stílusdefinícióval ellátott SPAN elem bármilyen szövegszintű kiemelés kialakítását
lehetővé teszi, míg ezek az elavult elemek kifejezetten a dokumentum struktúrájába építenék be a dokumentum megjele-
nését, amely a HTML 4-es verziójának alapfilozófiájával ellentétes. Ebből a megfontolásból kiindulva eme elemeket már
nem is mutatjuk be. . .
A nyugati nyelvek előszeretettel alkalmaznak mozaikszavakat (NATO, FBI, GmbH stb.) illetve rövidítéseket (Inc.,
Corp. stb.). Ezek nyomtatásban nem okoznak problémát, azonban egy beszédszintetizátornak tudnia kell, hogy ezeket nem
szóként kell felolvasni. Ilyenkor hasznos az ACRONYM illetve az ABBR elem használata, amely jelzi a beszédszinteti-
zátornak, hogy mozaikszóként illetve rövidítésként kell felolvasni a tartalmát. Ilyenkor a title paraméter (19. szabály)
segíthet abban, hogy mit is jelent a rövidítés vagy a mozaikszó :
<p>
<ABBR title=’World Wide Web">WWW</ABBR>
<ABBR lang=’fr’
title=’Soci&eacute;t&eacute; Nationale des Chemins de Fer">
SNCF
</ABBR>
<ABBR lang="es" title="Do&ntilde;a">Do&ntilde;a</ABBR>

41
<ABBR title="abbreviation">abbr.</ABBR>

19. A title paraméter

Nagyon sok elem rendelkezik egy paraméterrel, amely lehetővé teszi, hogy ha a felhasználó az egeret az elemhez
tartozó objektum fölé viszi, akkor egy buborék jelenjen meg, benne azzal a szöveggel, amelyet a paraméter értékül
kapott. Ez a title paraméter.

4.3. Idézetek
Idézet lehet egy szövegen belüli, vagy egész bekezdéseket tartalmazó is. Éppen ezért két elem létezik, amellyel idézeteket
lehet készíteni. A szövegszintű idézetekhez a Q, blokkszintű idézetekhez a BLOCKQUOTE elem használható.

20. A BLOCKQUOTE elem

<!ELEMENT BLOCKQUOTE - - ( %block; | SCRIPT )+ -- long quotation -->


<!ATTLIST BLOCKQUOTE
%attrs; -- %coreattrs, %i18n, %events --
cite %URI; #IMPLIED -- URI for source document or msg --
>

21. A Q elem

<!ELEMENT Q - - (%inline)* -- short inline quotation -->


<!ATTLIST Q
%attrs; -- %coreattrs, %i18n, %events --
cite %URI; #IMPLIED -- URI for source document or msg --
>

Mindkét elem ugyanazokkal a paramérekkel rendelkezhet. Ezek a szokásos id, class, lang, dir, title, style,
és az eseménykezelők paraméterei. Ezeken felül van még egy paraméter, a cite.

22. A cite paraméter

A cite paraméter értéke egy URI, amely arra a dokumentumra mutat, amely az idézet eredetijét tartalmazza. Bön-
gészőtől függ, hogy mit kezd a paraméter értékével, de a legszerencsésebb megoldásnak az számít, ha valamilyen
formában lehetővé teszi a megadott címen levő dokumentum betöltését.

42
A két elem tehát idézetek létrehozására alkalmas. A Q elem szövegszintű elem, amely a tartalma elé egy kezdő
idézőjelet, a tartalma után pedig egy záróidézőjelet helyez el. A kezdő- és a záróidézőjel nyelvtől függő szokott lenni,
azonban a legtöbb böngésző nem tudja, hogy mit kellene megjeleníteni, így a használandó idézőjelet célszerű a stíluslap
segítségével beállítani (lásd lentebb). . .
A BLOCKQUOTE egy blokk szintű elem, amely akár több bekezdést is tartalmazhat. Az elem tartalma előtt és után
alaphelyzetben nem jelenik meg semmilyen idézőjel (de beállítható ilyen), viszont nagyobb oldalmargók alkalmazásával
szokták a böngészők jelezni a szövegben, hogy idézetről van szó.1
Íme egy példa (átvéve [1]-ből) a BLOCKQUOTE alkalmazására :
<BLOCKQUOTE cite="http://www.mycom.com/tolkien/twotowers.html">
<P>They went in single file, running like hounds on a strong scent,
and an eager light was in their eyes. Nearly due west the broad
swath of the marching Orcs tramped its ugly slot; the sweet grass
of Rohan had been bruised and blackened as they passed.</P>
</BLOCKQUOTE>

4.3.1. Idézőjelek beállítása a stíluslap segítségével


Az idézőjel típusának beállításához két dolgot kell ismernünk. Az egyik a két pszeudo elem, amellyel bármely elemhez
generálni lehet valamilyen tartalmat: a :before elé, az :after utána írandó szöveg megadására szolgál. A másik az
ezekben használható content tulajdonság, amely a beszúrandó tartalmat adja meg.
Ezek az eszközök persze jóval többet is tudnak, nem csupán az idézőjelek beállítását. Elvileg2 akár számozott fejezet-
címeket is elő lehet állítani velük, vagy speciális kezdetű bekezdéseket például megjegyzések számára a „Megjegyzés :”
kezdőszöveg beszúrásával. Mindezekről a [2] bőven tartalmaz leírást, itt most csupán az idézetekhez szükséges mélység-
ben tárgyaljuk ezeket.

23. A content tulajdonság

A content tulajdonság a :before és :after pszeudo elemekkel együtt valamilyen tartalom generálására alkalmas.
Értékei a következők lehetnek:
• szöveg : A megadott szöveg fog megjelenni az előírt helyen (a tartalom előtt illetve után).
• URI : A megadott címen levő erőforrást kell megjeleníteni az előírt helyen (ha a böngésző nem tudja az erőforrást
kezelni, akkor nem jelenít meg semmit).
• számláló : A counter() vagy a counters() függvénnyel megadott számláló(k) értékét jeleníti meg.a
• open-quote és close-quote: A quotes tulajdonságban megadott megfelelő érték kerül a helyére.

• no-open-quote és no-close-quote: Valójában nem szúr be semmit, de növeli az idézet mélységét.


aA számlálókkal nem foglalkozunk, mivel egyenlőre a legtöbb böngésző még nem támogatja őket. . .

Az egyes nyelvek más-más idézőjelet használnak, így fontos, hogy az éppen használt nyelvnek megfelelő idézőjeleket
lehessen használni. Ennek egyik módja az imént ismertetett content tulajdonság, és a :before, :after pszeudo elemek
használata. De van ennél általában egyszerűbb megoldás is : a quotes tulajdonság.
1 A szerző személyes tapasztalata, hogy nem célszerű idézőjelet beállítani, mivel a nyitó idézőjelet ilyenkor minden bekezdés előtt megismétlik a

böngészők, míg a záró idézőjel csak a legtulsó bekezdés végén jelenik meg. Ez pedig nem felel meg a magyar tipográfiának. Helyette inkább más,
trükkösebb megoldást kell alkalmazni, vagy elhagyjuk az idézőjelet és másképpen jelezzük, hogy idézetről van szó.
2 A böngészők még nem feltétlenül támogatják ezeket !

43
24. A quotes tulajdonság

A quotes tulajdonság az egyes idézőjelek beállítására szolgál. Akárhány egymásba ágyazott idézetnek megfelelően be
lehet állítani idézőjeleket:
• none érték megadása esetén az idézőjelek nem jelennek meg.
• minden egyes szövegpáros egy-egy szinten állítja be az idézőjeleket. A páros első tagja a kezdő idézőjelet adja
meg, a második tagja a záró idézőjelet. Minden egyes újabb páros az előző idézőjelen belüli idézetnél alkalma-
zandó idézőjelpár beállítására szolgál.

A következő példa az angol és a norvég nyelvben használt idézőjelek beállítását mutatja :


Q:lang(en) { quotes: ’"’ ’"’ "’" "’" }
Q:lang(no) { quotes: "\00AA" "\00BB" "<" ">" }

/* A Q elem elé és után a most beállított idézőjelek kerüljenek: */


Q:before { content: open-quote }
Q:after { content: close-quote }
Bár az utóbbi két szabály alaphelyzetben érvényes a Q elemre, ha biztosak akarunk lenni, hogy az általunk beállított
idézőjeleket használja a böngésző, akkor az idézőjelek beállítása után érdemes megadni ezeket is.
Mivel nem minden lehetséges idézőjel található meg a billentyűzeten – például a magyar idézőjelek sem –, íme
példaként néhány karakter, amelyet (a kódjuk segítségével) használni lehet idézőjelek számára :
várható megjelenés kód megnevezés
" 0022 Az ASCII dupla idézőjel
’ 0027 Az ASCII aposztróf
< 2039 egyszeres balra néző idézőjel
> 203A egyszeres jobbra néző idézőjel
« 00AB dupla balra néző idézőjel
» 00BB dupla jobbra néző idézőjel
‘ 2018 felső 6-os idézőjel
’ 2019 felső 9-es idézőjel
„ 201C felső 66-os idézőjel
” 201D felső 99-es idézőjel
„ 201E alsó 99-es idézőjel
Mivel a magyar nyelvben az alsó 99, felső 99 párt kell használni, ezen belül pedig a », « párt, a magyar nyelvű
dokumentumban az idézetek akkor jelennek meg helyesen, ha ezek vannak beállítva :
Q:lang(hu) {quotes: ’\201E’,’\201D’,’\00BB’,’\00AA’}
Amennyiben egy adott nyelvű dokumentumban egy másik nyelvű idézet szerepel, akkor az idézőjel annak a nyelvnek
megfelelő, amelyben szerepel, és nem az idézett szöveg nyelvéhez igazodó. Azonban az idézeten belüli újabb idézetnél
már ugyanezt a szabályt alkalmazva a külső idézet nyelve dönt :
„The device of the order of the garter is „Honi soit qui mal y pense.” ”
„Il disait : « Il faut mettre l’action en < fast forward >.» ”
A két példa egy magyar nyelvű szövegben található idézet, tehát magyar szabályok szerint kell idézőjelbe tenni. Ezen
belül az első mondat angol, tehát benne a francia nyelvű idézetet angol szabályok szerint kell idézni. A második mondat
francia, tehát a benne szereplő francia szöveget a francia nyelv szabályai szerint kell idézni, míg az ebben levő angol
idézetet a belső idézetre vonatkozó francia szabály szerint.

44
Ilyen esetben a > (gyermek) elemre utaló szelektort kell használni, hogy az idézet helyesen működjön :
[LANG|hu] > * szelektor után megadva a quotes tulajdonságot, minden magyar nyelvű szövegben nyíló idézet he-
lyesen jelenik meg. Ugyanezt a szabályt alkalmazva a többi szükséges nyelvre is, elérhető, hogy minden szövegben a
belőle nyíló idézetek helyesen jelenjenek meg.

4.4. Alsó és felső index


Szövegen belül egyszerűbb matematikai képletek készítésénél használható a SUB és a SUP elem (25. szabály). Bonyo-
lultabb matematikai képletek alkotására a HTML nyelv nem alkalmas. Helyette a még a legtöbb böngésző által nem
feldolgozott MathML nyelv használható, amely HTML kódba illeszthető, vagyis a HTML egyfajta bővítése lehet. . .

25. A SUP és a SUB elemek

<!ELEMENT (SUB|SUP) - - (%inline;)* -- subscript, superscript -->


<!ATTLIST (SUB|SUP)
%attrs; -- %coreattrs, %i18n, %event --
>

A SUB elem alsó indexet hoz létre a tartalmából, míg a SUP felső indexet. Mindkettőnek a szokásos paraméterei
lehetnek : id, class, lang, dir, title, style és az eseménykezelők paraméterei.

Néhány példa az elemek használatára:


H<sub>2</sub>O
E = mc<sup>2</sup>
<span lang="fr">M<sup>lle</sup> Dupont</span>

4.5. Bekezdések
Általában a szöveget bekezdésekre szoktuk osztani. Ezúttal a bekezdés fogalma elsősorban a nyelvtani értelemben vett
bekezdéssel egyezik meg. Bekezdést a P elemmel lehet megadni, amelynek tartalma lesz egy bekezdésként megjelenítve
(itt már a bekezdés részben formai elem is!).
A bekezdés vizuális megjelenése szempontjából fontos, hogy mit kell tenni a szóközökkel, hogyan kell a bekezdést
sorokra bontani, milyen a bekezdés sorainak igazítása, hogyan kell (lehet) elválasztani a szavakat a sor végén, milyen
irányba kell a sorokban a szöveget írni (nyelvfüggő), milyen módon kell a bekezdés határait a környező objektumokhoz
képest kezelni.
Ezek egy része már a bekezdés formázásához tartozik, így a stíluslap segítségével állítandó be.
Egy bekezdés szövege a rendelkezésre álló szélességen belül elhelyezkedő sorokra bomlik. Alaphelyzetben a bön-
gésző a sort mindig annál a szóköznél töri el, amely utáni szó már nem fér el a sor végéig. Ezt a viselkedést bizonyos
esetekben célszerű megváltoztatni.
Az egyik ilyen eset, amikor két szó között nem volna szabad új sort kezdeni, mint például, amikor egy mennyiség és a
mértékegysége közötti szóköznél kell megtiltani a sortörést. Erre a már korábban ismertetett &nbsp; karakterreferenciát
használhatjuk : a szóköz helyett ezt kell az összeragasztandó szavak közé írni.
A másik eset, amikor valahol akkor is szeretnénk sortörésre bírni a böngészőt, ha még nem értük el a sor végét. Erre
a BR elem kínál lehetőséget.

45
26. A P elem

<!ELEMENT P - O (%inline;)* -- paragraph -->


<!ATTLIST P
%attrs; -- %coreattrs, %i18n, %events --
>

A P elem tartalma egy bekezdésként fog megjelenni. Maga az elem blokk szintű elem, a tartalma azonban semmilyen
blokk szintű elemet nem tartalmazhat, csak szövegszintű elemet.
Az üres P elemek használatát kerülni kell, mivel a böngészők az üres P elemeket figyelmen kívül szokták hagyni
(feltéve, hogy helyesen működnek)!

27. A BR elem

<!ELEMENT BR - O EMPTY -- forced line break -->


<!ATTLIST BR
%coreattrs; -- id, class, style, title --
>

A BR elem sortörés kikényszerítését végzi. Egyetlen nyitótagból áll, tartalma és zárótagja nincs. Ahol a szövegben
a nyitótagja szerepel, ott a böngésző a soron belüli helyzettől függetlenül eltöri a sort, és az utána levő szöveget a
következő sorban kezdi megjeleníteni.
A fenti definícióban nem szerepel, de megadható a clear paraméter, amely a sortörés utáni sornak az úsztatott objek-
tumokhoz képest való viselkedését szabályozza (lásd az úsztatott objektumoknál, a 9.3. fejezetben). Helyette azonban
célszerűbb a stíluslapon megadható clear tulajdonságot használni. . .

A HTML dokumentumokban levő szöveget a böngészők többsége úgy jeleníti meg, hogy a sor végére kerülő szavakat
nem próbálja meg elválasztani. Ennek egyik káros következménye, hogy sok magyar weboldalon az elválasztást kézi
módszerrel próbálják imitálni. Ennek eredménye a sor közepén megjelenő kettévágott szó lehet, így ezt a gyakorlatot
minél előbb el kellene felejtei.
A HTML nyelvben a kötőjelet normál karakternek tekintik, amely nem vált ki sortörést, ha a sor utolsó szavában
szerepel. Van azonban egy lágy elválasztó jel, amelyet bizonyos böngészők képesek felhasználni arra, hogy a sor végére
kerülő szót ezen a helyen elválasszák. Ezek a böngészők ilyenkor a sor végén megjelenítik a szükséges elválasztó jelet, és
a szó további részével kezdik a következő sort. Azok a böngészők, amelyek nem kezelik ezt a lehetőséget, a szót továbbra
is egyben viszik a következő sorra, viszont a lágy elválasztást nem jelenítik meg kötőjelként.
A lágy elválasztó jel a &shy; karakterreferenciával adható meg. Amennyiben szeretnénk, hogy az erre képes bön-
gészők a sor végére kerülő szavakat elválasszák, ezt helyezzük el minden olyan helyre, ahol a szavak elválaszthatóak.
Azonban nem valószínű, hogy ennek a használata elterjed, hiszen minden szó összes lehetséges elválasztási helyére beír-
ni ezt a karakterreferenciát – vagyis gyakorlatilag az egész szöveget szótagolva írni – iszonyatosan fárasztó feladat. . .
Vannak esetek, amikor egy szövegrészt úgy szeretnénk megjeleníteni, hogy minden abban elhelyezett szóköz, sortörés
az eredeti formájában maradjon. Erre használható a PRE elem.
A PRE elem gyakorlatilag azt közli a böngészővel, hogy a tartalma már meg van formázva olyanra, ahogyan meg
kell jeleníteni. Ez az egyetlen elem, amelyen belül minden, egyébként egyetlen szóközzé összeolvasztandó karakter külön

46
28. A PRE elem

<!ENTITY % pre.exclusion "IMG|OBJECT|BIG|SMALL|SUB|SUP">


<!ELEMENT PRE - - (%inline;)* -(%pre.exclusion;) -- preformatted text -->
<!ATTLIST PRE
%attrs; -- %coreattrs, %i18n, %events --
>

A PRE elem tartalma pontosan úgy kerül megjelenítésre, ahogyan szerepel a forráskódban. Minden szóköz, újsor jel
megmarad. Leginkább programkód, vagy programkimenet megadására célszerű használni.

megjelenítésre kerül. Ellenben ha az előre formázott szöveg egy sora hosszabb, mint ami a rendelkezésre álló helyen elfér,
akkor sem történik sortörés, hanem tovább íródik, ami esetleg a bögészőablak vízszintes görgetését teszi szükségessé a
sor további részének megjelenítésére.
Az elemet csak akkor szabad használni, ha fontos, hogy úgy jelenjen meg, ahogyan megadtuk (programkód esetén
például). Az alapértelmezett szövegformázási szabályok felülbírálására soha nem szabad használni !
Mivel az elem kifejezetten programkódok megadására szolgál, ezért a CODE elemhez hasonlóan írógép típusú betúk-
kel szokott megjelenni a tartalma.

4.6. A szöveg formázása


4.6.1. Betűtulajdonságok
Weboldalak esetében a betűtípusok beállítása problematikus lehet, mivel nem tudható, hogy a felhasználó milyen bön-
gészőt használ, és az adott böngésző – részben az operációs rendszertől is függően – milyen betűtípusokhoz fér hozzá.
Természetesen elvileg lehetőség van arra is, hogy a böngészőnek előírjuk valamilyen betűtípus letöltését, és azután a hasz-
nálatát. Ezzel azonban az a baj, hogy a betűtípus letöltése ismét időbe telik, tehát lassíthatja az oldal megjelenését. Emiatt
a továbbiakban ezzel a témával csak nagyon érintőleges foglalkozunk, akit a többi is érdekel, az a [2]-ben megtalálhatja a
többi ismeretet is (az egész 15. fejezet ezzel foglalkozik). . .
A CSS2-ben a betűtípusra vonatkozó információkat a következő – külön tulajdonsággal állítható – csoportokra lehet
felbontani :
Betűcsalád/betűkészlet (font family) A betűkészlet (font family) felel meg leginkább a szövegszerkesztésben betűtí-
pusként emlegetett fogalomnak. Itt azért nevezzük inkább „családnak”, mert nem egyetlen betűtípusról, hanem
betűváltozatok egész csoportjáról van szó. Egy ilyen készlet általában tartalmaz különböző stílusú betűket (normál,
dőlt, más-más vonalvastagságú stb.), amelyek küzül aztán még ki kell választani a megfelelőt. A betűkészlet neve
általában lehet „Helvetica”, „New Century Schoolbook”, „Times” stb. Általában kétféleképpen külön kategóriába
sorolhatóak: talpakkal ellátott (serif) vagy talpatlan (san serif), illetve írógép típusú (ahol minden betű szélessége
azonos) vagy proporcionális (ahol a betűk szélessége változik).
Betűstílus (font style) Álló (normal), döntött (oblique) vagy dőlt (italic) a betű. Nem minden rendszerben/böngészőben
érhető el döntött betű, ilyenkor helyette is dőlt betűk jelennek meg.
Betűváltozat (font variant) Ez határozza meg, hogy a kisbetűk alakja megegyezik a nagybetűkével, csak alacsonyabb
(kiskapitális: small-caps), vagy valódi kisbetűkként jelennek meg (normál).
Betűvastagság (font weight) Ez határozza meg a betűk egyes vonalainak vastagságát (nem keverendő össze az antikva
betűtípussal). A normál betűvastagsághoz képest lehet vékonyabb és vastagabb is a betű vonala.

47
Betűsűrűség (font stretch) A normál betűközhöz képest beállítható sűrített vagy ritkított betűköz.
1
Betűméret (font size) A betű mérete általában pontban (1 pont = 72 hüvelyk) van megadva. Minden más tulajdonságnál
az em és ex relatív mértékegységek az elem betűméretéhez képest értendők, míg a font-size tulajdonság esetén –
mivel ez magát a betűméretet állítja be – az elem szülőjének betűméretét jelentik.

29. A font-family tulajdonság

A font-family tulajdonság a betűkészlet megadására szolgál. Több betűkészlet is megadható. Ilyenkor először az elsőnek
megadott betűtípust próbálja a böngésző használni. Amennyiben ez nem lehetséges, úgy a próbálkozást a következő-
vel folytatja mindaddig, amíg egy elérhető betűkészlethez nem ér. Ezért célszerű a lista végére mindig egy általános
betűkészletet megadni.
A lista elemeit vesszővel kell elválasztani egymástól. Ennek ellenére, ha a betűkészlet neve tartalmaz szóközt, akkor
ajánlatos idézőjelek közé tenni a nevet. A lista arra is használható, hogy megadjuk a használandó betűkészletet, ha egy
bizonyos karakter az elsődlegesen használható betűkészletben nem létezik (így lehet például matematikai szimbólumo-
kat elérhetővé tenni).
Az általános betűkészletek nevei azokat a betűkészleteket jelölik, amelyek mindenképpen elérhetőek a böngészőben,
mivel ezeket be lehet állítani, hogy melyikre mit használjon az operációs rendszer által kínált készletből.
• serif: az alapbeállításban az antikva (talpas) betűkhöz rendelt betűkészletet kell használni.
• sans-serif: az alapértelmezett talpatlan betűket kell használni.
• cursive: az alapértelmezett dőlt betűket kell használni.
• fantasy: az alapértelmezett „fantasy” betűkészletet kell használni (nem biztos, hogy létezik, ilyenkor a serif
használatos helyette).

• monospaced: az alapértelmezett írógép betűtípust kell alkalmazni.

30. A font-style tulajdoság

A font-style tulajdonság a betűstílust határozza meg. Lehetséges értékei :


• normal: normál, álló betűk;
• oblique: döntött betűk, vagy dőlt, ha nem áll rendelkezésre döntött betű ;
• italic: dőlt betűk ;
• inherit: a szülőtől örökölt érték használata (akkor hasznos, ha egyébként be lenne állítva az elemre valamilyen
érték).

48
31. A font-variant tulajdonság

A font-variant tulajdonság adja meg, hogy normál betűket, vagy kiskapitális betűket kell-e használni az elemhez tartozó
szöveg megjelenítésére. Lehetséges értékei ennek megfelelően :
• normal: normál betűk, azaz (latin és görög írásnál) a kisbetűk alakja eltér a nagybetűkétől.
• small-caps: kiskapitális betűk, azaz a kisbetűk alakja ugyanolyan, mint a nagybetűké, de alacsonyabbak.
A tulajdonság nincs hatással azokra a betűkészletekre, amelyben egy betűnek csak egy alakja van (például a kínai
írásnál).

A következő példa a font-style és a font-variant tulajdonságok használatát mutatja. A H3 elemet kiskapitálissá teszi,
az ebben szereplő EM elem tartalmát a kiskapitálison felül döntötté is teszi :
H3 { font-variant: small-caps }
H3 EM { font-style: oblique }

32. A font-weight tulajdonság

A font-weight tulajdonság a betűk vonalainak vastagságát szabályozza. Az értékeinek megadásánál két lehetőségünk
van : 100 és 900 között százas lépésközzel beállítható a betűvastagság. Ilyenkor az egyes értékek legalább olyan vas-
tagok, mint az egyel kisebb érték (olyan betűkészletnél, ahol nincs kilenc vastagság, így biztosítható, hogy nem kell
mind a kilenc értéknek különböznie). A másik értékfajta a következő kulcsszavak valamelyikének megadása lehet :

• normal: a 400 értékkel egyezik meg. A normál betűvastagságot jelöli.


• bold: a 700 értékkel egyezik meg. Félkövér betűket eredményez.
• bolder: az örökölt betűvastagságnál egyel vastagabb – feltéve, hogy van ilyen, mivel a 900-nál tovább nem
lehet menni.
• lighter: az örökölt betűvastagságnál egyel vékonyabb – feltéve, hogy van ilyen, mivel 100-nál vékonyabb
már nem lehet.
A leszármazottak mindig a számított értéket öröklik, így ha vastagabbat állítunk ott be a 400-nál, de nincs 500, akkor
is az 500 érték öröklődik, bár megjelenésében a 400 marad.

49
33. A font-stretch tulajdonság

A font-stretch tulajdonság a betűközt határozza meg. Pontosabban a betű szélességét állítja, amely természetesen a
betűközt is befolyásolja. Lehet relatív értékként megadni a narrower (keskenyebb), a wider (szélesebb) kulcsszót.
Az abszolút kulcsszavak a következők a legkeskenyebbtől a legszélesebb felé :
1. ultra-condensed
2. extra-condensed
3. condensed
4. semi-condensed

5. normal
6. semi-expanded
7. expanded
8. extra-expanded
9. ultra-expanded
A böngészők nem mindegyike képes ezt a tulajdonságot értelmezni.

4.6.2. Betűméret beállítása

34. A font-size tulajdonság

A font-size tulajdonság a betűméret beállítására szolgál. Megadható abszolút méret, relatív méret, százalékos érték,
vagy hosszérték.

• Az abszolút méret a következő kulcsszavak egyikét jelenti : xx-small, x-small, small, medium, large,
x-large, xxlarge. Ezek között általában 1.2 a szorzó, vagyis a 12 pontos normal esetén a large 14,4
pontos betűméretet jelent.
• A relatív méret kulcsszavai a szülő elem betűméretéhez képesti változást jelentik. Ezek a kulcsszavak a követke-
zők : larger és smaller. Mindkét kulcsszó egy értéket lép a fenti skálán felfelé illetve lefelé.

• A hosszérték a megszokott mértékegységekkel történő beállítást jelenti. A relatív mértékegységek a szülő elem
betűméretéhez viszonyított méreteket jelentenek.
• A százalékos megadás szintén a szülő elem betűméretéhez viszonyított relatív méret beállítását teszi lehetővé.

50
35. A font-size-adjust tulajdonság

Az egyes betűméreteknél a nagy- és a kisbetűk magasságának az aránya eltérő lehet. Ezzel együtt tapasztalhattuk
például szövegszerkesztés során is, hogy az egyes betűkészletek nagybetűi sem egyforma méretűek. Emiatt ha a kívánt
betűkészlet nem érhető el, és mással kell helyettesíteni, akkor előállhat az a probléma, hogy a helyettesítő betűkészlet
más méretű betűi miatt az oldal kívánt kinézete nem felel meg a valóságosnak.
A font-size-adjust tulajdonság ezt a problémát orvosolja a betűméret skálázásával. Értéke egy valós szám lehet, amely
szorzótényezőként veendő figyelembe a szöveg méretezésénél. Ugyanakkor az em és ex mértékegységek jelentését
ez a szorzótényező nem befolyásolja. A beállított szorzótényezőt a betűkészlet saját – változó – arányával szemben
mindenképpen megtartja az elem szövege. Ezt a viselkedést letiltja – vagyis a betűkészlet saját arányát alkalmazza – az
alapértelmezett none érték.

4.6.3. A betűformázások egyszeri megadása, a font tulajdonság

36. A font tulajdonság

A font tulajdonság a többi font- kezdetű tulajdonság értékének egyszerre történő beállítására szolgál. Ezen felül néhány
speciális érték beállítását is lehetővé teszi, amelyeket csak ezzel a tulajdonsággal lehet beállítani. Először a betűstílust,
a betűváltozatot, majd a betűvastagságot lehet megadni, amit követhet a betűméret vagy a betűméret és utána egy / jel
után a sormagasság (line-height tulajdonság), végül következhet a betűkészlet. Legalább a betűméretet meg kell adni,
ha így használjuk a tulajdonságot. Ilyen esetben a meg nem adott értékek az adott elemre érvényes alapértelmezett
értéket kapják meg.
Egy alternatív lehetőség az alábbi kulcsszavak valamelyikének használata. Ezek az operációs rendszer bizonyos célokra
használt szövegbeállításait állítják be az adott elemre.
• caption: A címkézett űrlap-elemeken (gombok, legördülő menük) használt betűt állítja be.

• icon: Az operációs rendszer által az ikonok feliratához használt betűt állítja be.
• menu: Az operációs rendszer által a menükben használt betűt állítja be.
• message-box: A párbeszédablakokban használt betűt állítja be.

• small-caption: A [2] szerint „The font used for labeling small controls.”a
• status-bar: Az ablak státuszsorában megjelenő szöveg betűit állítja be az adott elemre.
a Aki tudja, mi ez a „small control”, tudassa velem is. . .

4.6.4. A sor magassága


A sor magassága meghatározza a két szomszédos sor alapvonalának távolságát. Más néven ezt a tulajdonságot nevez-
zük sorköznek. A sor magasságának megadására szolgáló tulajdonság a line-height. Amennyiben a szöveg-szintű elemek
tartalma, amelyek egy sorba kerülnek, különböző magasságú dobozokat hoznak létre, akkor a sor magassága a legmaga-
sabban kezdődő doboz tetejétől a legmélyebbre érő doboz aljáig terjedő távolság lesz. Egy szöveg-szintű doboz magassága
minden esetben a szöveg méretétől függ, ha a line-height tulajdonsággal más magasság nincs beállítva.

51
37. A line-height tulajdonság

A line-height tulajdonság minden elemre alkalmazhatóan a sormagasságot állítja be. Értelemszerűen egy szöveg-szintű
elem esetén az elem tartalmának megjelenítésére létrejövő szöveg-szintű dobozét, míg blokk-szintű elem esetén a belőle
létrejövő dobozba kerülő minden olyan sorét, amelynek nincs külön beállítva a sormagassága. Ilyenkor a legkisebb
alkalmazandó magasságot adja meg, amelynél egyik sor magassága sem lehet kisebb.
Lehetséges értékei a következők:
• normal (alapértelmezés) : A sor magassága a szöveg betűmérete, illetve a sorba kerülő elemek sormagassága
által igényelt méret alapján dől el (ez egyben azt is jelentheti, hogy örökli az elemet tartalmazó elem sormagas-
ságát).
• hosszérték: A sormagasságot pontosan a megadott értékre állítja. Relatív hosszérték az elem font-size tulajdon-
ságához értendő. Nem lehet negatív.
• szám : A normal érték esetén alkalmazandó magasság ennyiszeresét kell alkalmazni. Ezzel lehet a szövegszer-
kesztésből ismert másfeles, dupla sorközt beállítani. Negatív nem lehet.
• százalék : Az elem betűméretében méri a sormagasságot. Ha például azt akarjuk, hogy a betűméret 1,4-szerese
legyen a sormagasság, adjunk meg értékként 140%-ot.

Amennyiben a sorban olyan szöveg-szintű doboz is található, amelynek magassága kisebb a sor teljes magasságánál,
akkor a doboz többféleképpen is elhelyezkedhet a vertical-align tulajdonság értékétől függően.

52
38. A vertical-align tulajdonság

A vertical-align tulajdonság egy szöveg-szintű elem, vagy egy táblázat cellája esetén alkalmazható annak megadására,
hogy az elemet tartalmazó doboz hogyan kerüljön a sorba. Lehetséges értékei a következők :
• baseline (alapértelmezés) : A doboz alavonala a sor alapvonalára esik. Amennyiben a doboznak nincs alap-
vonala (szöveg-szintű kép esetén például), a doboz alja kerül a sor alapvonalára.
• middle: A doboz középvonala függőlegesen a sor fél x-magasságával lesz a sor alapvonala fölött. Táblázatok
esetében a cellatartalom függőlegesen középre igazítását jelenti ez az érték (lásd a táblázatoknál).
• sub: Az alapvonalnál mélyebbre kerül a doboz, alsó indexet hozva létre. Ez azonban az elem betűméretét ma-
gában nem befolyásolja.
• super: Az alapvonalnál magasabbra kerül a doboz, felső indexet hozva létre. Ez sem befolyásolja a betűméretet.
• text-top: A tartalmazó elem betűméretének tetejéhez igazítja a doboz tetejét.
• text-bottom: A tartalmazó elem betűméretének aljához igazítja a doboz alját.
• százalék : A sormagasságban (line-height) mérve megemeli (pozitív értéknél) vagy lesüllyeszti (negatív értéknél)
a dobozt a baseline értékéhez képest.
• hosszérték: A megadott értékkel megemeli (pozitív értékre) vagy lesüllyeszti (negatív értékre) a dobozt a
baseline állapothoz képest.
• top: A sor tetejéhez igazítja a doboz tetejét.
• bottom: A sor aljához igazítja a doboz alját.

Íme néhány példa a sormagasság állítására, ahol mindhárom ugyanazt eredményezi :


DIV { line-height: 1.2; font-size: 10pt } /* szám */
DIV { line-height: 1.2em; font-size: 10pt } /* hosszérték */
DIV { line-height: 120%; font-size: 10pt } /* százalék */

4.6.5. Az első sor behúzása


Általában egy hosszabb szövegnél sorkizárt bekezdéseket szoktunk alkalmazni, köztük nem hagyva extra térközt. Ekkor
az egyes bekezdések kezdetét a bekezdés első sorának beljebb kezdésével, azaz az első sor behúzásával szokás jelezni.
Weboldalon ennek a fajta bekezdésformázásnak az egyik része – a bekezdések közötti margó nullára állításával meg-
szünetett extra térköz mellett, és a következő szakaszban bemutatásra kerülő sorkizárt igazítás mellett – a text-indent
tulajdonsággal szabályozható első sor behúzása.

53
39. A text-indent tulajdonság

A text-indent tulajdonság szabályozza a bekezdés első sorának behúzását. Értéke lehet hosszérték vagy százalék. Alap-
értéke nulla, ami azt jelenti, hogy nincs behúzás, azaz az első sor ugyanott kezdődik, mint a többi.
Hosszérték esetén a megadott mérték lesz az első sor behúzása a balmargóhoz (jobbról balra írás esetén a jobbmargó-
hoz) képest. A tipográfiai szabályoknak az 2 em érték felel meg a leginkább.
Százalékos érték megadása esetén a bekezdést tartalmazó doboz szélességének százalékában történik a behúzás mega-
dása.
Az érték lehet negatív is (függő behúzás), de ennek tényleges kezelése az egyes böngészőknél eltérő lehet.

Amennyiben a weboldalon a szöveget úgy szeretnénk megjeleníteni, ahogyan egy könyvben szokás, akkor a fejezet-
cím utáni bekezdésnél nulla, a többinél 2 em első sor beházást kell beállítani. Ez a CSS esetében úgy adandó meg, hogy
előbb megadjuk az általános esetet: minden bekezdésnek legyen behúzása :
P {text-indent: 2em}
Ezután a dokumentumban használni kívánt címsorok utáni bekezdésekre az általános szabályt felülbírálva meg kell szün-
tetni a behúzást:
H1+P, H2+P, H3+P {
text-indent: 0
}
Ebben az esetben feltételeztük, hogy a dokumentumban csak H1, H2, H3 elemeket használunk a fejezetcímek megadására.

4.6.6. A bekezdés igazítása


Szövegszerkesztésből már ismert, hogy egy bekezdést négyféleképpen lehet igazítani. Bár a weboldalon a hagyományos
igazításhoz ragaszkodva a böngészők alaphelyzetben a szöveget balra igazítva jelenítik meg, a sorkizárt, jobbrazárt és
középre zárt igazítások szintén beállíthatóak a text-align tulajdonság segítségével.

40. A text-align tulajdonság

A text-align tulajdonság a bekezdés szövegének igazítását határozza meg. Lehetséges értékei : left (alapértelmezés)
a balra igazításhoz, right a jobbra igazításhoz, center a középre igazításhoz, justify a sorkizárt igazításhoz,
valamint megadható egy szöveg, amely esetben egy táblázat celláját a böngésző úgy igazítja az adott oszlopban, hogy
a cella tartalmában a megadott szöveg mindig egymás alá kerüljön (ez utóbbi, ha a böngészőben működik egyáltalán, a
mértékegységekhez, vagy a tizedes jelhez történő igazítást teszi lehetővé).

Bár nyomtatott szövegben – és képernyőn is – a legesztétikusabb a sorkizárt igazítás, ám weboldalak esetében a


sorkizárt igazítás alkalmazásánál problémákba ütközhetünk. A probléma a sorkizárt szöveg előállításából adódik : ahhoz,
hogy a sorok a balmargótól a jobbmargóig tartsanak, a szóközöket kell megnövelni, széthúzva ezzel a sort. Az ebből
adódó probléma: rövid sorok esetén, vagy ha a sor utolsó szava nagyon hosszú, és már nem fér el, akkor nagyon szét
kell húzni a szavakat, ami szokatlanul nagy szóközöket, szabályos lyukakat eredményez a szövegben, ami nagyon csúnya
látványt nyújt.
Ennek a problémának a megoldására lehet használni az elválasztást : nem az egész szó kerül át a következő sorba,
hanem csak a szó azon része, amely az elválasztási pont után kerül. Az elválasztás megfelelő alkalmazásával el lehet érni,
hogy a sor széthúzásából eredő megnövelt szóközöket észre sem lehet venni a szövegben.

54
Mi akkor a probléma. . . ? Az, hogy a weboldalon a szöveg általában nincsen elválasztva, mert a böngészők nem
kezelik az elválasztást, elsősorban amiatt, hogy az egyes nyelvekre más elválasztási szabályok vonatkoznak. Van ugyan
egy lehetőség elválasztási pont megadására: a &shy; karakterreferencia egy elválasztási pontot helyez el, ahol ha a
sor végére kerül a szó, azt el lehet választani, egy elválasztásjelet elhelyezve a sor végén maradó szórész után. A gond
az, hogy nem ismert, hogy melyik szó fog a sor végére kerülni, mivel ez a böngésző ablakától is függ. Ezért ha ezt a
lehetőséget ki akarjuk használni, akkor minden elválasztási pontot – vagy legalább minden szóban egyet – meg kellene
adni, ami jelentős többletmunkát jelent.
Vannak olyan weboldalak, amelyeken a sorkizárt szöveget meghatározott szélességű oszlopba kényszerítik egy táb-
lázat cellája segítségével. Ez a megoldás viszont azért kerülendő, mert a megoldás a böngésző számára nagyon sok
memóriát igényelhet, ha a böngésző a táblázat teljes tartalmát letölti, mielőtt a megjelenítéséhez szükséges méreteket
meghatározza. Volt a Netscape böngészőnek olyan változata is, amely az ilyen oldalakat kis memóriájú gépeken képtelen
volt megjeleníteni, és helyette egy idő után egyszerűen „lefagyott”.
Természetesen van más megoldás az adott szélességű szöveg előállítására (DIV elem megadott width tulajdonsággal),
ami kevesebb memóriát igényel, ám az a gond itt is fennál, hogy ha a böngésző ablaka nem olyan széles, mint kellene,
akkor a szöveg egy része kilóg. Tehát ez a megoldás is veszélyezteti a weboldal általános elérhetőségét.
A fentiek azt mutatják, hogy jól meg kell gondolni, hogy a sorkizárt igazítást hol alkalmazzuk : csak akkor alkal-
mazzuk, ha biztosak vagyunk benne, hogy széles helyen jelenhet meg a szöveg. Segíthetjük a böngészőt az esztétikus
tördelésben, ha a hosszabb szavakban a legjobb elválasztás helyén elhelyezünk egy &shy; karakterreferenciát, lehetővé
téve, hogy ha esetleg ez a szó a sor végére kerülne, akkor a megadott ponton elválasztható legyen.
Internetezőként a fentiekből pedig azt a tanácsot lehet leszűrni, hogy ha egy sorkizárt igazítású szövegben túl nagy
szóközöket látunk, akkor ne a weboldal készítőjét szidjuk, hanem vegyük figyelembe a fenti korlátokat, és esetleg próbál-
juk meg azzal orvosolni a problémát, hogy megváltoztatjuk a böngésző ablakának a szélességét. Akár egy kis változtatás
is elég ahhoz, hogy a hosszú szó ne a sor végére kerüljön, és máris kellemesebb látványt nyújthat a szöveg tördelése. . .
Megjegyzés. Egyes régebbi böngészők nem ismerik a sorkizárt igazítást. Ezek a sorkizártnak beállított szöveget is bal-
razártan – jobbról balra íródó szövegben jobbrazártan – jelenítik meg.

4.6.7. Szövegdekorációk
Lehetőség van a szöveg aláhúzására, áthúzására, villogtatására is a text-decoration tulajdonsággal. Ezzel le lehet tiltani,
vagy a böngésző alapbeállítása ellenére elő lehet írni például a hivatkozások szövegének aláhúzását is.

55
41. A text-decoration tulajdonság

A text-decoration tulajdonság néhány szövegdekorálási tulajdonság beállítását teszi lehetővé. A tulajdonság alapér-
telmezett értéke – a legtöbb elemnél – none, ami azt jelenti, hogy az egyik dekoráció sincs beállítva az ezzel a tu-
lajdonsággal beállíthatóak közül. A többi lehetséges dekoráció akár egyenként, akár egymással társítva beállítható.
Amennyiben egynél több értéket állítunk be, az értékek közé szóközt kell tenni. A lehetséges értékek és jelentésük a
következő :
• underline: aláhúzottan jelenik meg a szöveg, amely az elemhez tartozik.
• overline: a szöveg fölött jelenik meg egy vonal („föléhúzás”).
• line-through: a szöveg áthúzva jelenik meg.
• blink: a szöveg villogva jelenik meg (nem minden böngészőben működik).
A vonalak az elem color tulajdonsága által meghatározott színnel jelennek meg. Ha az elem blokk-szintű, akkor minden
benne levő szöveg-szintű dobozra érvényes lesz a tulajdonság ; szöveg-szintű elemnél az általa generált szöveg-szintű
dobozokra. Amennyiben egy blokk-szintű elemre adjuk meg ezt a tulajdonságot (például aláhúzást), majd egy benne
levő szöveg-szintű elem megváltoztatja a szövegszínt, az aláhúzás továbbra is a blokk-szintű elem color tulajdonsága
által meghatározott színű lesz – de a szöveg természetesen a hozzá megadott színű. . .

42. A text-shadow tulajdonság

A text-shadow tulajdonság egy vesszővel elválasztott listát vár értékként (egy elemű listánál nincs vessző). Alapértel-
mezésben a lista a none értékből áll, ami azt jelenti, hogy nincs a szöveg árnyékolva. A lista minden eleme egy-egy
árnyékolást határoz meg, amelyek a megadási sorrendben kerülnek megjelenítésre, tehát minden további árnyék meg-
jelenése az előző árnyéktól is függ. Ezt a tulajdonságot sok böngésző még nem ismeri. Az árnyékok nem változtatják
meg a szöveget tartalmazó doboz méreteit, de kilóghatnak belőle.
Minden árnyékra meg lehet adni annak színét, és meg kell adni ezután a szöveghez képesti pozícióját három hosszérték
megadásával. Ezekből az első a vízszintes eltolást jelenti a szövegtől jobbfelé (negatív értékkel lehet balra eltolni). A
második hosszérték adja meg a függőleges eltolást a szövegtől lefelé (negatív érték tolja felfelé). A harmadik hosszérték
az árnyék vastagságát határozza meg, amelyen az árnyék látszik. Ennek nulla értéke jelenti, hogy az árnyék pontosan
ugyanolyan vastag, mint az eredeti szöveg. Amennyiben színt nem adunk meg, az elem color tulajdonsága határozza
meg az árnyék színét.

Íme egy szabály, amely a H1 elem szövegének beállít egy árnyékot, amely a szöveg színével azonos színű, 0,2 em-
nyivel a szövegtől lefelé és jobbra helyezkedik el:
H1 { text-shadow: 0.2em 0.2em }
A következő példa az árnyékot szintén a szöveg alá és jobbra helyezi el, de 5 pixeles átmenetet ad hozzá, és az árnyék
színét pirosra állítja:
H2 { text-shadow: 3px 3px 5px red }
Végül egy példa következik többszörös árnyék megadására. Az első árnyék jobbra lefelé jelenik meg piros színnel.
A második árnyék átfedi az elsőt, sárga színű, elmosódó átmenettel is rendelkezik, és balra lefelé jelenik meg. Végül a
harmadik árnyék jobbra felfelé jelenik meg, és nincs színbeállítása, így az elem color tulajdonsága határozza meg ennek
a színét:

56
H2 { text-shadow: 3px 3px red, yellow -3px 3px 2px, 3px -3px }

4.6.8. Betűköz és szóköz beállítása


Lehetőség van annak szabályozására is, hogy mekkora legyen a távolság a szavakon belül illetve szavak között az egyes
betűk közt. A szavakon belül a betűk távolságát betűköznek szokás nevezni, ezt a letter-spacing tulajdonság állítja be. A
szóközt a word-spacing tulajdonság befolyásolja.

43. A letter-spacing tulajdonság

A letter-spacing tulajdonság a betűk közti távolságot befolyásolja. Alapértelmezett értéke normal, amely azt jelenti,
hogy az adott betűkészletre érvényes normál betűközt kell alkalmazni. Ez az érték egyben lehetővé teszi a böngészők-
nek a betűköz változtatását a sorkizárt igazítás kialakítása céljából. Éppen ezért más érték beállítása megadkadályoz-
hatja a sorkizárt igazítást.
A tulajdonság további értékeiként hosszérték adható meg. A megadott hosszérték a normal értékből származó alap-
távolsághoz adódik hozzá. Ebből következően a negatív érték sűríti a szöveget, a pozitív érték ritkítja. Ilyen értékek
beállítása esetén a böngésző nem fogja a sorkizárt igazításhoz módosítani a betűközt, tehát hosszérték megadásával a
sorkizárt igazítást megakadályozzuk!

44. A word-spacing tulajdonság

A word-spacing tulajdonság a szavak közötti távolságot szabályozza. Alapértelmezett értéke normal, ami azt jelenti,
hogy a betűkészletre érvényes szóközméretet alkalmazza a böngésző. Ezt az értéket a böngésző sorkizárt szöveg esetén
a szükséges mértékben megnövelheti.
További értékként megadható egy hosszérték, amely egyrészt hozzáadódik a normál szóköz méretéhez, másrészt meg-
akadályozza a szóköz megváltoztatását a sorkizárt igazítás kialakítására. Ez tehát azt jelenti, hogy ha bármely ok miatt
beállítunk egy pontos szótávolságot, akkor a szöveg már nem lehet sorkizárt igazítású.

4.6.9. Kisbetű, nagybetű


Elképzelhető, hogy valamely elem szövegét csupa nagybetűvel, vagy csupa kisbetűvel szeretnénk megjeleníteni. Erre
szolgálhat a text-transform tulajdonság.

45. A text-transform tulajdonság

A text-transform tulajdonság segítségével a szöveget nagybetűssé, kisbetűssé, vagy nagy kezdőbetűssé tehetjük. Lehet-
séges értékei a következők:
• capitalize: minden szó első betűjét nagybetűvé alakítja.
• uppercase: a szöveg valamennyi betűjét nagybetűvé alakítja.
• lowercase: a szöveg valamennyi betűjét kisbetűvé alakítja.
• none (alapértelmezés): semmilyen változtatást nem hajt végre a szövegen.

57
A következő szabály a H1 elem teljes tartalmát nagybetűsen jeleníti meg, függetlenül attól, hogy milyen betűmérettel
írtuk be az elembe azt:
H1 { text-transform: uppercase }

Másik példa a csupa kisbetűvel írásra (ezúttal helyi stílusmegadásként) :


<SPAN style="text-transform: lowercase">Nemecsek Ernő</SPAN>

4.6.10. A tördelés szabályozása


Egy szöveg tördelését – annak letiltását vagy engedélyezését – a white-space tulajdonság befolyásolja. Ez a tulajdonság a
PRE elemnél kikapcsolja a tördelést, a többi elemnél bekapcsolja alaphelyzetben.

46. A white-space tulajdonság

A white-space tulajdonság segítségével szabályozható a szöveg tördelése. Erre a következő értékek használhatóak :
• normal (alapértelmezés általában): Minden egymás utáni szóköznek minősülő karaktera a HTML kódból egyet-
len megjelenített szóközzé válik, ahol szükség esetén – amennyiben a sor végére esik – a sort el lehet törni.
• pre (alapértelmezés a PRE elemnél): A HTML forrásban levő tartalmat előre formázottnak kell tekinteni. Ez
azt jelenti, hogy minden előforduló szóköz, tabulátorjel vagy újsor jel azonos formában kerül megjelenítésre.
Leginkább programkód megadására használatos tördelési mód. (A jelen dokumentum példái is ilyen tördelési
móddal jelennek meg.)

• nowrap: Hasonlóan a normal értékhez minden szóköznek minősülő karakter egyetlen szóközzé alakul át.
Annyiban tér el a normal értéktől, hogy a sor végén nem törhető el a szöveg csak a BR elemnél.
a Szóköznek minősül a HTML nyelv definíciója szerint a szóköz, a tabulátor és az újsor. Ezeket együttesen az angol szakirodalomban – más

területekhez hasonlóan – whitespace-nek nevezik.

4.7. Szövegváltozások jelzése


Van két elem, amely használható az időről időre megváltozó szöveg változásainak dokumentálására. A két elem pontos
viselkedését a stíluslap és esetleg JavaScript használatával lehet befolyásolni, alaphelyzetben nincs különösebb megjele-
nésük. Használatukkal azonban úgy lehet megváltoztatni egy dokumentum szövegét, hogy a változtatás előtti állapotot is
megőrzi a dokumentum. Ez a két elem tehát elsősorban a változás megjelölésére alkalmas. A DEL a törölt szöveg, az INS
a beszúrt szöveg megjelölését teszi lehetővé.

58
47. Az INS és a DEL elemek

<! -- INS/DEL are handled by inclusion on BODY -->


<!ELEMENT (INS|DEL) - - (%flow;)* -- inserted text, deleted text -->
<!ATTLIST (INS|DEL)
%attrs; -- %coreattrs, %i18n, %events --
cite %URI #IMPLIED -- info on reason for change --
datetime %Datetime #IMPLIED -- date and time of change --
>

Az INS a szövegbe beszúrt, a DEL a szövegből törölt részt jelöli. Az elemek paraméterei (a szokásosakon felül) :
cite Annak a dokumentumnak a címe, amely a változtatást elrendeli.
datetime Az időpont, amikor a változás életbe lép(ett).

Az elemek lehetnek egy szövegen belül úgy is elhelyezve, hogy egy bekezdésen belüli szövegrészre vonatkoznak, vagy
akár több bekezdést is magukba foglalhatnak.

59
5. fejezet

A weboldal megjelenítése

5.1. A doboz modell


Egy weboldal objektumainak megjelenítése a doboz modell alapján történik. Ez határozza meg, hogy az egyes elemek
egymáshoz viszonyítva hogyan helyezkednek el.
Már korábban említettük, hogy a HTML elemek besorolhatók fajtájuk szerint a szövegszintű vagy a blokk szintű
elemek közé. Ez alól egyedül az INS és a DEL elem kivétel, amely mindkét csoportba tartozhat, de egy adott elem esetén
ekkor is a tartalma egyértelműen besorolja valamelyikbe.
A szövegszintű és a blokk szintű elemek megkülönböztetése valójában éppen a doboz modell miatt történik. A blokk
szintű elemek ugyanis minden esetben egy téglalap alakú dobozt hoznak létre a tartalmuk számára. Ennek a doboznak a
tulajdonságait az adott elem tulajdonságaiként lehet szabályozni. A szövegszintű elemekhez egy vagy több doboz tartozik,
attól függően, hogy az elem tartalma elfér egy sorban vagy sem. Ez a doboz azonban a bekezdésdobozon belül egy, a sor
magasságánál nem nagyobb magasságú doboz, amely jóval kevesebb beállítási lehetőséggel rendelkezik, mint a blokk
szintű elemek dobozai.

5.1.1. A dobozok méretei


Minden doboznak van egy tartalom-része (content area), amely az elem tartalmának megjelenítésére szolgál. Normá-
lis körülmények között az elem tartalmának ebben a legbelső téglalapon belül kell elhelyezkednie, azonban van néhány
speciális eset, amikor az elem tartalma kilóg ebből a tartalom-dobozból. A tartalom-részt körülveszi egy belső margó
(padding area), ezután egy lehetséges keret (border), végül a külső margó területe (margin area). Mindegyik területfajtá-
nak a mérete a megfelelő tulajdonságokkal beállítható.
A 5.1. ábrán látható a doboz részeinek szemléltetése, ahogyan az megtalálható a [2]-ben. Mint az ábrán látható,
a belső margó, a keret és a külső margó egyaránt felosztható felső (top), alsó (bottom), bal (left) és jobb (right) oldalra.
Ezek mindegyike külön beállítható a megfelelő nevű tulajdonságokkal, amelyek az oldalt a nevükben megadják. Az egyes
területek találkozását – amelyet az ábrán a különböző típusú vonalak jelzik – élnek (edge) nevezzük : A tartalom és a belső
margó határán van a tartalom-él (content edge) stb.

belső vagy tartalom él (inner/content edge): A legbelső, az elem tartalmát tartalmazó téglalap határa a belső margó
kezdetével.

belső margó éle (padding edge): A belső margó végét jelentő határvonal a belső margó és a keret találkozásánál.
keret él (border edge): A keret külső határán (és a margó belső határán) levő él. Amennyiben a keret szélessége nulla
(például mert nincs keret), akkor egybeesik az előzővel.

60
5.1. ábra. A doboz területei

külső él (margin/outer edge): A doboz legkülső határa, ahol a margó véget ér.

A legbelső doboz (az elem tartalmának doboza) szélességét és magasságát lehet megadni a width és height tulajdon-
ságokkal, míg a többi terület vastagsága ehhez hozzáadva adja meg a doboz teljes méretét.
Az egyes téglalapok hátterét is különböző tulajdonságokkal lehet beállítani.
• A tartalom téglalapjában a háttér a background tulajdonság értékétől függ.
• A belső margó hátterét szintén a background tulajdonság határozza meg.
• A keret színét a keret tulajdonságai állítják (border-color).
• A (külső) margó mindig átlátszó, azaz a tartalmazó doboz háttere látszik ezen a területen.
A [2]-ben szerepel egy példa a margók bemutatására. Álljon itt most ez egy kicsit magyarítva, mivel tanulságos lehet
kipróbálni a hatását:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD>
<TITLE>Példa a belső margóra, keretre és külső margóra</TITLE>
<STYLE type="text/css">
UL {
background: green;
margin: 12px 12px 12px 12px;
padding: 3px 3px 3px 3px;

61
/* Nincs keret beállítva */
}
LI {
color: black; /* A szöveg színe fekete */
background: gray; /* A tartalom és a belső
margó háttere szürke */
margin: 12px 12px 12px 12px;
padding: 12px 0px 12px 12px; /* 0px jobbról a belső margó! */
list-style: none /* nincs felsorolásjel */
/* Nincs keret beállítva */
}
LI.withborder {
border-style: dashed;
border-width: medium; /* minden oldalon szaggatott a margó */
border-color: black;
}
</STYLE>
</HEAD>
<BODY>
<UL>
<LI>A lista első eleme
<LI class="withborder">Egy jó hosszú második listaelem, hogy
látni lehessen, mi történik a jobboldalán a doboznak. A lista
létrehozásáról majd a következő fejezet fog szólni. Ez már
remélhetőleg biztosan nem fér el egy sorban...
</UL>
</BODY>
</HTML>
A 5.2. ábra mutatja, hogyan alakul a fenti HTML kód megjelenítése egy olyan böngészőben, amely megfelel a HTML
4.01 és CSS2 szabványoknak.1 Mint látható, a második listaelem zöld színű, szaggatott kerettel rendelkezik, míg az
elsőnek nincs kerete. A belső margónak az UL-nál beállítottól eltérő színe jól mutatja a belső margó határát. Az egyes
listaelemek között levő 12 pixel magas hézag azonban egy kis magyarázatra szorul. Az LI elem felső és alsó margója
egyaránt 12 pixelre van állítva. Akkor miért nem 24 pixel a két LI távolsága. . . ?
A válasz az, hogy az egymás fölötti dobozok esetében – néhány kivételtől eltekintve – a két találkozó margó átfedi
egymást, azaz – ahogyan az ábra jobboldali felirata is mutatja – a két találkozó margó által megadott értékből számított
maximális érték lesz a teljes margó közöttük.2

5.1.2. A margókra vonatkozó tulajdonságok


A dobozok margóinak beállításánál mindössze a szélességének megadására van lehetőség. (Mint említettük, a margón
mindig a mögötte levő tartalom látszik, hátteret nem lehet a margóra beállítani). Állítható külön a négy oldal a margin-
top, margin-right, margin-bottom, margin-left tulajdonságokkal, vagy egyszerre a margin tulajdonsággal.
1 Mivel ez is a [2]-ből származó ábra, azért angol nyelvű az ábrán szereplő szöveg. . .
2A szomszédos bekezdések közötti térköz viselkedése az egyes szövegszerkesztőknél, szövegmegjelenítőknél mindig egy érdekes kérdés. A kü-
lönöző programok nem egységesen kezelik azt az esetet, amikor két egymást követő bekezdés (esetünkben általában valamilyen doboz) egymással
találkozó margói nullától különböző értékűek. Van olyan program, amely összeadja azokat, van olyan, amely átfedést hoz létre közöttük, a nagyobb
érték megtartásával, és van olyan is, amelyen a kétfajta viselkedés közül a beállításokkal váltani lehet. A weboldalaknál egységesen az átfedést kell
alkalmazni, így az MS Internet Explorer kivételével biztosak lehetünk abban, hogy ezt a viselkedést kapjuk. Az Explorer is valószínűleg ezt alkalmazza,
így a kivételként való említés oka csupán a szabványtól való általános eltérésére akar utalni. . .

62
5.2. ábra. Példa a margók és keretek méreteire

48. A margó tulajdonságai

A margin-top, margin-right, margin-bottom, margin-left tulajdonságok rendre a felső, jobb, alsó és bal oldalon levő
margó szélességének beállítására szolgálnak. A margin rövidítés a négy tulajdonságnak egyszerre ad értéket : négy
érték szóközzel elválasztott listája az egyes tulajdonságoknak a fenti sorrendben adja az értékeket, míg ha egy értéket
elhagyunk, akkor az az oldal a vele szemköztivel azonos értékű lesz. Ebből következően két érték esetén az első a fenti
és lenti, a második érték a két oldalon levő margóra fog vonatkozni, egy érték pedig értelemszerűen minden oldalon
azonos méretű margót eredményez.
A tulajdonságok értéke lehet:
hosszmérték Amely pontosan beállítja a margó méretét.
százalék A felső és alsó margó esetén a tartalom-doboz szélességéhez (width tulajdonság), a másik két margó esetén
a magasságához (height tulajdonság) relatív értékként értelmezendő.
auto A böngésző dönti el a CSS szabványban meghatározott szabályok szerint.
Használható negatív margó is. Alapértékként a legtöbb elemnél a 0 szerepel.

A margin tulajdonság még akkor is beállítja mindegyik margót, ha nem szerepel négy érték. Amennyiben ezt mege-
lőzően szerepelt egy margóbeállítás valamelyik oldalra, azt felülírja. Ezért ha a margin tulajdonságot az alapérték beállí-
tására akarjuk használni, akkor az ettől való eltérést a szabályon belül később kell szerepeltetni !
Amennyiben két margó úgy találkozik, hogy közöttük nincs semmi más (sem tartalom, sem keret, vagy belső margó),

63
akkor a két margó egyetlen margóvá olvadhat össze. Egy doboz oldalsó margója soha nem olvad össze más margóval. Az
alsó és felső margók a következő esetekben olvadhatnak össze :
• Két vagy több alsó ill. felső margó összeolvad a normál szedési szabályok szerint elrendezett dobozok esetén. Az
összeolvadás eredményeként keletkező margó magassága az összeolvadó margók magasságának maximuma lesz.
• Egy úsztatott doboz margója soha nem olvad össze más margókkal.
• Abszolút és relatív pozíciójú dobozok margója egymással soha nem olvad össze.

5.1.3. A belső margó tulajdonságai


A dobozok belső margói esetében is azok szélessége adható meg a négy oldalon. Ezen kívül a belső margón érvényes
még a doboz hátterére vonatkozó beállítás is.

49. A belső margó tulajdonságai

A padding-top, padding-right, padding-bottom és a padding-left tulajdonságok rendre a felül, jobboldalt, alul illetve
baloldalt levő belső margó szélességét állítják be a megadott értékre. A négy oldalon egyszerre állítható be – ebben a
sorrendben – a belső margó a padding tulajdonsággal, amely mind a négy oldali belső margót állítja még akkor is, ha
csak egy értéke van. Ha egy érték szerepel, akkor az mind a négy oldalra érvényes lesz, két érték esetén az első a felső
és alsó, a második a két oldali értéket jelenti, négy érték esetén a fenti sorrendben lesznek a négy oldal értékei, míg
három érték esetén a második adja meg a bal- és jobboldalt, az első a fenti, a harmadik pedig az alsó értéke lesz.
A tulajdonság értékeként megadható:
hossz a megadott érték lesz a pontos szélessége a belső margónak (a megjeleníthetőségen belülre kerekítve).
százalék a tartalom-doboz szélességének (width tulajdonság) százalékaként megadott relatív méretet jelent, még akkor
is, ha a felső vagy az alsó oldalra vonatkozik.
inherit Az inherit kulcsszó megadása azt jelenti, hogy a dobozt tartalmazó doboznál beállított értéket örökölje a
tulajdonság.
A margóval ellentétben a belső margó sohasem vehet fel negatív értéket. Alapértelmezett értéke a belső margónak 0.

5.1.4. A keret tulajdonságai


A dobozok keretére három fajta tulajdonság is állítható : szín, vastagság és stílus. Ezek rendre a border- ?-color, border- ?-
width és a border-?-style tulajdonságokkal állíthatóak be oldalanként, a kérdőjel helyére a már ismert szavakat – top: fent,
right : jobb, bottom: lent, left : bal – írva, vagy az egyes oldalak egyszerre történő megadásával border-color, border-width
és border-style alakban.

64
50. A keret szélessége : border-width

A border-top-width, border-right-width, border-bottom-width és a border-left-width tulajdonságok rendre a felső, jobb-


oldali, alsó és a baloldali keret vastagságát állítják be. Ugyanez megtehető egyszerre a border-width tulajdonsággal is,
amely egy érték esetén mind a négy oldalra vonatkozik, két érték esetén az első az alsó és felső, a második a két oldali
keretre, három esetén az első felül, a második két oldalt, a harmadik alul lesz érvényes, míg négy érték esetén a fenti
sorrendben állítja be a négy oldalt.
A tulajdonságok lehetséges értékei a következők:
• thin: Egy vékony keret.
• medium: Egy közepes vastagságú keret.

• thick: Egy vastag keret.


• hosszmérték : A megadott szélességű lesz a keret. Az érték nem lehet negatív.
• Százalékos, tehát relatív szélesség nem adható meg.
• inherit: a dobozt tartalmazó doboznál beállítottal azonos értéket veszi fel.

Megjegyzés. Az alapértelmezett értékként a [2] a medium értéket adja meg, azonban a valóságban inkább a 0 értéknek
kellene itt szerepelnie, hiszen ha nem állítunk be keretet, akkor nem látszik a keret. Valójában erre az a magyarázat, hogy a
keret egy másik értékére van megadva alapértelmezésként olyan érték, amely a keretet kikapcsolja, az itt szereplő közepes
vastagság pedig arra az esetre vonatkozik, ha bekapcsoljuk ugyan a keretet, de nem adjuk meg a szélességét.

51. A keret színe: border-color


A border-top-color, border-right-color, border-bottom-color és a border-left-color tulajdonságok rendre a felső, jobb-
oldali, alsó és a baloldali keret színét állítják be. Ugyanez megtehető egyszerre a border-color tulajdonsággal, amely
egy érték esetén a megadott értéket állítja be minden oldalra, négy érték esetén a fenti sorrendben alkalmazza az érté-
keket a négy oldalon, kettő illetve három érték esetén a hiányzó oldalra a szemköztivel azonos értéket alkalmaz.
A lehetséges értékek:
• inherit: a dobozt tartalmazó doboztól örökli a tulajdonság az értékét.
• szín: a megadott színt alkalmazza a kereten. A színek megadási módját lásd a 39. oldalon. . .

• transparent: a keret átlátszó (ettől még lehet szélessége).


Amennyiben a tulajdonságnak nincs értéke, akkor az elem color tulajdonságának értékét fogja megkapni.

65
52. A keret stílusa: border-style

A border-top-style, border-right-style, border-bottom-style és a border-left-style tulajdonságok rendre a felső, jobbol-


dali, alsó és a baloldali keret stílusát állítják be. Ugyanez megtehető egyszerre a border-style tulajdonsággal a többi
hasonló tulajdonsággal megegyező módon adva neki az értékeket.
Lehetséges értékei:
• none: Nincs keret. Ez a keret szélességét automatikusan 0 értékűre állítja. Mivel ez a tulajdonság alapértelmezett
értéke is, ezért a dobozoknak alaphelyzetben nincs keretük.
• hidden: Általában ugyanaz, mint a none, ám táblázatoknál mást eredményez (lásd ott. . . ).
• dotted: Pontozott keretet eredményez.
• dashed: Szaggatott vonalból áll a keret.
• solid: A legegyszerűbb keret, amely mindössze egyetlen vonalból áll, amelynek színe a keretszín, vastagsága
a keretvastagság.
• double: Duplavonalas keret. A két vonal közötti rész színe a background tulajdonságtól származik. A két vonal
és a köztük levő rész vastagsága a keretvastagsággal egyezik meg, a keretvastagság a három rész között egyenlően
oszlik meg.

• groove: A keret olyannak látszik, mintha bele lenne vésve a vászonba.


• ridge: A groove ellentéteként, mintha a vászonból kidudorodna a keret.
• inset: A keret árnyékolása olyan hatást kelt, mintha a kereten belüli téglalap besüllyedne a vászonba.

• outset: A keret árnyékolása olyan hatást kelt, mintha a kereten belüli téglalap kiemelkedne a vászonból.
• inherit: A keret stílusa megegyezik a dobozt tartalmazó dobozéval.
Az utolsó négy érték pontos színei nem csupán a keretre beállított színtól, hanem a doboz color tulajdonságától is
függenek (az árnyékolás kelti a megadott hatást, és az árnyék színét a color tulajdonság befolyásolja).

Megjegyzés. Elképzelhető, hogy egyes böngészők nem minden keretstílust tudnak megjeleníteni. Ezek a böngészők azt a
stílust, amelyet nem képesek megjeleníteni, úgy jelenítik meg, mint a solid stílusú keretet.

66
53. A kerettulajdonságok együttes beállítása

A keret három tulajdonságának együttes beállítására vonatkozó tulajdonságok a border-top, border-right, border-
bottom, border-left és a border. Az első négy rendre a felső, jobboldali, alsó és baloldali keretre vonatkoznak, míg
a border együtt állítja mind a négy oldalt. Ez utóbbi esetben nem lehet az egyes oldalakra különböző fajta keretet
beállítani.
Mind az öt tulajdonságnál azonos sorrendben kell az értékeket megadni :
1. Szélesség
2. Stílus
3. Szín
Amennyiben nem szerepel valamelyik érték, úgy az adott tulajdonság az alapértelmezett értéket kapja. Használható
egyszerre mindhárom helyett a inherit kulcsszó arra az esetre, ha mindhárom tulajdonságot a dobozt tartalmazó
doboztól kell örökölni.

5.2. A szöveg és a háttér színére vonatkozó tulajdonságok


5.2.1. A szöveg színe
A szöveg színét – és vele a keret és egyéb elemek alapértelmezett színét – a color tulajdonság határozza meg.

54. A color tulajdonság

A color tulajdonság egy elem szöveges tartalmának színét határozza meg. Alapértelmezett értékét a böngésző beállí-
tásai határozzák meg. A tulajdonság értékét az elem gyermekei öröklik, amennyiben nincs szabály, amely annak más
értéket írna elő.
A szín bármely színmegadási móddal megadható (lásd 39. oldal).

Például egy H1 elem színét pirosra lehet állítani a következő négy szabály bármelyikével :
H1 {color: red} /* a szín nevével */
H1 {color: rgb(255,0,0)} /* rgb komponensekkel */
H1 {color: #f00} /* rövidített rgb színkóddal */
H1 {color: #ff0000} /* normál rgb színkóddal */

5.2.2. A háttér beállítása


Egy elem háttere lehet szín, vagy kép egyaránt. Az elem dobozánál a háttér beállítása a tartalomdobozra és a belső margóra
lesz érvényes, a keret színét a keret tulajdonságai állítják be, míg a külső margó háttere mindig átlátszó lesz.
Amennyiben mást nem állítunk be, akkor a háttér alapértelmezésben átlátszó. Ez azt jelenti, hogy annak az elemnek a
háttere jelenik meg, amely az adott elemet tartalmazza. Ebből következően a háttér beállítása nem öröklődik. A gyökér-
elem – HTML esetében ez a BODY – háttere betölti az egész vászont, így az erre beállított háttér látszik mindenhol, ahol
más háttér nincs beállítva. A BODY elem háttérszíne a böngésző alapbeállításaitól függ, ha nincs más beállítva.

67
55. A background-color tulajdonság

A background-color tulajdonság a háttér színét állítja be. Amennyiben nem adjuk meg, akkor értéke transparent,
ami azt jelenti, hogy a háttér átlátszó, vagyis a doboz mögötti tartalom és háttér látszik. További lehetséges értékei a
színmegadási módok egyikével megadott szín lehet (lásd 39. oldal).

56. A background-image tulajdonság

A background-image tulajdonság a háttérként megjelenő kép beállítására szolgál. Amennyiben a megadott kép elérhető,
a beállított háttérszín előtt jelenik meg, így ha a kép áttetsző részeket tartalmaz, akkor ott a háttérszín látszik. Akkor is
célszerű a háttérszínt is beállítani, ha a képnek nincs áttetsző része, mivel ha a kép nem tölthető be, akkor a háttérszín
jelenik meg. A lehetséges értékek a következők:
• none (alapértelmezés): nincs beállítva háttérkép ; a háttérszín jelenik meg.

• Egy URI-val megadott kép, amelyet a böngészőnek be kell töltenie, és az elem hátterében jelenik meg. Amennyi-
ben a kép mérete nem egyezik meg a dobozéval, a további tulajdonságok befolyásolják a háttérkép elhelyezke-
dését.

57. A background-repeat tulajdonság

A background-repeat tulajdonság a background-image által megadott háttérkép esetleges ismétlését állítja be. Az is-
métlés minden esetben mozaikszerű elrendezést ad a tulajdonság értéke által megadott irányban.

• repeat (alapértelmezés) : Mind vízszintesen, mind függőlegesen ismétlődik a kép, hogy a szükséges helyet
kitöltse.
• repeat-x: A kép csak vízszintesen ismétlődik. A fennmaradó helyeken a háttérszín jelenik meg.
• repeat-y: A kép csak függőlegesen ismétlődik. A fennmaradó helyeken a háttérszín jelenik meg.
• no-repeat: A kép csak egy példányban jelenik meg, ismétlődés nélkül. A fennmaradó helyeken ilyenkor is a
háttérszín jelenik meg.
A kép pozíciója határozza meg, hogy a nem minden irányban ismétlődő kép hol fog megjelenni.

58. A background-attachment tulajdonság

A background-attachment tulajdonság azt határozza meg, hogy az oldal gördítése során a háttérkép hogyan viselkedjen.
Megadható a scroll (alapértelmezés) értékkel, hogy a tartalommal együtt mozogjon, vagy a fixed értékkel, hogy
mozdulatlan maradjon. Az utóbbi esetben természetesen a helyben maradó háttérképnek is csupán az a része látszik,
amely a doboz és belső margója területén belülre esik.

68
59. A background-position tulajdonság

Amennyiben a háttérkép látható, a background-position tulajdonság meghatározza a pozícióját, ahol meg kell jelennie.
Amennyiben ismétlődik a kép, ez a tulajdonság az eredeti kép pozícióját adja meg, ahonnan az ismétléseket el kell
kezdeni. Lehetséges értékei a következők:
• Egy vagy két százalékérték: A 0% 0% pár jelentése : a bal felső sarka a képnek a doboz bal felső sarkába kerül.
A 100% 100% pár jelentése: a kép jobb alsó sarka a doboz jobb alsó sarkára esik. A további értékek a kettő
közötti pozíció megfelelő beállítását teszik lehetővé.
• Egy vagy két hosszérték: A kép bal felső sarka a doboz bal felső sarkától a megadott távolságra kerül elhelye-
zésre.
• top left vagy left top: A 0% 0% értékkel egyezik meg.
• top, top center vagy center top: A 50% 0% értékkel egyezik meg, azaz függőlegesen felülre kerül a
kép, vízszintesen pedig középre van igazítva.
• right top vagy top right: A 100% 0% értékkel egyezik meg, vagyis a kép jobb felső sarka van a doboz
jobb felső sarkához igazítva.
• left, left center vagy center left: A 0% 50% értéknek megfelelően függőlegesen középre igazítva,
vízszintesen balra igazítva jelenik meg a kép.
• center vagy center center: A kép mind függőlegesen, mind vízszintesen középre van igazítva, ahogyan
a 50% 50% esetén is lenne.
• right right center vagy center right: Függőlegesen középre, vízszintesen jobbra igazított kép, aho-
gyan a 100% 50% esetén.
• bottom left vagy left bottom: A bal alsó sarokba van igazítva, mint a 0% 100% esetén.
• bottom, bottom center vagy center bottom: Mint a 50% 100% esetén, függőlegesen alulra, vízszin-
tesen középre van igazítva.
• bottom right vagy right bottom: Mint a 100% 100%, a kép a jobb alsó sarokba van igazítva.
Amennyiben csak egy érték van megadva, akkor az a vízszintes igazítást adja meg, míg a függőleges igazítás az 50%
értéket kapja. A százalék és a hosszérték keverhető, de a kulcsszavakkal nem lehet mást együtt szerepeltetni. Negatív
hosszértékek is megadhatóak.
Amennyiben a háttérkép rögzített beállítást kapott (background-attachment: fixed), a kép nem a doboz
belső margójához, hanem a megjelenítési ablakhoz relatív elhelyezésű.

60. A background tulajdonság

A background tulajdonság egy rövidítés a background-color, background-image, background-repeat, background-


position tulajdonságoknak ebben a sorrendben történő megadására. Amelyik érték nem szerepel, az az alapértelmezett
értékét veszi fel.

A következő példa mutatja, hogyan lehet a fenti tulajdonságokat használni. Először csak a színt állítjuk be, míg a

69
következő példák további tulajdonságokat is állítanak :
BODY { background: red }
P { background: url("chess.png") gray 50% repeat fixed }
A következő példa a logo.png képet állítja be a megjelenítő ablak jobb alsó sarkába úgy, hogy az ne is mozduljon
el a tartalom görgetésével.
BODY {
background-image: url("logo.png");
background-attachment: fixed;
background-position: 100% 100%;
background-repeat: no-repeat;
}

5.3. A doboz méretei


A doboz méreteit megadhatjuk a width (szélesség) és a height (magasság) tulajdonságokkal.

61. A width tulajdonság

A width tulajdonság az elem tartalomdobozának szélességét adja meg. Értéke megadható a következő formákban :
• hosszérték : a megadott szélességű lesz a doboz.
• százalékérték : az elemet tartalmazó doboz szélességéhez relatív szélességet ad meg.
• auto: egyéb tulajdonságok alapján a böngésző határozza meg a doboz szélességét ; ha mást nem adunk meg, ez
az értéke a tulajdonságnak.
Negatív érték nem adható meg. Ugyanezekkel az értékekkel,de megjelenítőtől függő alapértelmezett értékekkel meg-
adható a min-width és a max-width tulajdonság, amelyek segítségével beállítható egy intervallum, amelyen belül mo-
zoghat a doboz szélessége abban az esetben, ha a pontos szélességet a megjelenítőre bízzuk.

62. A height tulajdonság

A height tulajdonság az elem tartalomdobozának magasságát adja meg. Értéke megadható a következő formákban :

• hosszérték : a megadott magasságú lesz a doboz.


• százalékérték : az elemet tartalmazó doboz magasságához relatív szélességet ad meg.
• auto: egyéb tulajdonságok alapján a böngésző határozza meg a doboz magasságát ; ha mást nem adunk meg, ez
az értéke a tulajdonságnak.

Negatív érték nem adható meg. Ugyanezekkel az értékekkel,de megjelenítőtől függő alapértelmezett értékekkel meg-
adható a min-height és a max-height tulajdonság, amelyek segítségével beállítható egy intervallum, amelyen belül
mozoghat a doboz magassága abban az esetben, ha a pontos magasságot a megjelenítőre bízzuk.

70
Megjegyzés. Képek beillesztésénél is használható a width és height tulajdonság. Azonban egy dolgot nem szabad el-
felejteni : hajlamosak vagyunk ilyenkor úgy gondolni, hogy ha a kép méreteit százalékban adjuk meg, akkor az eredeti
képmérethez relatív értéket adunk meg. Holott nem így van : A százalékos méretek mindig a rendelkezésre álló széles-
séghez illetve magassághoz viszonyítva értendők! Másrészt képekre nem is célszerű ezeket a tulajdonságokat használni,
mivel a kisebb méretben való megjelenítés esetén is a teljes kép töltődik le. Ehelyett érdemesebb a képet egy erre alkalmas
programmal lekicsinyíteni, majd ezt beilleszteni.
Hasznos az objektumok méretének megadása – akár képek esetén is – ha az objektum betöltése sokáig tart. Néhány
elemnél erre a célra lehet ugyanezen nevekkel paramétereket is használni (például táblázatoknál). Ezzel a böngészővel
az objektum letöltése előtt tudathatjuk, hogy mekkora helyet fog elfoglalni, így az képes a további tartalmat ennek meg-
felelően elhelyezni, még az objektumhoz tartozó minden adat letöltésének befejezése előtt. Ezzel bizonyos esetekben
jelentősen gyorsítható a weboldal megjelenítése.

71
6. fejezet

Listaelemek és formázásuk

Ebben a fejezetben a listakészítéshez használható elemeket vesszük sorra. A HTML nyelv háromféle lista készítését teszi
lehetővé :
• felsorolás (nem sorszámozott lista),
• számozás (sorszámozott lista),
• definíciós lista.1
A fentihez hasonló felsorolás például a következő kódrészlettel hozható létre:
<UL>
<LI>felsorolás (nem sorszámozott lista),</LI>
<LI>számozás,</LI>
<LI>definíciós lista</LI>
</UL>
Mint látható, a felsorolást az UL elemmel lehet létrehozni, amin belül egy-egy tétele a listának az LI elemmel adható
meg. Ugyanez az LI elem egy OL (ordered list) elemen belül a felsorolás tételeit jelenti. A definíciós lista létrehozása a
DL, DD és DT elemekkel történhet. Természetesen a listák egymásba is ágyazhatóak, akár az egyes típusokat keverve is
alkalmazhatjuk.
1 A legtöbb böngésző esetében a definíciós lista megjelenítése még nem igazán testreszabható, és a böngészők által alapból használt megjelenítés

nem a legszebb, ezért általában más módszert szokás helyette alkalmazni. . .

72
6.1. Számozott, számozatlan lista és a listaelem

63. Az UL elem

<!ELEMENT UL - - (LI)+ -- unordered list -->


<!ATTLIST UL
%attrs; -- %coreattrs, %i18n, %events --
>

Az UL elemmel felsorolást, azaz nem sorszámozott listát lehet létrehozni, amelynek minden egyes tétele (listaeleme)
az LI elemmel adható meg.

64. Az OL elem

<!ELEMENT OL - - (LI)+ -- ordered list -->


<!ATTLIST OL
%attrs; -- %coreattrs, %i18n, %events --
>

Az OL elemmel sorszámozott lista hozható létre, amelynek minden egyes tétele (listaeleme) az LI elemmel adható
meg.

65. Az LI elem

<!ELEMENT LI - O (%flow;)* -- list item -->


<!ATTLIST LI
%attrs; -- %coreattrs, %i18n, %events --
>

Az LI elem egy OL vagy UL elemmel létrehozott lista egy elemét adja meg. Amennyiben OL elemben található, akkor
a listajel szám lesz, UL elem esetén kör, korong, vagy tömör négyzet szokott a listaelem jeleként megjelenni.

Mindhárom elem a „szokásos” paraméterekkel rendelkezhet (class, id, lang, dir, title, style, és az esemény-
kezelők).
Az OL és az UL elemek tartalmának megjelenítése a listaelemek előtt megjelenő szimbólumoktól eltekintve telje-
sen azonos módon történik. Mindkét esetben a lista gyakorlatilag az LI elemekkel megadott listaelemek sorozatából áll
(amelyek zárótagja elhagyható). A lista végét a listát létrehozó elem zárótagja jelzi, így a zárótag megadása az OL és UL
elemek esetén kötelező.

73
A listaelemek előtti szimbólumok formázásáról a fejezet későbbi részén lesz szó. . .

6.2. Definíciós listák


A definíciós listák létrehozásához három elemet kell használni : DL a lista létrehozására, DT a definiálandó kifejezés
megadására és DD a magyarázat megadására.

66. A DL elem

<!-- definition lists - DT for term, DD for its definition -->


<!ELEMENT DL - - (DT|DD)+ -- definition list -->
<!ATTLIST DL
%attrs; -- %coreattrs, %i18n, %events --
>

A DL elem egy definíciós listát hoz létre. Benne DT elemmel lehet a definiálandó kifejezést, DD elemmel a hozzá
tartozó magyarázatot megadni.

67. A DD és a DT elem

<!ELEMENT DT - O (%inline;)* -- definition term -->


<!ELEMENT DD - O (%flow;)* -- definition description -->
<!ATTLIST (DT|DD)
%attrs; -- %coreattrs, %i18n, %events --
>

A DT elem egy definiálandó fogalom megadására, a DD elem a definíció megadására szolgál. A DT elem tartalma
csak szöveg-szintű elemeket tartalmazhat, míg a DD elem tartalma akár több bekezdés is lehet. Megjelenésében a DT
a listaelemek szimbólumaihoz hasonlóan helyezkedik el egy kis dobozban (ezért van a tartalma szövegre korlátozva),
míg a DD elem tartalma egy ehhez képest baloldali behúzással (magyarul baloldali margóval) rendelkező blokk-szintű
dobozba kerül. Mindkét elem csak egy DL elemen belül fordulhat elő, a két elem bármilyen sorrendben követheti
egymást.

Mindhárom elemhez a „szokásos” paraméterek tartoznak (class, id, lang, dir, title, style és az esemény-
kezelők).
A definíciós lista a lexikonokban, szótárakban használatos formára hasonlító szövegmegjelenést hoz létre. Minden
definícióban szerepel egy vagy több fogalom (DT elem), és utána egy vagy több magyarázat (DD elem). Mivel egy
magyarázathoz több fogalom is tartozhat, és fordítva : egy fogalomhoz több magyarázat is tartozhat, így nincs megszabva,
hogy a DT és DD elemek milyen sorrendben követik egymást.
Íme néhány példa definíciós listára (az első a HTML szabványban szereplő példa angolul) :
<DL>

74
<DT>Dweeb
<DD>young excitable person who may mature
into a <EM>Nerd</EM> or <EM>Geek</EM>
<DT>Hacker
<DD>a clever programmer
<DT>Nerd
<DD>technically bright but socially inept person
</DL>

<DL>
<DT>Center
<DT>Centre
<DD> Egy gömb felszínének vagy kör kerületének
valamennyi pontjától egyenlő távolságra lévő pont.
Magyarul: középpont.
<DD> Valamely csapatsportban annak a játékosnak a neve,
aki a pálya, vagy a sor középső pozícióján tartózkodik.
Magyarul: center.
</DL>
A második példa egyszerre mutatja a többszörös fogalommegadást (az angol szó kétféle írásmódját), és a többszörös
meghatározást (a szó egyes magyar jelentéseivel).

6.3. A listák megjelenése


Amennyiben másképp nem formázzuk a stíluslap segítségével, az egymásba ágyazott listák elemei az előzőeknél nagyobb
behúzással jelennek meg, ezzel jelezve a beágyazást. Az UL elemek által létrehozott listák esetén a listaelem szimbólumai
a beágyazási szinttől függően változnak a korong, kör és a négyzet valamelyikét felvéve. Az OL elem által létrehozott
listák elemei előtt, a szimbólum helyén valamilyen számozás jelenik meg, amelynek típusa szintén függ a lista beágyazási
szintjétől.
A szimbólumok típusai azonban felülbírálhatóak a list-style-type tulajdonsággal.
A listaelem megjelenését befolyásolhatjuk a CSS2-ben bevezetett markerek segítségével is (ezt még nem minden bön-
gésző érti meg). Amennyiben a display tulajdonság értékét marker-re állítjuk a LI:before pszeudo elemre, a content
tulajdonságon keresztül megadhatjuk a listaszimbólum pontos megjelenését. Erről bővebb információ megtalálható [2]-
ben. A továbbiakban csupán a már minden böngészőn működő, CSS1 óta létező listaformázó tulajdonságokkal fogunk
foglalkozni.2
A list-style-image segítségével egy számozatlan lista pontjait lecserélhetjük például kis színes golyókra, ha a golyót
tartalmazó GIF, JPEG vagy PNG kép címét adjuk meg értékül. Természetesen ilyen célra kizárólag kis méretű képeket
célszerű alkalmazni, mivel a hely, ahol el kell férnie szintén kicsi. . .

2 A könyv egy későbbi változatában – ha majd a jobb böngészők teljesen megvalósítják a CSS2-t – egy külön fejezetben lesz szó a számlálókról és

azok használatáról. Ekkor a markerek használatáról is szólni fog ez a később elkészítendő fejezet. . .

75
68. A list-style-stype tulajdonság

A list-style-type tulajdonság a normál – vagyis más markerrel nem helyettesített – markerben megjelenő listaszimbólum
típusát határozza meg. Amennyiben a list-style-image tulajdonság értéke none, vagy az ott megadott kép nem jelenít-
hető meg, az itt beállított listaszimbólum kerül felhasználásra. A tulajdonság a listaelemet létrehozó tulajdonságokra
alkalmazható : LI, OL vagy UL (az utóbbi kettő esetén a benne levő LI elemek öröklik az értékét).
Amennyiben a tulajdonság értéke none, a listaelem előtt nem jelenik meg semmilyen szimbólum. Nem számozott
lista esetében a használható értékek: disc, circle és square. A tényleges megjelenés persze böngészőfüggő.
A számozott listák esetében vagy számozási rendszer, vagy betűzési rendszer adható meg, amelynek hatására a lista
számlálójának értéke a megadott rendszerben jelenik meg.
A lehetséges számozási rendszerek:
• decimal: tízes számrendszerbeli egész számok 1-től kezdve.

• decimal-leading-zero: tízes számrendszerbeli egész számok 0-tól kezdve.


• lower-roman: kisbetűs római számok: i, ii, iii, iv stb.
• upper-roman: nagybetűs római számok : I, II, III, IV stb.
• hebrew: héber számozás.

• georgian: grúz (?) számozás (an, ban, gan, . . . , he, tan, in, in-an, . . . ).
• armenian: örmény számozás.
• cjk-ideografic

• hiragana: a, i, u, e, o, ka, ki, . . .


• katana: A, I, U, E, O, KA, KI, . . .
• hiragana-iroha: i, ro, ha, ni, ho, he, to, . . .
• katana-iroha: I, RO, HA, NI, HO, HE, TO, . . .
A lehetséges betűzési rendszerek:
• lower-latin vagy lower-alpha: Az angol ábécé kisbetűi.
• upper-latin vagy upper-alpha: Az angol ábécé nagybetűi.
• lower-greek: A görög ábécé kisbetűi.

69. A list-style-image tulajdonság

A list-style-image tulajdonság segítségével a normál listaszimbólumot lecserélhetjük egy külső erőforrásból származó
képre. Ez a tulajdonság az LI elemnél is megadható, de megadható az UL vagy OL elemnél is, amely esetben a benne
levő LI elemek öröklik az értékét.
Értéke alapértelmezésben none. Ha más értéket állítunk be, akkor a megadott értékből származó képre cserélődik a
listaszimbólum. Ez az érték egy URI, amelyet megadhatunk egyszerű szövegként idézőjelek között, vagy az uri()
függvényen belül egyaránt.

76
70. A list-style-position tulajdonság

A list-style-position tulajdonság a listaszimbólumot tartalmazó marker pozícióját határozza meg a listaelem alapdobo-
zához képest. Lehetséges értékei:
• inherit: örökli a tartalmazó elem beállítását.
• outside (alapértelmezés): a marker az alapdobozon kívül helyezkedik el. A pontos helyzetét a CSS1 nem
határozza meg – ezért a CSS2 sem. Pontosabb pozícionáláshoz a CSS2 új, markerre vonatkozó tulajdonságait
kell használni.
• inside: a marker doboz az alapdoboz első szöveg-szintű doboza lesz, amelyet a listaelem további tartalma
sorfolytonosan követ.
Jobbról balra haladó írásban a listaszimbólumot tartalmazó marker mindig a listaelem jobboldalán jelenik meg.

71. A list-style tulajdonság

A list-style tulajdonság egy rövidítése a list-style-type, list-style-position és a list-style-image tulajdonságoknak, ebben


a sorrendben.

77
7. fejezet

Hivatkozások

A weboldalakon az egyik nagyon fontos elem a hivatkozás, hiszen a hipertext dokumentum egyik legfontosabb jellemzője,
hogy hivatkozik más dokumentumokra is, amelyek azonnal betölthetőek.
A hivatkozások kapcsán tudnunk kell, hogy egy-egy dokumentumot hogyan lehet az interneten azonosítani, mielőtt a
dokumentumokra egyáltalán hivatkozni tudnánk. Éppen ezért ebben a fejezetben először a dokumentumok azonosításáról
lesz szó, majd a hivatkozást létrehozó elemekről, végül a hivatkozások megjelenését befolyásoló tulajdonságokról.

7.1. A link fogalma


A weboldalak esetében a link egy nagyon fontos fogalom. A link szó magyarul kapcsolatot jelent. A webes dokumentum
között egy link mindig kettőt kapcsol össze egymással.
A linknek két vége van (ezeket nevezzük angolul anchor-nak) : Az egyik, ahonnan indul, a másik, ahova érkezik.
A link mindig indul valahonnan (source) és érkezik egy célponthoz (destination). Ez utóbbi bármilyen webes erőforrás
lehet. A kiindulópont pedig nem más, mint a hivatkozás, amely a célpontra mutat.
Egy hivatkozás aktiválása tulajdonképpen nem más, mint a link célpontjaként megadott erőforrás letöltése.
Egy célpont lehet egy weboldalon belül is, amely esetben külön azonosítóval kell rendelkeznie. Az erre a célpontra
mutató cím minden esetben tartalmazza ezt az azonosítót is a weboldal saját címén felül. Elvileg ilyen belső célpontot
bármely elem id paraméterével meg lehet adni, azonban a régebbi böngészők – és természetesen az MS IE – az ilyen cél-
pontokat nem feltétlenül hajlandóak megtalálni. Az A elem name paraméterével megadott célpontokat azonban minden
böngészőnek meg kell tudnia találni (lásd 81. oldalon).
Vannak azonban a fentiektől eltérő célú kapcsolatok is, amikor nem az a célja egy kapcsolatnak, hogy egy másik do-
kumentum letöltésére adjon lehetőséget. Tulajdonképpen amikor egy külső állományban elhelyezett stíluslapot rendelünk
a LINK elem segítségével a weboldalhoz, akkor is egy kapcsolatot (linket) definiálunk, amelynek kezdőpontja a weboldal
HTML állománya, a célpontja pedig a stíluslapot tartalmazó állomány.
Az A és a LINK elem rel és rev paramétereinek értékével még további kapcsolattípusokat is meg lehet adni, ezeket
röviden, és a teljesség igénye nélkül a 25. oldalon soroltuk fel a LINK elemnél. . .

7.2. Az egységes címzési rendszer felépítése


Az egyes erőforrások címzésére az internet – ezenfelül már maga a UNIX rendszer is – egy egységes szabályt alkalmaz.
Ezt nevezzük URI-nak, azaz Universal Resource Identifier-nek, ami magyarra fordítva Egyetemes Erőforrás Azonosítót
jelent. Erről a 39. oldalon, a stílus tulajdonságok lehetséges értéktípusánál már szóltunk. Most, a hivatkozások tárgyalá-
sánál ismét szólnunk kell róla, hiszen a hivatkozások célpontját ezzel az URI-val kell minden esetben megadnunk.

78
Egy URI minden esetben az erőforrás eléréséhez igénybe veendő protokollal kezdődik. Ez a protokoll határozza
meg, hogy a felhasználó gépe és az erőforrást szolgáltató szerver gép között „milyen nyelven kell a kommunikációt
végrehajtani”. Egy weboldal esetében ez a protokoll a http:// címkezdést jelenti. Gyakori protokoll lehet még ezen
felül a következő :
• https:// Biztonságos (secure) HTTP, ahol a két gép közötti adatforgalom titkosítva van.
• ftp:// FTP szerverrel való kapcsolat. Például állomány letöltésénél használatos.
A következő rész a gépnek a neve, amelyen az erőforrás található.1 A gép neve az ismert név.tartomány alakú gépnév.
Ezt követi az erőforrást tartalmazó állomány elérési útvonalának megadása, amely mindig egy / jellel kezdődik, és
ezzel is végződik. Ez azt is jelenti, hogy amennyiben a főkönyvtárban van, akkor a legrövidebb, egyetlen / jelből álló
útvonalmegadást kell használni.
Következik az állomány neve, amelyben az erőforrás található.
Végül jöhet még két kiegészítés, amely az erőforráson belüli információkat tartalmaz :
1. Az állományon belüli célpont megadása, amelyet egy # után a belső célpont azonosítójával kell megadni.
2. Paraméterek, amelyeket az erőforrás bemeneti adatként feldolgoz. Ezekről majd a PHP-ről szóló részben lesz szó. . .
Egy URI a fentiek nem mindegyikét tartalmazza minden esetben. Amennyiben a protokoll és a gépnév nem szerepel,
akkor relatív címzésről beszélünk. Az ilyen címeknél az aktuális dokumentum báziscíméhez relatív a cím. Ez azt jelenti,
hogy ugyanaz a protokoll – általában HTTP vagy HTTPS – és ugyanaz a gép használandó, mint ami a báziscímben
szerepel. Ilyenkor előfordulhat, hogy az útvonal megadása nem / jellel kezdődik. Ebben az esetben az adott dokumentum
címének (vagyis a báziscímnek) a könyvtárától indul az útvonal. A hagyományos UNIX-os könyvtármegadási módszerek,
mint a .. a szülő könyvtár megadására ilyen esetben is használhatóak. A dokumentum báziscíme általában a dokumentum
címével egyezik meg.
Amennyiben a protokoll és a gépnév is szerepel, akkor abszolút címről beszélünk. Ekkor a cím pontosan megadja az
erőforrás helyét, így az nem függ a dokumentumtól.
Az, hogy mikor célszerű abszolút illetve relatív címzést használni, több dologtól is függhet. Érdemes alapszabály-
nak tekinteni, hogy egy sok oldalból álló dokumentum esetében az egybe tartozó állományok egymásra relatív címzéssel
hivatkozzanak. Így az egészet együtt mozgatva egy új könyvtárba vagy új szerverre, a dokumentum ugyanúgy működő-
képes marad. Ezzel szemben az abszolút címeket a dokumentumból kimutató hivatkozásoknál használjuk, még akkor is,
ha ugyanazon a gépen vannak. Így akárhová tesszük a dokumentum állományait, a tőle független oldalakra mutató hi-
vatkozások ugyanúgy működőképesek maradnak. Másik megközelítés, ha egy webszerver oldalait egyetlen dokumentum
részeinek tekintjük. Ilyenkor a gép nevének megváltoztatása esetén akkor nem kell a hivatkozásokat átírni, ha a gépen
belüli címek relatív címek, a külső címek pedig értelemszerűen abszolút címek.
Elhagyható az útvonal megadása utáni címrész is. Ebben az esetben a megadott könyvtáron belüli alapértelmezett
weboldalt adja meg a cím. Ilyen címek esetében a webszerver megkeresi ezt az alapértelmezett weboldalt, és ezt küldi
válaszként.
Ez az alapértelmezett weboldal általában az index.html, vagy – ha úgy van beállítva a szerver – index.?,
ahol a kérdőjel helyén valamilyen kiterjesztés áll. Például a PHP feldolgozóval is rendelkező webszerverek esetében az
index.php is lehet ilyen alapértelmezett weboldal. Ha nem talál semmilyen feldolgozható típusra utaló kiterjesztéssel
ellátott index. kezdetű állományt a szerver, akkor általában a könyvtár tartalomjegyzékét küldi el weboldallá generálva,
ahol az egyes bejegyzések hivatkozásként jelennek meg.2
Természetesen a belső célpont megadása nem kötelező. Ha nem szerepel, akkor az oldal elejéről kezdve látható.
Ugyanakkor lehetséges olyan címet is megadni, ahol nem szerepel más, csak a # és az azonosító. Ilyenkor egyszerűbb
dolga van a böngészőnek: nem kell semmilyen oldalt betölteni, csupán az aktuális oldalban megkeresni a megadott azo-
nosítót, és oda görgetve a megjelenítő ablakot az aktuális dokumentumot megjeleníteni.
1 Amennyiben a protokoll megadásánál például a file: szerepel, akkor helyi állományt ad meg az URI, ez esetben a gépnév nem szerepel. Ilyen

URI azonban egy weboldalon nem szerepelhet, hiszen ez azt jelentené, hogy a felhasználó gépén van az állomány. A valóságban azonban lehet olyan
weboldallal találkozni, amelyben ilyen címre is történik hivatkozás. Az ilyen weboldalak hibásak, hiszen az így hivatkozott erőforrás általában nem
létezik.
2 Azért ebben ne bízzunk, mivel van lehetőség ennek a letiltására több módszerrel, így elképzelhető, hogy nem kapunk tartalomjegyzéket !

79
7.3. Hivatkozás és célpont létrehozása
Angolul mind az induló, mind a cél oldalát a linknek anchor azaz horgony néven említjük – ezért jelzi például a Quanta
esetében az ezek létrehozására szolgáló gombot egy horgony. Ennek az anchor szónak a rövidítéséből származik az erre
a feladatra szolgáló elem neve is: A.
Minden egyes A elem tehát egy-egy horgonyt hoz létre.

1. Az A elem helyzete a HTML kódban meghatározza a horgony pozícióját a dokumentumon belül.


2. Amennyiben szerepel az elemben a name paraméter, akkor az abban szereplő azonosítóval létrejön az A elem
helyén a dokumentumban egy belső célpont, amelyre máshonnan hivatkozni lehet. Például ha a paraméter értéke
egyik, akkor erre a célpontra a #egyik címvégződéssel lehet hivatkozni. Természetesen egy célpontra akárhány
hivatkozás mutathat. . .
3. Amennyiben szerepel a href paraméter, akkor az A elem egy link indulópontja lesz. Egy A elem egyszerre csak
egy indulópontot tud létrehozni, és mivel az A elemek egymásba nem ágyazhatóak, így biztosítva van, hogy egy
hivatkozást aktiválva mindig ugyanarra a címre érkezünk. A hivatkozás címe ilyenkor a href paraméter értékeként
szerepel.

Furcsán hangzik talán, de lehetőség van olyan A elem készítésére is, amely sem célpontként, sem indulópontként
nem funkcionál, azaz nincs sem name sem href paramétere. Persze ennek is lehet értelme, hiszen egy elem paraméterei
például JavaScript programok segítségével dinamikusan megváltoztathatóak, így egy ilyen elemet fel lehet használni arra,
hogy menet közben váljon például hivatkozássá. Ugyanígy persze akkor arra is van lehetőség, hogy a hivatkozás címe
menet közben megváltozzon. . .
A következő példában szerepel egy hivatkozás, amely ennek a dokumentumnak a fellelési helyére mutat (FTP szer-
veren) :
A jegyzet legfrissebb változata bármikor letölthető a <A
href="ftp://szerver3.moragimi.sulinet.hu/informatika/jegyzet.pdf">gimnázium
FTP szerveréről</A>.
Megjegyzés. A hivatkozások létrehozásánál éppúgy, mint az EM vagy STRONG elemnél, vagy bármely más szöveg-szintű
elemnél – az A is az – nagyon oda kell figyelni, hogy hova teszünk szóközt : az elem nyitótagja előtti és az elem zárótagja
utáni szóközöket a böngészők megjelenítik, míg a nyitótag utáni és a zárótag előtti szóközöket a böngészőknek le kell(ene)
nyelniük. Ezért a sortöréseket, amelyek szintén szóköznek számítanak, ennek megfelelően szabad csak elhelyezni a HTML
kódban.
Amennyiben szeretnénk egy valami.html nevű állomány belsejében elhelyezni egy célpontot, akkor azt a következő-
képpen tehetjük meg:
sok-sok szöveg a célpont előtt
<A name="ide">Célpont a dokumentumban</A>
sok-sok szöveg a célpont után
Erre az ide azonosítójú célpontra a valami.html állományon belül egyszerűen a következőképpen tudunk hivatkozni :
<A href="#ide">belső célpont ebben a dokumentumban</A>
Egy ugyanebben a könyvtárban levő másik weboldalról :
<A href="valami.html#ide">Másik dokumentum belsejébe</A>
Megjegyzés. Soha ne készítsünk olyan A elemet, amelynek a tartalma üres, mivel egyes böngészők az ilyen A elemeket
egyszerűen figyelmen kívül hagyják, akárcsak az üres P elemeket !

80
72. Az A elem

<!ELEMENT A - - (%inline;)* -(A) -- anchor -->


<!ATTLIST A
%attrs; -- %coreattrs, %i18n, %events --
charset %Charset; #IMPLIED -- char encoding of linked resource --
type %ContentType; #IMPLIED -- advisory content type --
name CDATA #IMPLIED -- named link end --
href %URI; #IMPLIED -- URI for linked resource --
hreflang %LanguageCode; #IMPLIED -- language code --
rel %LinkTypes; #IMPLIED -- forward link types --
rev %LinkTypes; #IMPLIED -- reverse link types --
accesskey %Character; #IMPLIED -- accessibility key character --
shape %Shape; rect -- for use with client-side image maps --
coords %Coords; #IMPLIED -- for use with client-side image maps --
tabindex NUMBER #IMPLIED -- position in tabbing order --
onfocus %Script; #IMPLIED -- the element got the focus --
onblur %Script; #IMPLIED -- the element lost the focus --
>

Az A elem induló hivatkozásnak, hivatkozás célpontjának vagy mindkettőnek egyidejű létrehozására alkalmas. Az
elem tartalma lesz az a szöveg, vagy más objektum, amelyből a hivatkozás származik. Vizuális megjelenítés esetén erre
kattintva lehet a hivatkozást aktiválni. Paraméterei a következők lehetnek :
• name: Ezzel a paraméterrel egy célpontot hoz létre az elem. A célpont a paraméter értékeként megadott azo-
nosítóval jön létre. Az azonosító nem egyezhet meg a dokumentumban szereplő egyetlen másik name vagy id
paraméterben szereplő azonosítóval sem.

• href: Ezzel a paraméterrel egy induló hivatkozást hoz létre az elem. A paraméter értékeként kell megadni azt a
címet, amelyre az elem hivatkozik. A cím szerkezete az előző szakaszban (78. oldal) került bemutatásra. . .
• hreflang: A href paraméter által megadott erőforrás nyelvét lehet ebben a paraméterben megadni. Ebből
következően csak akkor szerepelhet, ha a href is szerepel.
• type: A hivatkozott erőforrás típusa. Ha nem szerepel, akkor az értéke text/html, azonban ez csupán segíti
a böngészőt abban, hogy megfelelő típusúnak azonosítsa az erőforrást, így elhagyása a legtöbb esetben nem okoz
gondot, vagyis az alapértékét akár definiálatlannak vagy unknown-nak is tekinthetjük.
• rel: Milyen kapcsolat van a hivatkozó és a hivatkozott erőforrás között.
• rev: Célpont esetén megfelel a rel paraméternek, amely indulópontra használható.
• charset: Segíthetjük a böngészőt az erőforrás által használt karakterkészlet megadásával.
• id, class, lang, dir, title, style és az eseménykezelők paraméterei a többi elemhez hasonlóan funkci-
onálnak az A elem esetében is.
• target: keret nevének megadása (funkcióját lásd a keretekről szóló fejezetben).
• tabindex, accesskey: az űrlapok elemeihez hasonlóan lehet egy billentyűkombinációt rendelni a hivatko-
zás aktiválásához.

81
7.3.1. A célpont-azonosítóra vonatkozó szabályok
Egy célpont azonosítására – akárcsak egy elem egyedi megjelölésére általában – szolgáló azonosítónak minden esetben
meg kell felelnie a következő feltételeknek:
Egyediség Az azonosítónak különböznie kell minden más name vagy id paraméter értékétől a dokumentumon belül.
Ilyen szempontból a betűméret nem számít: ha két azonosító csak a betűk méretében tér el egymástól, akkor azok
egyezőnek számítanak.
Pontos egyezés Az azonosítónak, és a rá való hivatkozásnak még a betűméretben is meg kell egyezniük : ha nagybetű
szerepel az azonosítóban, akkor hivatkozni is így kell rá.
Csak ASCII karaktereket tartalmazhat Ez egyben azt is jelenti, hogy a magyar ékezetes betűket nem használhatjuk.
Ennek elsődleges oka, hogy egy internetes cím nem tartalmazhat más karaktert, csak az alap ASCII kódtáblában
szereplőeket.3 Nem célszerű szóközt sem elhelyezni az azonosítóban.

7.3.2. Célpont létrehozása id paraméterrel


Fentebb már szó volt arról, hogy a name és az id paraméter értékeiként megadott azonosítók a másik paraméter érté-
keként sem ismételhetőek meg. Ennek az az oka, hogy a szabvány lehetővé teszi, hogy bármely elem id paraméterében
megadott azonosítót célpontként használjuk. Ez ugyanúgy működik, mint az A elem name paramétere. Legalábbis a
szabvány szerint. . . Valójában sajnos még elképzelhető, hogy egy böngésző nem látja az id paraméterrel létrehozott
azonosítókat, és erre való hivatkozás esetén is az oldalt az elejétől jeleníti meg.
Ez a módszer azonban sok esetben leegyszerűsíthetné a weboldalak elkészítését, ahogyan azt a következő példa is
mutatja :
<p>Erről a témáról bővebben a <A href="#section2">második fejezetben</A>
lesz szó...</p>
<!-- további HTML kód -->
<h2 id="section2">Második fejezet</h2>
Furcsa módon – ugyanakkor van benne logika –, egy A elemen belül, ha mind az id, mind a name paraméter szerepel,
akkor mindkét paraméternek ugyanazt az értéket kell kapnia.
De ha így van megszabva a szabály, akkor minek a két különböző paraméter ? Nos, a name a hagyományos paraméter,
az id a stíluslapok bevezetésével jelent meg. Ezenkívül van egy különbség a kettő között : a name paraméter értéke
tartalmazhat karakterreferenciákat, míg az id nem.

7.3.3. A LINK elem


A LINK elem pontos definiálása már korábban szerepelt, a 10. szabályban. Ez az A elemmel ellentétben csak a HEAD
elemen belül szerepelhet, és inkább a böngésző számára ad információt a weboldalhoz kapcsolódó egyéb erőforrások-
ról. Ezek tipikus esete a stíluslap, amelyet a LINK elemmel kapcsolunk az oldalhoz. További felhasználási lehetőség a
keresőprogramoknak szóló információként a más nyelvű változatok megadása, illetve a dokumentum további oldalainak
elérését lehetővé tevő kapcsolatok (tartalomjegyzék, kezdőoldal, előző/következő fejezet stb.).
3 Újabban elvileg lehetséges ékezetes betűket tartalmazó gépneveket is regisztrálni Magyarországon. Ennek ellenére szerencsére még nem kezdtek

terjedni az ilyen gépnevek. Talán éppen az az oka ennek, hogy az emberek többsége – legalábbis, akinek módjában áll gépet kapcsolni az internetre –
tisztában van azzal, hogy az ékezetes címekkel a programok zöme nem fog boldogulni, így az ilyen gépen elhelyezett információkhoz a felhasználók
túlnyomó többsége soha nem fog hozzáférni. . .

82
7.4. Az alapértelmezett URI
Fentebb már említettük, hogy a relatív címek esetén a címet a böngésző egy alapértelmezett URI alapján egészíti ki, hogy
az erőforrás tényleges címét megkapja. Ez az alapértelmezett cím általában az aktuális oldal címével egyezik meg.
Vannak esetek, amikor kényelmesebb lenne ehelyett egy másik címet használni alapértelmezett címként, mivel ezzel
több címet lehetne a rövidebb, relatív változatban megadni. Ilyenkor vesszük hasznát a BASE elemnek, amely a HEAD
elemen belül helyezhető el, és a href paraméterében megadott URI-t állítja be alapértelmezett URI-ként. Ezenkívül ez
az elem még arra is alkalmas, hogy a később bemutatásra kerülő keretek használatakor szükséges target paraméternek
az alapértelmezett értékét beállítsa.

73. A BASE elem

<!ELEMENT BASE - O EMPTY -- document base URI -->


<!ATTLIST BASE
href %URI; #REQUIRED -- URI that acts as base URI --
>

A BASE elem a dokumentum A elemeiben (és LINK elemeiben) a relatív címek esetén figyelembe veendő alapértel-
mezett URI, illetve a hivatkozások megnyitására szolgáló alapértelmezett célkeret beállítására szolgál.
Paraméterei ennek megfelelően a következők:
• href: Az alapértelmezett URI-t megadó abszolút cím.
• target: Az alapértelmezett keret azonosítója azon hivatkozások számára, amelyekben nem szerepel a target
paraméter.

Bár a szabvány a href paraméter használatát kötelezően előírja, használható olyan BASE is, amelyban csak a
target paraméter használható. A legtöbb böngészőnél inkább úgy kell tekinteni, hogy a két paraméterből legalább
az egyik szerepeltetése kötelező.
A BASE elemet, ha megadjuk, mindig írjuk az összes olyan elem elé – a HEAD elemen belül –, amely valamilyen
címet ad meg : előbb a BASE elem szerepeljen, azután jöjjön a LINK. Amennyiben fordítva adjuk meg, akkor nem
egyértelmű a böngésző viselkedése a BASE előtt szereplő LINK elemek relatív címei esetén !

7.5. A hivatkozások megjelenése


Amennyiben egy hivatkozás megjelenését befolyásolni akarjuk, kicsit bonyolultabb feladat elé nézünk, mint egy normál
szöveges elem esetében. Egy hivatkozás ugyanis több állapotban lehet, amelyre más-más tulajdonságok adhatók meg,
így magának az A elemnek a formázása nem lesz hatással a hivatkozás megjelenésére. Ezek a lehetséges állapotok a
következők :
1. Ha a böngésző „úgy tudja”, hogy még nem néztük meg a hivatkozást. Ezt a böngésző egy lista alapján dönti el,
amely a beállított időnél régebben meglátogatott címeket már nem tartalmazza. Így a még tényleg nem letöltött
címeken kívül a beállított időtartamnál régebben meglátogatott címek is ebbe a körbe tartoznak. A :link pszeudo
osztályba tartozik az ilyen hivatkozás, így az erre az állapotra vonatkozó beállításoknál ezt kell a szelektorban
használni.
2. Ha a böngésző szerint már letöltöttük a beállított időtartamon belül a címet. Ekkor a :visited pszeudo osztály
tagja a hivatkozás, így ezzel a szelektorral ellátott szabályok érvényesek rá.

83
3. Mint minden más elem, a hivatkozás is az :active pszeudo osztály tagja, ha az egér mutatója az elem fölött
tartózkodik, és az egér valamelyik gombja éppen lenyomott helyzetben van.
4. Amennyiben az egér az elem fölött található – szintén bármely elemre igaz lehet –, de nincs egyetlen gombja sem
lenyomva, akkor az elem megjelenése a :hover pszeudo osztály segítségével befolyásolható.

A text-decoration tulajdonság segítségével befolyásolható a böngésző alapbeállításától függetlenül a hivatkozások


szövegének aláhúzása. Aki például nem szereti az aláhúzott szövegeket, az ezzel letilthatja azt, de ugyanígy ha a felhasz-
náló a böngészőn kikapcsolja az aláhúzást, akkor is ki lehet kényszeríteni a megjelenését.
Gyakori, egyre terjedő – nem feltétlenül elítélendő – szokás, hogy a hivatkozások csak a színükről ismerhetőek fel
mindaddig, amíg az egeret a hivatkozásra nem visszük. Ekkor viszont megjelenik az aláhúzás, megerősítve a felhasználó
feltételezését, hogy egy hivatkozást lát. Például tegyük fel, hogy sötétkék a betűk színe, és ehhez képest fekete hivatko-
zásokat akarunk aláhúzás nélkül úgy, hogy a meglátogatott hivatkozások legyenek halványabbak, az aláhúzás csak akkor
jelenjen meg, amikor fölötte van az egér, és amikor a felhasználó rákattint, a kattintás idején legyen a szöveg piros színű.
Ezt az alábbi szabályokkal lehet beállítani:

BODY { color: blue}


A:link {color: black; text-decoration: none}
A:visited {color: gray; text-decoration: none}
A:hover {text-decoration: underline}
A:active {color: red; text-decoration: underline}

A fenti példában kihasználtuk, hogy az első két A elemre vonatkozó szabály a hivatkozás színét – elvileg – beállítja.
Ha ez nem működne, akkor az A:hover szelektornál is meg kell adni egy színt.

84
8. fejezet

Képek és egyéb külső objektumok beillesztése

A hivatkozások mellett a hipertext másik fontos jellemzője a multimédia objektumok beillesztésének lehetősége. Ezek
közül a legegyszerűbb a képek használata. Ez a fejezet elsősorban a képek beillesztésével foglalkozik, de szót ejtünk
egyéb objektumok – mozgóképek, hang illetve programok – beillesztéséről is. Nem szól a fejezet a képtérképekről, ame-
lyek logikailag szintén ide tartozhatnának, azonban a képtérképeket egy külön fejezet ismerteti az interaktív weboldalak
készítéséről szóló részben (14.2. fejezet).

8.1. Képek beillesztése


Az IMG elem ott, ahol a HTML kódban szerepel, elhelyez a weboldalon egy képet tartalmazó dobozt. A doboz lehet
szöveg-szintű vagy blokk-szintű, az elhelyezkedésétől függően. A tartalom-doboz mérete alapesetben megegyezik a kép
méretével, azonban ez a width és height paraméterekkel illetve tulajdonságokkal megváltoztatható. Az elemnek nincs
tartalma, csupán nyitótagja. Úgy is tekinthető, hogy a nyitótag lecserélésre kerül a kép tartalmával, amely alaphelyzetben
a sor egy objektuma lesz (szöveg-szintű objektum), azonban bizonyos beállítások lehetővé teszik akár a szöveg mellé
helyezését is (lásd az úsztatott objektumokat: 97. oldal).
Az alt paraméter arra az esetre vonatkozik – a [2] szerint mindenképpen alkalmazni kell – amikor bármilyen ok
miatt a böngésző nem képes a képet megjeleníteni. Ez lehet amiatt, hogy még nem töltődött le, de lehet amiatt is, hogy
egyáltalán nem érhető el, vagy a böngészőn a képek megjelenítése le van tiltva. Minden ilyen esetben az alt paraméter
értéke jelenik meg, mint szöveg. Éppen ezért a paraméter értékét feltétlenül úgy kell megadni, hogy arra utaljon, amit
a kép ábrázolna. Továbbá figyeljünk arra, hogy bizonyos helyeken nem célszerű alternatív szöveget megjeleníteni (pl.
táblázat keretezésére használt sormintánál, bár erre inkább a cella háttérképe alkalmas).
A következő példa (a [1]-ből átvéve) az IMG használatát mutatja. A példában szerepel az alt paraméter arra az
esetre, ha a kép nem jeleníthető meg bármilyen okból, valamint a longdesc paraméter arra a célra, hogy egy bővebb
leírást kapcsoljon a képhez. Ez utóbbi paraméter tényleges használatának megoldása a böngészőre van bízva, azonban a
helyes működés az, ha valahogyan elérhetővé teszi a megadott oldalt a falhasználónak.

<BODY>
<P>
<IMG src="sitemap.gif"
alt="HP Labs Site Map"
longdesc="sitemap.html">
</BODY>

85
74. Az IMG elem

<!ELEMENT IMG - O EMPTY -- Embedded image -->


<!ATTLIST IMG
%attrs; -- %coreattrs, %i18n, %events --
src %URI; #REQUIRED -- URI of image to embed --
alt %Text; #REQUIRED -- short description --
longdesc %URI; #IMPLIED -- link to long description
(complements alt) --
name CDATA #IMPLIED -- name of image for scripting --
height %Length; #IMPLIED -- override height --
width %Length; #IMPLIED -- override width --
usemap %URI; #IMPLIED -- use client-side image map --
ismap (ismap) #IMPLIED -- use server-side image map --
>

Az IMG elem kép beillesztésére szolgál. A kép címét az src paraméter értékeként kell megadni. Az elem lehetséges
paraméterei :

• src: Ez a paraméter adja meg a beillesztendő kép helyét egy URI formájában. A használható formátumok közé
tartozik a GIF, JPEG és a PNG. BMP képet csak azok a böngészők jelenítenek meg, amelyeket a kiszolgáló
operációs rendszer ismeri alapból ezt a formátumot.
• longdesc: Ez a paraméter szintén egy URI-t kap értékül. Az általa megadott állomány egy hosszabb leírását
tartalmazza a képnek.
• name: A képhez rendelhető név. A paraméter csak kompatibilitási okok miatt maradt meg, helyette inkább az
id paramétert célszerű használni.
• id, class: Az elem azonosítására szolgáló paraméterek.
• alt: Amennyiben a kép nem jeleníthető meg, vagy még tart a kép letöltése, akkor ennek a paraméternek a tartal-
ma jelenik meg a kép helyén. Ugyancsak ez a szöveg jelenik meg a kép helyett azokban a böngészőkben, amelyek
nem képesek kép megjelenítésére (pl. Lynx). A szövegre alkalmazandó nyelvet az alt paraméter határozza meg.
• lang és dir az elem nyelvét és írásirányát megadó paraméterek.
• title: A paraméter értéke egy buborékban jelenik meg, amikor az egér az elem fölé kerül.
• style: Helyi stílusszabályok megadását teszi lehetővé.
• Eseménykezelőkhöz tartozó paraméterek.
• ismap és usemap: A képtérképek megadásához szükséges paraméterek. Leírásuk a képtérképekről szóló rész-
ben található. . .
• align, width, height, border, hspace, vspace: A kép méreteit és elhelyezkedését befolyásoló, stílus-
lappal helyettesíthető paraméterei.

86
8.2. Általános objektum beillesztés
A legtöbb böngészőnek a JPEG és GIF képek – az újabbaknál ez igaz a PNG-re is – megjelenítése nem okoz gondot.
Más objektumok kezeléséhez azonban szükségük van olyan erőforrásokra (elsősorban programokra), amelyek segítenek
az objektum megjelenítésében. Az ilyen külső segítséget igénylő objektumok beillesztését, és az őket kezelő program
betöltését egy lépésben végzi el az OBJECT elem.
Általában a weboldal készítőjének három információt kell megadnia :
• A beillesztett objektum értelmezését, feldolgozását végző erőforrást. Például ha a beillesztett objektum egy óra
(például Java appletként megvalósítva), akkor meg kell adni azt a programkódot, amely az objektumot működteti.
Ebben a példában ez nem más, mint maga a Java applet, amely létrehozza az órát.
• A megjelenítendő/feldolgozandó adatot. Ha például az erőforrás egy program, akkor ez a program által feldolgo-
zandó adatok helyét jelenti.
• További értékek, amelyekre az alkalmazásnak a működéséhez szüksége van. Ilyen lehet például a program induló
értékeinek megadása.
Az OBJECT elem mindhárom információ megadását lehetővé teszi. Azonban értelemszerűen nem kell minden esetben
mindhárom információfajtát megadni. Ha például egy olyan alkalmazást akarunk beilleszteni a weboldalba, amely nem
igényel külső adatokat, akkor nincs szükség az adatok megadására. A fenti felsorolásban szereplő óra applet esetében
például nincs szükség külső adatokra, azonban szükség lehet az óra kezdeti értékeinek megadására.
Az induló adatok megadását másnéven a program paraméterezésének nevezzük. Ezeknek a paramétereknek a mega-
dására a PARAM elem szolgál (lásd 76. szabályt).
Az OBJECT elem elhelyezhető a HEAD elemen belül is. Ilyenkor természetesen az elem nem jelenít meg semmilyen
objektumot a weboldalon, így az ilyen OBJECT elemeknek olyanoknak kell lenniük, amelyek valóban nem hoznak létre
megjelenítendő objektumot. Létrehozhatnak azonban megszólaltatandó objektumot, vagy felhasználhatók arra, hogy egy
több keretből álló web-dokumentum egyes keretei között információt osszunk meg.1
Amennyiben a böngésző képes az objektum megjelenítésére, úgy az OBJECT elem tartalmát figyelmen kívül hagyja –
kivéve a benne található PARAM elemeket, amelyek az objektum paramétereit adják meg. Ha az objektum megjelenítése
bármely ok miatt lehetetlen, akkor az OBJECT elem tartalmát jeleníti meg helyette (a PARAM elemek kivételével). Ez
lehetővé teszi azt is, hogy ha egy adott objektumfajta nem megjeleníthető, akkor egy beágyazott újabb OBJECT elemmel
ugyanazt más típusban próbáljuk meg megjeleníteni. A következőkben erre láthatunk néhány példát.
Az első példa egy Python nyelven írt applet beillesztését mutatja :
<P><OBJECT classid="http://www.miamachina.it/analogclock.py">
</OBJECT>

Mint látható, ez az alkalmazás nem igényel sem kezdő paramétereket, sem pedig külső adatokat, így csak a classid
paraméter szerepel a programkódot tartalmazó állomány címének megadására. Amint a programkód letöltése befejező-
dött, az általa létrehozott óra azonnal elindul.
Ha akkor is szeretnénk valamit megjeleníteni, ha a böngésző nem képes a Pythonban írt kód értelmezésére és végrehaj-
tására, akkor az OBJECT elem belsejében elhelyezhetjük az ebben az esetben megjelenítendő HTML kódot, a következő
példában ez egy egyszerű szöveg:
<P><OBJECT classid="http://www.miamachina.it/analogclock.py">
An animated clock.
</OBJECT>
1 Mint említettük a fejezet elején, nem minden lehetőséget fogunk bemutatni. Az itt említett lehetőségek is azok közé tartoznak, amelyekkel nem

kíván a könyv bővebben foglalkozni. Akit az OBJECT elem használata az itt leírtaknál jobban érdekel, a [1]-ben bővebb leírást is találhat. . .

87
A következő példa már azt az esetet mutatja, amikor több alternatívát kínálunk a böngészőnek : először egy appletet
próbálunk megjelentetni, amely Python nyelven például a Föld forgását szimuláló animáció lenne ; ha ez nem jeleníthető
meg, akkor egy MPEG videót, mint animációt a Földről, ha ez sem működik, akkor egy GIF képet a Földről, végül, ha ez
sem megy, akkor egy magyarázó szöveget:2

<P> <!-- Először, próbáljuk a Python applet-et -->


<OBJECT title="A Föld az űrből nézve"
classid="http://www.observer.mars/TheEarth.py">
<!-- ha nem: próbáljuk az MPEG videót -->
<OBJECT data="TheEarth.mpeg" type="application/mpeg">
<!-- ha ez sem: a GIF képet -->
<OBJECT data="TheEarth.gif" type="image/gif">
<!-- végül marad a szöveg... -->
A <STRONG>Föld</STRONG> az űrből nézve.
</OBJECT>
</OBJECT>
</OBJECT>

Utolsó példánk a PARAM elem használatát mutatja. A korábbi óra példát egészítjük ki az órát megvalósító applet
szélességének és magasságának megadásával:
<P><OBJECT classid="http://www.miamachina.it/analogclock.py">
<PARAM name="height" value="40" valuetype="data">
<PARAM name="width" value="40" valuetype="data">
Ez a böngésző nem képes Python alkalmazások kezelésére.
</OBJECT>
Megjegyzés. A [1] további példákat is tartalmaz még az OBJECT és a PARAM elemek használatára. Ezeket egyrészt
azért nem mutatjuk be, mert elsősorban a képek megjelenítésével foglalkozunk, másrészt nem is lenne helyes egy másik
dokumentumot teljesen lemásolni, mivel aki akarja, megtalálhatja azokat a példákat az eredeti helyén is. . .

2 Ez és az előző példák a [1]-ből származnak. . .

88
75. Az OBJECT elem

<!ELEMENT OBJECT - - (PARAM | %flow;)* -- generic embedded object -->


<!ATTLIST OBJECT
%attrs; -- %coreattrs, %i18n, %events --
declare (declare) #IMPLIED -- declare but don’t instantiate flag --
classid %URI; #IMPLIED -- identifies an implementation --
codebase %URI; #IMPLIED -- base URI for classid, data, archive--
data %URI; #IMPLIED -- reference to object’s data --
type %ContentType; #IMPLIED -- content type for data --
codetype %ContentType; #IMPLIED -- content type for code --
archive CDATA #IMPLIED -- space-separated list of URIs --
standby %Text; #IMPLIED -- message to show while loading --
height %Length; #IMPLIED -- override height --
width %Length; #IMPLIED -- override width --
usemap %URI; #IMPLIED -- use client-side image map --
name CDATA #IMPLIED -- submit as part of form --
tabindex NUMBER #IMPLIED -- position in tabbing order --
>

Az OBJECT elem általában egy külső erőforrásnak a weboldalba történő beillesztésére szolgál. Ilyen erőforrás lehet
a képtől kezdve a hangokig bármi – akár újabb weboldal is, bár arra inkább az IFRAME elemet szokás használni.
Paraméterei a következők:
• A szokásos paraméterek (id, class, . . . , style és az eseménykezelők).
• classid: Az objektum feldolgozásához szükséges erőforrás vagy program címének (URI) megadására szolgál.
Hasonló célt szolgál a data paraméter is: bizonyos objektumfajtáknál együtt kell szerepelniük, máshol a kettő
közül az egyikre van szükség.
• codebase: A classid, data és archive paraméterekben szereplő relatív URI-khoz ad meg viszonyítási
alapot (ez is URI). Ha nem szerepel, a BASE elemben megadott értéktől függetlenül az aktuális dokumentumot
használja viszonyítási alapként.
• codetype: A classid által megadott erőforrás típusát adja meg (pl. text/java). A paraméter elhagyható,
ugyanakkor a megadása segíti a böngészőt annak eldöntésében, hogy az adott objektumot képes-e megjeleníteni.
Ha nem szerepel, akkor a type paraméterrel azonos értékűnek kell tekinteni.
• data: Az objektum címét adja meg (URI), tehát képek esetében megfelel az IMG src paraméterének.
• type: A data által megadott objektum típusát adja meg (pl. image/jpeg).
• archive: Ez a paraméter egy szóközökkel elválasztott címlistát tartalmazhat. A listával azokat az archívumokat
lehet megadni, amelyekben rá lehet keresni a szükséges erőforrásra az objektum megjelenítéséhez.
• declare: Ez a logikai paraméter (ha szerepel, akkor igaz az értéke, különben hamis) arra szolgál, hogy meg-
mondja a böngészőnek: ez nem az a hely, ahova az objektumot be kell illeszteni, itt csupán azért szerepel, hogy
hamarabb sor kerülhessen az objektumhoz tartozó állományok letöltésére.
• standby: Megfelel az IMG elem alt paraméterének : A betöltés alatt megjelenítendő szöveget adja meg.

89
76. A PARAM elem : objektum paraméterezése

A PARAM elem kizárólag egy OBJECT elem belsejében használható, az OBJECT elem által megadott objektumnak
induláskor átadandó paraméterek átadására.

<!ELEMENT PARAM - O EMPTY -- named property value -->


<!ATTLIST PARAM
id ID #IMPLIED -- document-wide unique id --
name CDATA #REQUIRED -- property name --
value CDATA #IMPLIED -- property value --
valuetype (DATA|REF|OBJECT) DATA -- How to interpret value --
type %ContentType; #IMPLIED -- content type for value
when valuetype=ref --
>

Az elem paraméterei a következők:


• id: az elem egyedi azonosítója.
• name: a beillesztett objektum egyik paraméterének a neve, feltételezve, hogy az objektum ismeri a megadott ne-
vű paramétert. Az, hogy a kis- és a nagybetű különbözőnek számít-e az objektumtól függ. Ennek a paraméternek
a megadása mindig kötelező.

• value: a name által megadott nevű paraméter értéke.


• valuetype: A value típusát adja meg:
– data: mint szöveg adandó át a paraméterérték az objektumnak ;
– ref: mint URI adandó át a paraméter az objektumnak (a böngésző nem próbálja meg feloldani) ;
– object: a value értéke egy másik OBJECT elem id paramétere által megadott azonosítóra mutató
referencia ugyanebben a dokumentumban.
• type: amennyiben a valuetype értéke ref, ez a paraméter a value által megadott erőforrás típusát hatá-
rozza meg.

A PARAM elemeket mindig annak az OBJECT elemnek a közvetlen leszármazottjaként kell megadni, amely OBJECT
elemhez tartoznak. Az OBJECT elemen belül először kell mindig a PARAM elemeket szerepeltetni, és csak azután
következhet minden egyéb tartalom.

90
8.3. Képek formázása
A képek formázása során beállítható a kép elhelyezkedése a dokumentum többi tartalmához képest, a kép mérete, valamint
a kép körüli keret és margó tulajdonságai. Kezdjük a legegyszerűbbel, a margók és keretek kérdésével.

8.3.1. Képek keretezése


A kép körül megjelenő keretet is a border-? tulajdonságok befolyásolják. A keret és a kép közötti távolság a belső margó
(padding tulajdonságok), míg a keret és a környező egyéb objektumok közötti távolság a margók állításával (margin
tulajdonságok) szabályozható. Amennyiben nincs keret, akkor a kép és a környező tartalom távolsága a margó és a belső
margó együttes méretétől függ.
Fontos még tudni, hogy ha egy képet hivatkozásba helyezünk, akkor alapértelmezésben megjelenik körülötte egy
keret, amelynek színe megegyezik a hivatkozásokhoz beállított színnel. Ez eltüntethető az A elem border paraméterének
nullára állításával, vagy az A elembe kerülő kép keretének letiltásával például az alábbi szabállyal :
A IMG, A OBJECT {border: none}

Az alábbi szabály beállítja az IMG elemet úgy, hogy a kép látszólag kiemelkedjen a háttérből, és a keret körül 1em
méretű margó legyen minden oldalon:
IMG {
border-style: outset;
border-color: blue;
border-width: 0.5em;
margin: 1em;
padding: 0
}

8.3.2. Képek mérete


Bár az IMG elem rendelkezik a width és height paraméterekkel, használata problémás lehet. Amennyiben százalékos
értéket adunk meg, az nem a kép tényleges méretében értendő, hanem a weboldal megjelenítésére rendelkezésre álló
szélesség és magasság relatív értéke. Ez azt jelenti, hogy szinte biztosan torzítani fogja a képet a százalékos méretezés.
Ugyanez érvényes akkor is, ha a paraméterek helyett a width és height tulajdonságokat használjuk százalékokkal.
Másrészt problémás lehet a méretek megadása amiatt is, hogy az egyes képek nem azonos méretűek, így a stíluslapon
minden képhez ugyanazt a méretet rendelni nem feltétlenül jó ötlet.
A nagy képek megjelenítése, főleg egy dokumentum nyitóoldalán nem helyes, ahogyan azt a Netikett is tartalmazza :
„Kéretlenül és figyelmeztetés nélkül ne küldjünk nagy méretű állományokat !” Bár ez eredetileg a levelezésre vonatkozott,
a weboldalakra is igaz: ha valakinek lassú és időarányos díjfizetéses az internetkapcsolata, az nem fog örülni annak, ha
a weboldal letöltése során egy vagy több nagyméretű kép letöltésére kell órákon át várnia ahhoz, hogy a szükséges
információhoz hozzájusson.
Ezért tehát alapvető – sajnos sokak által megszegett – szabály : a kezdőoldalon nem helyezünk el nagy sávszélességet
igénylő, jelentős méretű objektumokat, legyen az kép, vagy animáció. A későbbi oldalaknál szintén célszerű alkalmazni
ezt az elvet.
A nagyméretű képeket úgy illik elhelyezni a weboldalon, hogy egy kis „bélyegképet” helyezünk el az oldalon, amely
megmutatja kicsiben a tartalmát, és ez a bélyegkép egyben hivatkozás a teljes kép vagy animáció címére. Az a felhasználó,
aki látni akarja a képet vagy animációt, rákkattint a hivatkozásra, és türelmesen kivárja a betöltését, aki nem kíváncsi a
képre, az nem fog bosszankodni a számára fölösleges várakozás miatt.
Igen ám, de a bélyegkép nem lehet akármilyen ! Amennyiben az eredeti képet illesztjük be úgy, hogy a szélességét és
magasságát megadva lekicsinyítjük, akkor a böngésző továbbra is betölti az eredeti nagyméretű képet, csak kicsinyítve
jeleníti meg. Ez azt jelenti, hogy a kép letöltése ugyanannyi ideig tart, tehát ugyanúgy lassítja a weboldal megjelenítését.

91
Az ilyen hibás megoldást könnyen fel lehet ismerni arról, hogy a bélyegképre kattintva a nagy kép azonnal megje-
lenik, minden további töltődés nélkül, hiszen már le van töltve. Amennyiben ehelyett lassan bontakozik ki a kép, akkor
valóban a bélyegképre kattintás után kezdi el a böngésző letölteni, tehát a bélyegkép valódi bélyegkép. Hogyan lehet ezt
megvalósítani ?
Úgy, hogy a használandó méretben készítünk a nagy képről, vagy annak egy jellemző részéről egy kisebb méretű
képet, amelyet így már átméretezés nélkül lehet a neki szánt helyen megjeleníteni. Ezek után lesz két képünk : az eredeti
kép, és a kis bélyegkép. Ha például az eredeti neve bigpict.png volt, a bélyegkép neve smallpict.jpg (a png
kevésbé tömör, mint a jpg), és szeretnénk ha egy külön ablakban nyílnának meg a nagy képek, akkor a következő HTML
kódot használhatjuk:
<A href="bigpict.png" target="pictures" title="A teljes kép megnyitása">
<IMG src="smallpict.jpg" border=0>
</A>
További fontos képformázási lehetőség a képnek és a környező szövegnek az egymáshoz viszonyított helyzetét befo-
lyásoló úsztatás, amelynek ismertetése a 9.3. szakaszban található a 97. oldalon. . .

92
9. fejezet

A vizuális megjelenés modellje

A korábbi fejezetek már elég sokat foglalkoztak néhány olyan fogalommal, amelyet még nem teljesen magyaráztunk meg.
Ennek oka, hogy ha mindjárt az elején elkezdtünk volna ezzel foglalkozni, akkor mindenkinek elment volna a kedve a
sok elméleti ismeret miatt a weboldalaktól. Most viszont idáig eljutva már remélhetőleg mindenki elég sok weboldalt
készített ahhoz, hogy ne rettenjen vissze egy kis elmélettől, amely szintén sok hasznos segédeszközre derít még fényt.
Ilyen hasznos segédeszköz lesz az úsztatás, vagy az elemek fix pozícionálása, amelyről szintén ebben a fejezetben lesz
szó.
A következőkben kifejezetten a weboldal vizuális megjelenítésekor használt modellről, és az ezzel összefüggő tulaj-
donságokról lesz szó. Először ismerkedjünk meg két fontos fogalommal, amelyeket korábban már használtunk. Ezután
bemutatunk néhány olyan tényezőt, amely a weboldal megjelenését befolyásolja. Ilyen, a megjelenést befolyásoló tényező
a következő :
• A dobozok méretei és típusa.
• A dobozok pozícionálása (normál, úsztatott és abszolút pozíció).

• A dokumentum fán belüli kapcsolat az elemek között.


• Külső információk, mint például a megjelenítő ablak (viewport).

A megjelenítő ablak (viewport) Azok a megjelenítő eszközök, amelyek folytonos formában jelenítik meg a weboldalt
– mint amilyen például egy böngésző – a dokumentumnak általában csak egy részét jelenítik meg egy időben. Ezt a
téglalap alakú részt nevezik angolul viewportnak. Amennyiben ez a megjelenítő ablak nem elegendő a teljes dokumen-
tum megjelenítésére, akkor a dokumentum fölötti elmozgatását a megjelenítő program gördítősávok segítségével teszi
lehetővé.
Ez a viewport úgy képzelhető el, hogy van egy kiterjedése (vízszintesen és függőlegesen is) a dokumentumot tartal-
mazó doboznak (a BODY elem dobozának). Efölött a viewport olyan, mint egy ablak, amelyen keresztül a felhasználó
azt a részét láthatja a dokumentumnak, amely fölött az ablak elhelyezkedik. Innen származik a viewport magyar neve :
megjelenítő ablak. Az ablakot elmozgatva a dokumentum más-más része válik láthatóvá.
A BODY elem doboza – a már korábban definiált vászon – általában megpróbál a megjelenítő ablakhoz igazodni
legalább szélességben. Ez azt jelenti, hogy ha nincs semmi, ami ezt megakadályozza, akkor a két téglalap szélessége
megegyezik. A vászon mindig legalább olyan széles és olyan magas, mint a megjelenítő ablak. Ha valamely doboz szé-
lessége miatt az így adódó szélesség nem elég, akkor lesz a vászon szélesebb a megjelenítő ablaknál, a vászon magassága
pedig mindig lehet nagyobb a megjelenítő ablaknál, ha a használt szélességgel a megjelenítő ablak magassága nem elég
a teljes dokumentum megjelenítésére.

93
A legtöbb esetben a megjelenítő ablakban egyetlen vászon jelenik meg. Azonban ha például a dokumentumban kere-
teket is alkalmazunk, akkor megjelenítő ablak több vászon között oszlik meg, és lehet olyan eset is, amikor egy vászon
más-más részeit más-más megjelenítő ablakokban láthatjuk.

Tartalmazó dobozok A tartalmazó doboz (containing box) az egyes elemek tartalmát megjelenítő doboz (lásd a doboz-
modellnél), amelynek pozíciója és szélessége/magassága a megfelelő tulajdonságokkal befolyásolható. A dobozhoz tarto-
zó margók és keretek természetesen a szomszédos dobozok elhelyezkedését befolyásolhatják, de elsődlegesen a tartalma-
zó doboz helyzetét tudjuk befolyásolni. Általában egy elem tartalom-dobozán belül jelenik meg az elem minden leszárma-
zottja által generált doboz a margóival és kereteivel együtt. Maga a vászon tulajdonképpen a BODY elem tartalom-doboza
és esetleges margói által elfoglalt doboz, és minden, ami a weboldalon található – mivel a BODY elem leszármazottja – a
BODY elem tartalom-dobozán belül jelenik meg (ez az oka, hogy a vászon szélessége lehet nagyobb a megjelenítő ablak
szélességénél : mindennek bele kell férnie a BODY tartalom-dobozába).
Ez visszafelé így értelmezendő: egy elem dobozát teljes egészében tartalmazza annak az elemnek a tartalom-doboza,
amely elemnek a közvetlen leszármazottja. Ezt a dobozt nevezzük az adott elem dobozának tartalmazó dobozának, ango-
lul ez a containing box.
Amennyiben az egyes dobozoknak pontos szélességet, magasságot és pozíciót adnak meg, előfordulhat, hogy nem
férnek el tartalmazó dobozukban (ha annak is van pontos dimenziója), hanem kilógnak belőle. Létezik tulajdonság, amely
azt befolyásolja, hogy ilyenkor mi történjen a kilógó részekkel. Ezek a haladó weboldalkészítésről szóló részben szere-
pelnek, mivel nagyon jól ki lehet őket használni a JavaScript-tel támogatott interaktív weboldalakon például fényreklám
vagy folyamatosan scrollozott szöveg előállítására. . .

9.1. A dobozok típusai


Minden elemnek van egy típusa, amit a display tulajdonság értéke határoz meg. A legtöbb elemnél – HTML esetén – ez
az érték nem módosítható, de vannak esetek, amikor ez megtehető. A következőkben a fontosabb doboz-típusokról lesz
szó.

9.1.1. Blokk-szintű dobozok


A blokk-szintű doboz – mint azt korábban már említettük – olyan doboz, amelynek több sornyi szöveg is lehet a tartalma,
és amely ebből következően egy nagyobb téglalapot alkot. A display tulajdonság értéke a blokk-szintű elemeknél lehet
blokk, list-item (lista egy eleme), compact vagy run-in.
A blokk-szintű elemek egy alap-dobozt hoznak létre, amely kizárólag további dobozokat tartalmazhat. Ez az alap-
doboz lesz, minden leszármazott doboz tartalmazó doboza. Amennyiben a blokk-szintű elem nem a normál megjelenítés
alá esik, akkor az alap-doboz lesz az előírt pozícióba helyezve, és minden leszármazottja ebbe az alap-dobozba kerül.
Egyes blokk-szintű elemek az alap-dobozon kívül is létrehoznak dobozt. Ilyenek a listaelemek (a display tulajdonság
értéke list-item), amelyek létrehoznak egy dobozt a szimbólum számára (marker).
Előfordulhat, hogy a dokumentumfában nem szereplő elem is létrehoz blokk-dobozt. Ezeket névtelen doboznak ne-
vezzük. Vegyük a következő kódrészletet:

<DIV>
Némi szöveg
<P>További szöveg</P>
</DIV>
Itt a DIV blokk-szintű elem által létrehozott doboz két további blokk-szintű dobozt is tartalmaz. Az első egy névtelen do-
boz, mintha egy P elem hozná létre, tartalmazza a „Némi szöveg” bekezdést. Ezután következik a P elem által létrehozott
újabb bekezdésdoboz. (Ebben a példában a P elem már nem első gyermeke a DIV elemnek, tehát a :first-child
szelektor nem választja ki.)

94
9.1.2. Szöveg-szintű dobozok
A szöveg-szintű elemek szöveg-szintű dobozokat hoznak létre. Ezeknél az elemeknél a display értéke lehet inline,
inline-table, compact és run-in. A szövegbeli elem tartalma egy vagy több sorba tördelve jelenik meg egy
blokk-szintű elem által létrehozott doboz tartalmaként. Természetesen minden sor önálló dobozként is tekinthető, és így
lehet kerete vagy saját háttere a szövegnek.
Amennyiben a display értéke compact, az elem tartalma egy blokk-szintű doboz margóján jelenik meg önálló doboz-
ban. Ugyanígy helyezkedhet el egy listaelem szimbólumát tartalmazó marker doboz is a listaelem blokk-szintű dobozának
margóján.
Ahogy létezik névtelen blokk-szintű doboz, úgy létezik névtelen szöveg-szintű doboz is:
<P>Némi <EM>kiemelt</EM> szöveg</P>

Ebben a példában a P elem blokk-szintű dobozában – feltéve hogy a tartalma elfér egy sorban – egy sor szöveg jelenik
meg, amely három szöveg-szintű dobozt tartalmaz : az első egy névtelen doboz az EM elem előtti tartalommal, utána az
EM elem szöveg-szintű doboza, végül egy újabb névtelen doboz az EM elem utáni tartalommal. Az ilyen névtelen szöveg-
szintű dobozok a tulajdonságaikat az őket létrehozó blokk-szintű doboztól öröklik, illetve a nem öröklődő tulajdonságok
az alapértelmezett értéküket veszik fel – mivel nincs rá lehetőség, hogy valahol azokat más értékre állítsa valaki. . .

9.1.3. Kompakt dobozok


A kompakt doboz az a doboz, amelynek display tulajdonsága a compact értéket kapta. Ilyen kompakt dobozba kerülhet
például a DT elem tartalma.
Ha egy blokk-szintű doboz, amely nincs úsztatva, vagy megadott pozícióval ellátva, egy kompakt dobozt követ a
HTML kód szerint, a kompakt doboz egysoros szöveg-szintű dobozként viselkedik. Az így létrejött doboz szélessége és
a blokk-szintű doboz oldalsó margójának vastagsága befolyásolja a kompakt doboz helyzetét. Hogy melyik oldali az a
kompakt dobozt létrehozó elem direction tulajdonságától függ. Amennyiben a kompakt doboz szélessége a megfelelő
oldali margó szélességénél nem nagyobb, a doboz a margóra kerül.
Amennyiben az előző bekezdés elején szereplő feltételek nem teljesülnek, a kompakt doboz blokk-szintű dobozként
jelenik meg.
Bővebben a kompakt dobozok viselkedéséről a [2]-ben lehet olvasni. . .

9.1.4. „run-in” dobozok


Amennyiben a display tulajdonság értékét a run-in-re állítjuk, az elem tartalma megjelenhet az őt követő blokk-szintű
elemmel egy dobozban. Ez megfelel annak, amikor egy bekezdésnek külön címet adunk, amely a bekezdés szövegével
egy sorban jelenik meg:

Ez egy „run-in” doboznak megfelelően megjelenő címmel ellátott bekezdés.


Amennyiben a „run-in” dobozt egy blokk-szintű elem követi, és annak szélessége elég ahhoz, hogy a „run-in” doboz
tartalma elférjen egy sorban, úgy a blokk-szintű elem első sorában szöveg-szintű dobozban jelenik meg. Ellenkező esetben
külön blokk-szintű doboza lesz.
Íme használatára egy példa:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD>
<TITLE>A run-in box example</TITLE>
<STYLE type="text/css">
H3 { display: run-in }
</STYLE>

95
</HEAD>
<BODY>
<H3>A run-in heading.</H3>
<P>And a paragraph of text that
follows it.
</BODY>
</HTML>
Ez valahogy így jelenne meg:

A run-in heading. And a paragraph of text that follows it.

9.1.5. A display tulajdonság


Ennyi bevezető után már megismerkedhetünk a display tulajdonság teljes definíciójával.

77. A display tulajdonság

A display tulajdonság meghatározza, hogy az elem hogyan jelenik meg a dokumentumban. HTML esetén a legtöbb
elemnél ez a tulajdonság nem módosítható, azonban bizonyos elemeknél meg lehet változtatni az értékét.
Lehetséges értékei a következők:
• blokk: az elem blokk-szintű dobozt hoz létre a tartalma megjelenítésére.
• inline: az elem szöveg-szintű dobozokat hoz létre az őt tartalmaző blokk-szintű doboz belsejében.
• list-item: az elem tartalma egy olyan blokk-szintű dobozba kerül, amely a listaelemekre jellemző formázást
kap, és amelyhez tartozik egy külső, egysoros szöveg-szintű doboz is a listaszimbólum számára. Általában az LI
elem ilyen típusú.
• marker: például a listaszimbólum számára létrejött doboz ilyen típusú. Kizárólag a :before és :after
pszeudo elemeknél használható.
• none: az elem és leszármazottai egyáltalán nem hoznak létre dobozt, vagyis az ilyen értékű elemek nem jelennek
meg a weboldalon. Még akkor sem jelenhet meg egy elem, amely az így beállított elem leszármazottja, ha annak
display tulajdonsága más értéket kap.
• run-in és compact: A tartalmuktól függően lehetnek blokk- vagy szöveg-szintű elemek.
• table, inline-table, table-row-group, table-column, table-column-group,
table-header-group, table-footer-group, table-row, table-cell, table-caption: a
táblázat különböző részeinél használt elemek típusa.
A tulajdonság értéke nem öröklődik, alapértelmezett értéke mindig az adott elemtől függ.

9.2. A pozícionálási lehetőségek


A CSS2 háromfajta pozícionálási módos ismer, amely mindegyike más-más módon helyezi el egymáshoz képest a dobo-
zokat :

96
1. Normál pozícionálás esetén (ezt angolul a normal flow kifejezéssel illetik) az egyes blokk-szintű dobozok egymás
alá kerülnek, egy adott dobozon belül a szöveg-szintű tartalmak pedig soronként követik egymást, ahol egy sor
az őt tartalmazó doboz egyik oldali margójától a másik oldali margóig tart. Az eddigiekben minden esetben ezt a
pozícionálási módot tételeztük fel. Azért hívják normál pozícionálásnak, mert ha mást nem mondunk, akkor ezt a
módszert követi a megjelenítés.
2. Úsztatás (float) esetén a doboz először is kikerül a normál pozícionálás során alkalmazott eljárás alól, és a weboldal
valamelyik szélén jelenik meg. A normál pozícionálással megjelenítendő elemek „körbefolyják” ezt a dobozt, és
a bennük levő szöveg-szintű elemek – ha ez lehetséges – véget érnek az úsztatott doboz margójánál. A következő
szakaszban bővebben is szó lesz erről.
3. Abszolút pozícionálás esetén a doboz szintén kikerül a normál pozícionálásból, és egy pontosan meghatározott
(fixed), vagy a dobozt létrehozó elemet közvetlenül tartalmazó elem dobozához relatív (relative) pozícióban jelenik
meg.
A pozícionálást a position és a float tulajdonságok szabályozzák.

78. A position tulajdonság

A position tulajdonság az elem által generált doboz pozícionálási módját határozza meg. Alapértelmezett értéke minden
elem esetében static, amely a normál pozícionálást jelenti. A tulajdonság lehetséges értékei a következőt jelentik :
• static: A doboz a normál pozícionálás szerint kerül elhelyezésre, a top és left tulajdonságok hatástalanok.
• relative: A doboz helyzete a normál pozícionálás alapján kerül kiszámításra. Ezután a doboz az így kiszá-
mított helyzetéhez képest a top és left tulajdonságok által megadott mértékben eltolásra kerül.
• absolute: A doboz kikerül a normál pozícionálás hatálya alól. A left, right, top, bottom tulajdonságok által
meghatározott helyre kerül, amelyet mindig a tartalmazó dobozhoz képest kell mérni.

• fixed: Hasonló a absolute értékhez, de ezúttal a viszonyítási alap a megjelenítő ablak, amelyen belül a
doboz rögzített, tehát esetleges gördítés esetén is a helyén marad. Nyomtatás esetén az így beállított doboz
minden oldalon azonos pozícióban megismétlődik.

A pozícionálásról további ismertetés – többek között az ide tartozó további tulajdonságok is – a JavaScript ismerteté-
séről szóló részben található, ahol konkrét alkalmazások is vannak ezekre a tulajdonságokra. . .

9.3. Úsztatás
Az úsztatás során egy doboz kikerül a normál pozícionálás hatása alól, és a dokumentum jobb vagy bal oldalára kerül. A
normál pozícionálás hatálya alá eső objektumok a balra úsztatott doboz jobboldalán, a jobbra úsztatott doboz baloldalán
jelennek meg. Az úsztatott doboz mindig azon a helyen – vagy ha ott már nem fér el : ez alatt a lehetséges legmagasabban
levő helyen – kezdve jelenik meg, ahol ha nem lenne úsztatva, a normál pozícionálás szerint kezdődnie kellene.

97
79. A float tulajdonság

Ez a tulajdonság adja meg, hogy egy elem dobozát – és minden bele kerülő dobozt – el kell-e tolni jobbra vagy
balra a dokumentum szélére. Minden olyan elemnél használható, amelynek doboza nem lett a position tulajdonsággal
pozícionálva.
Lehetséges értékei a következők:
• left: A doboz a baloldalra úsztatva jelenik meg. A normál pozícionálás hatálya alá eső tartalom a dobozt
jobbról folyja körbe.
• right: A doboz a jobboldalra úsztatva jelenik meg. A normál pozícionálás hatálya alá eső tartalom a dobozt
balról folyja körbe.
• none: (alapértelmezett érték) A doboz nincs úsztatva, ha a position tulajdonság sincs beállítva, akkor a doboz
része a normál pozícionálás hatálya alá eső tartalomnak.

Az úsztatás pontos menetének leírása megtalálható a [2]-ben. . .

80. A clear tulajdonság

A clear tulajdonság meghatározza, hogy melyik oldalon levő, korábban elhelyezkedő úsztatott objektum mellé nem ke-
rülhet az adott elem tartalma. Az ilyen tartalom mindenképpen lejjebb kerül annyival, hogy teljes egészében a korábban
kezdődött úsztatott objektum alá kerüljön. Azonban az ilyen tartalom is kerülhet úsztatott objektum mellé, amennyiben
az később kezdődik. Kizárólag blokk-szintű elemeknél alkalmazható – beleértve az úsztatott objektumokat is.
A tulajdonság lehetséges értékei:
• left: A balra úsztatott objektum mellé kerülést akadályozza meg.
• right: A jobbra úsztatott objektum mellé kerülést akadályozza meg.

• both: Mind a jobbra, mind a balra úsztatott objektum mellé kerülést megakadályozza.
• none: Az elem tartalma kezdődhet úsztatott objektum mellett. Ez az alapértelmezés.
Amennyiben egy úsztatott objektumra adjuk meg az adott oldalra a clear értékét, azzal azt érhetjük el, hogy az úsztatott
objektum az előző úsztatott objektum alatt fog elhelyezkedni.a
a Nem minden böngésző teljesíti ezt a kívánságot, bár hivatalosan így kellene működnie. . .

Két azonos oldalra úsztatott doboz megjelenhet egymás mellett. Ilyenkor a forráskódban később szereplő elem doboza
kerül beljebb a dokumentumba, mivel az az előző úsztatott objektum mellé kerülhet, a dokumentum szélére már nem.
Minden olyan doboznak, amelyet az úsztatott dobozt létrehozó elem leszármazottja hoz létre, az úsztatott dobozon
belül a normál pozícionálás szerint kell megjelennie, kivéve, ha az is úsztatott, amely esetben úgy viselkedik, mintha nem
egy már úsztatott doboz tartalmazná.
Minden úsztatott doboznak rendelkeznie kell egyértelműen meghatározott szélességgel, hogy a böngésző meg tudja
határozni, hogy a mellé kerülő objektumok meddig terjedhetnek. Ez a szélesség származhat egy kép esetén onnan, hogy
eleve adott a kép szélessége. Amennyiben a doboznak egyébként nem lenne szélessége, úgy a width tulajdonsággal be
kell állítani a szélességét. Minden úsztatott doboz blokk-szintűvé válik, még akkor is, ha olyan elem hozta létre, amely
egyébként szöveg-szintű dobozt hozna létre: egy SPAN vagy EM elem is úsztatható, amely esetben a szöveg többi része
körbefutja a tartalmát (így hozható létre például iniciálé).

98
9.1. ábra. Balra úsztatott kép és a mellette levő szöveg elhelyezkedése

Mivel az úsztatott doboz nem tartozik a normál pozícionálás hatálya alá, minden olyan doboz, amelyet az úsztatott
doboz előtt helyezünk el, úgy fog megjelenni, mintha az úsztatott doboz ott sem lenne. Ez alól az egyetlen kivétel : az
úsztatott doboz előtt elkezdett bekezdésdoboz sorai az úsztatott doboz mellett lerövidülnek úgy, hogy a szöveg véget érjen
az úsztatott doboz mellett, ilyen módon a szöveg körbefolyik az úsztatott doboz mellett.
Az úsztatott doboz kezdete után kezdődő bekezdések szövege ugyanígy viselkedik : az úsztatott doboz mellett a sorok
véget érnek a doboz határán, de ha a bekezdés tovább ér az úsztatott doboz aljánál, akkor azok a sorok, amelyek a doboz
alja alatt vannak, tovább nyúlnak az úsztatott doboz alá.
A következő példa a left osztályba sorolt képeket balra úsztatja, a jobboldali margót fél EM-re, a baloldalit nullára
állítva (a jobboldali margó azért kell, hogy a kép mellé kerülő szöveg ne ragadjon a képhez) :

IMG.left {
float: left;
margin-left: 0;
margin-right: 0.5em
}
A 9.1. ábra mutatja, hogy egy balra úsztatott kép mellett hogyan jelenik meg az azt körbefutó szöveg. Mint az ábrán
látható, a kép alatt a szöveg úgy folytatódik, hogy egészen az oldal széléig érnek a sorok.
Úsztatott dobozok margói soha nem egyesülnek egyéb dobozok margójával.
Elképzelhető, hogy az úsztatott doboz margója negatív, aminek eredményeként az úsztatott doboz és a mellé kerülő
objektum átfedi egymást. Ilyenkor a doboz mellé kerülő objektum tartalma, kerete és háttere az úsztatott doboz előtt
jelenik meg szöveg-szintű dobozok esetén. Ha az átfedő doboz blokk-szintű, akkor a háttér és a keret az úsztatott objektum
mögött jelenik meg, míg a tartalma az úsztatott objektum előtt. Ennek a szabálynak az eredményét mutatja a 9.2. ábra.

99
9.2. ábra. Az úsztatást átfedő dobozok viselkedése

Amennyiben a következő bekezdést szeretnénk teljesen az úsztatott objektum alatt kezdve megjeleníteni, akkor kell
használni a clear tulajdonságot. Most tegyük fel, hogy a stíluslapon szerepel a
P {clear: left}
szabály. Ez a P elemet a már addig elkezdett valamennyi balra úsztatott objektum alá tolja, ahogyan az a 9.3. ábrán látható.
Ezt úgy történik, hogy az úsztatott doboz alá tolandó bekezdés felső margója annyival megnő az előző bekezdés aljának és
az úsztatott objektum aljának távolságára. Ebből következően ezt a bekezdést tovább lefelé a bekezdés felső margójának
beállításával nem lehet növelni. Erre a célra inkább az úsztatott doboz alsó margóját kell használni, mivel az nem olvad
bele a többi margóba.

100
9.3. ábra. A clear tulajdonság hatása

9.4. Lapokra bomló megjelenítés (nyomtatás)


Amennyiben a weboldalt lapokra bontva kell megjeleníteni (például nyomtatás esetén), néhány szabályt még az eddigie-
ken felül feltétlenül figyelembe kell venni. Van néhány olyan tulajdonság, amely másképpen viselkedik a lapokra bontott
megjelenítésnél, illetve van néhány speciális tulajdonság, amely kifejezetten a lapokra bontott megjelenítést befolyásolja.
Ezekről szólunk a következőkben.
Először is ilyenkor létezik egy speciális doboz fajta, a lapdoboz vagy oldaldoboz, amely kibővíti a doboz-modellt,
amely a blokk- és a szöveg-szintű dobozokat ismeri. Ezen felül létezik egy új fogalom is a folyamatos megjelenítéshez
képest : az oldaltörés.
Az oldaldoboznak véges szélessége és magassága van, így minden, ami egy adott oldalra kerül, ebbe a méretkorlátba
bele kell férjen. Ezek a méretek persze nem feltétlenül egyeznek meg a tényleges nyomtatási méretekkel. A megfelelő
átkonvertálást mindig a böngésző végzi el (egy lapra két oldal, egy lapra több oldal nyomtatása stb.).
Az oldaldoboz tehát egy téglalap alakú terület, amely két részt tartalmaz :
1. Az oldal-terület tartalmazza az oldalon elhelyezkedő dobozokat. Ennek a külső élei felelnek meg ezeknek a dobo-
zoknak a tartalmazó dobozának. A normál tipográfiában ezt nevezik az oldal szedéstükrének vagy szövegtükrének.
2. A margó, amely körbeveszi az oldal-területet.
Megjegyzés. Mint ebből látható, a CSS2-ben nincs lehetőség az egész oldal bekeretezésére. A tervek szerint a CSS későbbi
változataiban ez megváltozik majd, és erre is lesz majd lehetőség. . .
Az oldaldoboz tulajdonságainak beállítására szolgál az @page szabály. Az @page kulcsszó egy szelektor, amely az
oldaldobozt, mint elemet határozza meg. A CSS2-ben lehet külön szabályt megadni az első oldalra, a páros oldalakra
vagy a páratlan oldalakra.

101
Az oldaldoboz méreteit a size tulajdonsággal lehet megadni. Az oldal-terület mérete az oldaldoboz méretéből a margók
szélességét levonva kapható meg.

81. A size tulajdonság

A size tulajdonság az oldal(doboz) méretét és tájolását – más terminológia szerint az írásirányát – határozza meg. Az
oldaldoboz mérete lehet fix, vagy relatív (méretezhető). Az utóbbi lehetővé teszi a böngészőnek, hogy a tényleges
papírméret alapján állítsa be a doboz méreteit.
Relatív méretet állítanak be a következő értékek:
• auto (alapértelmezés): A doboz a papír méretéhez igazodik.
• landscape: A doboz méretében a papír méretéhez igazodik, de fekvő tájolással, azaz a hosszabb oldalak
lesznek a vízszintesek.
• portrait: A doboz méretében a papír méretéhez igazodik, de álló tájolással, azaz a rövidebb oldalak lesznek
a vízszintesek.

A fix méretek normál hosszmértékként adhatóak meg. Ha csak egy méret van megadva, akkor mindkét oldal egyforma
lesz, tehát négyzet alakú lesz a doboz.

A [2]-ben szereplő példa egy 8,5 × 11 hüvelykes oldaldobozt hoz létre, minden oldalon 2-2 cm méretű margókkal :
@page { size: 8.5in 11in; margin: 2cm }

9.4.1. Oldalmargók
Mint a fenti példából is látható, a margin-top, . . . , margin-left és margin tulajdonságok használhatóak az oldal margójának
beállítására.
Mivel az oldal tartalmához nincs betűkészlet rendelve, így az oldalmargóknál nem használhatóak a betűmérethez
relatív mértékegységek, azaz az em és az ex. A százalékos megadás az oldal szélességéhez (oldalsó margók esetén),
illetve a magasságához (alsó és felső margó esetén) mérendőek.
A negatív margók használata, vagy az abszolút pozícionálás eredményeként előfordulhat, hogy a tartalom kilóg az
oldaldobozból. Ebben az esetben természetesen a kilógó tartalmat levágja a böngésző, a nyomtató, vagy egyszerűen a
papír széle. . .
Nézzünk egy-két példát az oldaldoboz beállítására ! Először állítsuk a méretet a papírméretre, és az így kialakuló méret
tíz százaléka legyen minden oldalon a margó:
@page {
size: auto; /* auto is the initial value */
margin: 10%;
}
Ekkor például egy A4-es lap esetén (21,0 cm × 29,7 cm) a margók 2,1 cm, illetve 29,7 cm méretűek lesznek.
A következő példa a doboz méretének pontos beállítását mutatja :
@page {
size: 8.5in 11in; /* width height */
}

102
9.4.2. Oldalvágás-jelek
A nyomtatott lapokat esetleg szeretnénk összefűzni. Ilyenkor hasznosak az oldalvágást segítő jelek, amelyeket angolul
cross marks illetve crop marks néven említenek.

82. A marks tulajdonság

A marks tulajdonság az oldalvágások jelzésére használható jelek megjelenítését teszi lehetővé a lapon. Megadható a
none kulcsszó az alapértelmezett viselkedésre, amikor nem jelennek meg jelek ; vagy megadható, hogy a kétféle jelből
melyik jelenjen meg: cross és crop.

A crop marks azt a helyet jelzi, ahol a papírt el kell vágni. A cross marks a lapok igazítására szolgál.
Ezek a jelek természetesen csak a fix méretű oldalakon látszanak, hiszen a relatív méretek esetén a nyomtatás úgy
állítja be a doboz méretét, hogy a jel éppen a papír szélére esne.

9.4.3. Oldalfajták
Általában a legtöbb többoldalas nyomtatványnál a páros és a páratlan oldalak nem egyformák. Másrészt az első oldalt,
mint címlapot szintén másképpen szokás formázni. Ezekre is van megoldás.
Minden oldal automatikusan belekerül a :left vagy a :right pszeudo osztályba, így ezeken keresztül megadha-
tunk a kifejezetten baloldali, illetve jobboldali oldaldobozhoz tartozó szabályokat. A következő példa a belső margókat 3,
a külső margókat 4 cm-re állítja:
@page :left {
margin-left: 4cm;
margin-right: 3cm;
}
@page :right {
margin-left: 3cm;
margin-right: 4cm;
}
Hasonlóan az első oldalt a :first pszeudo osztályon keresztül lehet beállítani.

9.4.4. Oldaltörések szabályozása


Az oldaltörés letiltható egy elem belsejében a page-break-inside tulajdonság avoid értékével, vagy egy elem utolsó sora
után illetve az első sora előtt a page-break-after illetve a page-break-before tulajdonság avoid értékével. Előírható az
oldaltörés egy elem első sora előtt illetve az utolsó sora után a page-break-before illetve page-break-after tulajdonság
always értékével. Amennyiben mindenképpen páros vagy páratlan oldalon szeretnénk az oldal tartalmának folytatását,
akkor szintén a page-break-before és a page-break-after tulajdonság left illetve right értéke használható erre.
Egy adott elemen belüli oldaltörést lehet még úgy is szabályozni, hogy nem az egész elemet tartjuk egy oldalon,
csupán azt akarjuk előírni, hogy hány sornak kell együtt maradnia. Erre szolgál az orphans és a widows tulajdonság. A
két tulajdonság neve nem véletlenül jelent árvát illetve özvegyet, ugyanis a tipográfiában az előző oldalon maradó sorokat
árvasoroknak, a következő oldalra átkerült sorokat özvegysoroknak nevezik.

103
83. A page-break-before, page-break-after és a page-break-inside tulajdonságok

A page-break-before, page-break-after és a page-break-inside tulajdonságok valamely elem előtt (before), után (after)
illetve közben (inside) új oldalt kezdenek, vagy letiltják az új oldal kezdését. Mindhárom tulajdonság lehetséges értékei :
• auto (alapértelmezés mindhárom tulajdonság esetén) : sem nem kényszerít ki, sem nem tilt le oldaltörést.

• always mindenképpen kikényszerít egy sortörést az elem előtt illetve után (közben nem lehet).
• aviod letiltja a oldaltörést az elem előtt, után, illetve közben. A közben történő oldaltörés azt jelenti, hogy az
elemnek egy oldalon kell teljesen lennie.
• left Egy vagy két oldaltörést kényszerít ki az elem előtt illetve után (közben nem lehet) úgy, hogy a következő
oldal baloldalként szerepeljen. (Nem jelent üres oldal nyomtatást feltétlenül.)
• right Hasonló a left értékhez, de a következő oldal jobboldalként szerepel.

84. Az orphans tulajdonság

Az orphans tulajdonság a legkevesebb megengedett árvasor-számot adja meg. Alapértelmezett értéke kettő, vagyis nem
maradhat egy sor egyedül az oldal alján. Ha egy bekezdésnek a megadott számúnál kevesebb sora maradhatna az oldal
alján, akkor az egész bekezdést át kell vinni a következő oldalra.

85. A widows tulajdonság

A widows tulajdonság a legkevesebb megengedett özvegysor-számot adja meg. Alapértelmezett értéke kettő, vagyis
nem kerülhet egy sor önmagában az új oldalra. Ha egy bekezdésnek a megadott számúnál kevesebb sora kerülne az új
oldal tetejére, akkor annyival korábban kell a bekezdésben az oldaltörést elhelyezni, hogy elegendő sor kerüljön az új
oldalra.

104
10. fejezet

Táblázatok készítése

A táblázatok az adatok közötti kapcsolat megmutatására szolgálnak. Igaz ugyan, hogy elég sok olyan weboldalat látni,
amelyben a táblázat funkciója csupán a tartalom formázása, azonban ilyen célra táblázatot használni amiatt is hibás, mert
más módszerekkel sokkal kisebb memóriaigénnyel elkészíthető ugyanaz az eredmény. Éppen ezért jobb, ha minél előbb
elfogadjuk, hogy táblázatokat csak akkor alkalmazunk, ha eredeti funkciójuk miatt, tehát az adatok közötti kapcsolat
szemléltetése miatt van rá szükségünk.
Egy táblázat gyakorlatilag vízszintes sorok és függőleges oszlopok találkozásánál kialakuló cellákból áll. Egy táblázat
logikailag felosztható ez alapján sorokra, oszlopokra, a sorok illetve oszlopok csoportba rendezhetőek. Minden táblázat-
hoz címsor is rendelhető. Így kialakul a táblázat részeinek az alábbi hierarchiája :
1. Táblázat ;
2. Címsor
3. Fejléc, lábléc, táblázattartalom (sorcsoportok)

4. Oszlopcsoportok
5. Sorok, oszlopok
6. Cellák : fejléc- és adatcella
Ebben a fejezetben a táblázat előállításához alkalmazható elemekről, és a táblázat megjelenését befolyásoló tulajdon-
ságokról lesz szó.
Az alábbi kódrészlet egy táblázatot mutat (általában ennyire nem bonyolult) :
<TABLE border="1"
summary="This table gives some statistics about fruit
flies: average height and weight, and percentage
with red eyes (for both males and females).">
<CAPTION><EM>A test table with merged cells</EM></CAPTION>
<TR><TH rowspan="2"><TH colspan="2">Average
<TH rowspan="2">Red<BR>eyes
<TR><TH>height<TH>weight
<TR><TH>Males<TD>1.9<TD>0.003<TD>40%
<TR><TH>Females<TD>1.7<TD>0.002<TD>43%
</TABLE>

105
Ahogy a példán is látszik, a táblázatot mindig a TABLE elemmel hozzuk létre. A TABLE elem paraméterei közül
most szerepel a border, amelynek hatására a táblázat kerete láthatóvá válik ; valamint a summary, amely egy rövid
leírást tartalmaz a táblázat tartalmáról. A TABLE belsejében levő első elem a CAPTION, amely – ha szerepel – egy címet
rendel a táblázathoz. Ennek pontos megjelenése később a stíluslapon szabályozható : alul vagy felül jelenjen meg, milyen
igazítással a táblázathoz képest stb.
A táblázat egy sorát a TR (Table Row) elemmel lehet megadni. Ezen belül az egyes cellákat a TH és a TD elemek
adják meg.
A következő szakaszban azokat az elemeket ismerjük meg, amelyek a táblázat létrehozásához szükségesek. Az ezt
követő szakaszokban a táblázat formázásáról, megjelenéséről ejtünk szót.

10.1. A táblázat létrehozásához szükséges elemek


10.1.1. A táblázat létrehozása: a TABLE elem
A táblázatot a TABLE elemmel hozzuk létre. A táblázat tartalmát ennek az elemnek a belsejébe kell írni.

86. A TABLE elem

<!ELEMENT TABLE - -
(CAPTION?, (COL*|COLGROUP*), THEAD?, TFOOT?, TBODY+)>
<!ATTLIST TABLE -- table element --
%attrs; -- %coreattrs, %i18n, %events --
summary %Text; #IMPLIED -- purpose/structure for speech output--
width %Length; #IMPLIED -- table width --
border %Pixels; #IMPLIED -- controls frame width around table --
frame %TFrame; #IMPLIED -- which parts of frame to render --
rules %TRules; #IMPLIED -- rulings between rows and cols --
cellspacing %Length; #IMPLIED -- spacing between cells --
cellpadding %Length; #IMPLIED -- spacing within cells --
>

A TABLE elem egy táblázatot hoz létre. Az elem lehetséges paraméterei – a „szokásos” paraméterek mellett :
• summary: Ez a paraméter arra szolgál, hogy a táblázat rövid összefoglalóját megadhassuk. Ez például a webol-
dal felolvasásakor lehet hasznos.
• width: A táblázat kívánt szélességét adja meg. Amennyiben százalékban van megadva, úgy a böngészőablak
szélességében értendő. Amennyiben nincs megadva, akkor a böngésző dönti el a táblázat méretét, elsősorban a
táblázat tartalma által igényelt szélesség alapján.
• border, frame, rules: A táblázat keretezését befolyásoló paraméterek (lásd később).
A táblázat minden egyes részét létrehozó elemet a TABLE elem belsejében kell elhelyezni.

106
10.1.2. Táblázat címének megadása
Táblázat címét megadni a CAPTION elemmel lehet. Akár a táblázat alatt, akár a táblázat fölött szeretnénk megjeleníteni,
mindenképpen a TABLE elem nyitótagja után közvetlenül kell megadni ezt az elemet. A megjelenés helyét azután majd
külön – a stíluslapon – lehet meghatározni.

87. A CAPTION elem : táblázat címe

<!ELEMENT CAPTION - - (%inline;)* -- table caption -->


<!ATTLIST CAPTION
%attrs; -- %coreattrs, %i18n, %events --
>

A CAPTION elem adja meg a táblázat címét. Kizárólag a TABLE elem nyitótagja után közvetlenül megadva használ-
ható.

10.1.3. Sorok csoportosítása, fejléc és lábléc a táblázatban


A táblázat sorait csoportokba lehet rendezni. Lehet fejlécet és láblécet definiálni, amely sorok egy-egy csoportja, ami
a táblázat alján és tetején úgy helyezkedik el, hogy mindig látható maradjon. Képernyőn történő megjelenítés esetén a
táblázat törzsét alkotó sorokat a fejléc és a lábléc között lehet görgetni, míg nyomtatásban ha a táblázat több oldalra esik,
a fejléc és a lábléc minden oldalon megismétlődik.
Sajnos a fenti viselkedés csupán egy elvárt viselkedés, azonban a böngészők egy jelentős része az ezt megvalósító
THEAD, TFOOT és TBODY elemeket egyszerűen figyelmen kívül hagyja. Ez azért probléma, mert így az egyébként
alulra szánt sorok (a lábléc sorai) a táblázat törzsét képező sorok előtt jelennek meg. Szerencsére a Mozilla legújabb
változata már megfelelően jeleníti meg ezeket a csoportokat.
Megadásuk mindig a THEAD, TFOOT, TBODY sorrendben történik, ahol az elemek rendre a fejlécet, a láblécet,
végül a törzset jelentik. A TBODY elem akár többször is szerepelhet, különálló csoportokba rendezve ezzel a törzsrész
sorait is. Ez segíthet a böngészőnek a táblázat nyomtatásánál egyoldalon tartani az összetartozó sorokat.
A következő HTML részlet mutatja a sorcsoportok használatát :

<TABLE>
<THEAD>
<TR> ...fejléc információ...
</THEAD>
<TFOOT>
<TR> ...lábléc információ...
</TFOOT>
<TBODY>
<TR> ...az első adatblokk első sora...
<TR> ...az első adatblokk második sora...
</TBODY>
<TBODY>
<TR> ...a második adatblokk első sora...
<TR> ...a második adatblokk második sora...
<TR> ...a második adatblokk harmadik sora...
</TBODY>

107
</TABLE>

10.1.4. Oszlopok csoportosítása és előzetes formázása


A cellákat az oszlopuk alapján is csoportosíthatjuk. Ez akkor lehet jó, ha valamely oszlopnak egyedi, de az oszlop minden
cellájára érvényes megjelenést akarunk adni. Erre szolgál a COL elem, illetve a több oszlopot egy csoportba rendelő
COLGROUP elem – amelyek szintén a legújabb böngészőkben váltak elérhetővé, mint az 1.7-es verziójú vagy újabb
Mozilla.
A COLGROUP elem egyik leghasznosabb tulajdonsága, hogy sok oszlopra lehet egyszerre azonos tulajdonságokat
beállítani. Például ha a táblázat negyven, egyenként 20 képpont széles oszlopot tartalmaz, akkor ahelyett, hogy negyven-
szer adnánk meg az egyes oszlopokra a szélességet (a COL nélkül ezt ráadásul soronként kellene megtenni), megtehetjük
egyszerre :
<COLGROUP span="40" width="20">
</COLGROUP>

Amennyiben ebből a negyven oszlopból az utolsót még más formázással is el kell látni, akkor így módosulhat a kód :
<COLGROUP width="20">
<COL span="39">
<COL id="specformat">
</COLGROUP>
Ekkor a negyven oszlop szélessége továbbra is megmarad 20 képpontos egyenként, de az utolsó oszlophoz megadható a
többitől eltérő formázás a stíluslapon a COL#specformat szelektorral megadott szabáyban.

108
88. A THEAD, a TFOOT és a TBODY elem

<!ELEMENT THEAD - O (TR)+ -- table header -->


<!ELEMENT TFOOT - O (TR)+ -- table footer -->

A THEAD és TFOOT elemek használata nem kötelező, de használatuk esetén a nyitótagot mindenképpen meg kell
adni, a zárótag elhagyható: a következő csoportosító elem nyitótagja jelzi az elem végét.

<!ELEMENT TBODY O O (TR)+ -- table body -->

A TBODY elem nyitótagja is elhagyható, amenyiben sem THEAD, sem TFOOT elem nem szerepelt. Amennyiben nem
adjuk meg a nyitótagját, akkor a TABLE elem egész tartalma egyetlen TBODY elemként lesz kezelve, amely a TABLE
elem zárótagjánál ér véget.
A három elem paraméterei:
<!ATTLIST (THEAD|TBODY|TFOOT) -- table section --
%attrs; -- %coreattrs, %i18n, %events --
%cellhalign; -- horizontal alignment in cells --
%cellvalign; -- vertical alignment in cells --
>

Mint látható, a „szokásos” paramétereken felül még két paramétere lehet ezeknek az elemeknek : cellhalign és
cellvalign. Ezek a csoporton belül a cellák függőleges és vízszintes igazításának alapértelmezését adják meg
(célszerűbb erre is a stíluslapot használni).
A táblázat fejléce és lábléce használandó arra, hogy az egyes oszlopokról információt adjunk meg a böngészőnek
(erre a COL és COLGROUP elemek használhatóak), valamint a fejlécként és láblécként megjelenő sorok tartalmának
megadására. A TBODY elem a táblázat tényleges tartalmának megadására szolgál.
Amennyiben megadjuk, először a THEAD, utána a TFOOT elemnek kell szerepelnie, és ezt követi egy vagy több
TBODY elem. Amennyiben szerepel, mindegyik elem egy-egy sorcsoportot hoz létre. Minden sorcsoportnak legalább
egy sort (TR elem) tartalmaznia kell.
A különböző sorcsoportoknak azonos számú oszlopot kell tartalmazniuk !

109
89. A COLGROUP elem

<!ELEMENT COLGROUP - O (COL)* -- table column group -->


<!ATTLIST COLGROUP
%attrs; -- %coreattrs, %i18n, %events --
span NUMBER 1 -- default number of columns in group --
width %MultiLength; #IMPLIED -- default width for enclosed COLs --
%cellhalign; -- horizontal alignment in cells --
%cellvalign; -- vertical alignment in cells --
>

A COLGROUP elem egy oszlopcsoportot hoz létre. Amennyiben nem szerepel ez az elem, akkor a táblázat minden
oszlopa egyetlen csoportot alkot. Az elem paraméterei a következők :
• span (alapértelmezett értéke 1): Egy nullánál nagyobb egész értékkel kell rendelkeznie, amely azt határozza
meg, hogy a csoportba hány oszlop tartozik. Amennyiben a COLGROUP elem tartalmaz legalább egy COL
elemet, a paraméter értéke lényegtelenné válik.
• width: Az oszlopcsoport valamennyi oszlopának egy alapértelmezett szélességet ad meg. Az ilyenkor szokásos
szélességmegadási módokon (hosszérték, százalék, pixelszám) felül használható még a "0*" forma is, amely
azt jelenti, a csoport minden oszlopa a tartalma megjelenítéséhez szükséges legkisebb szélességet vegye fel.
(Vigyázat: ennek következtében a táblázat csak a teljes tartalom ismeretében jeleníthető meg !) Ezt a paramétert
egyébként a csoport COL elemeinek vagy magának a cellának a szélessége felülbírálhatja.

90. A COL elem

<!ELEMENT COL - O EMPTY -- table column -->


<!ATTLIST COL -- column groups and properties --
%attrs; -- %coreattrs, %i18n, %events --
span NUMBER 1 -- COL attributes affect N columns --
width %MultiLength; #IMPLIED -- column width specification --
%cellhalign; -- horizontal alignment in cells --
%cellvalign; -- vertical alignment in cells --
>

A COL elem egy vagy több oszlop tulajdonságainak beállítására szolgál. Szerepelhet egy oszlopcsoportot megadó
COLGROUP elemben, vagy önállóan is. Csak nyitótagja van. Paraméterei a következők – a „szokásos” paraméterek
mellett:
• span: megadja, hogy hány oszlopra vonatkozik az elem által megadott formázás. Alapértéke 1.
• width: megadja, hogy mennyi legyen az oszlop(ok) szélessége, amely(ek)re az elem vonatkozik.

110
10.1.5. A táblázat sorai: a TR elem
A táblázat celláit sorról sorra haladva kell megadni. Ez azt jelenti, hogy először a TR (table row) elemmel meg kell adni
egy sort, benne felsorolva az adott sorba tartozó elemeket.

91. A TR elem

<!ELEMENT TR - O (TH|TD)+ -- table row -->


<!ATTLIST TR -- table row --
%attrs; -- %coreattrs, %i18n, %events --
%cellhalign; -- horizontal alignment in cells --
%cellvalign; -- vertical alignment in cells --
>

A TR elem a táblázat egy sorát definiálja. A sorba tartozó cellákat a TR elem tartalmaként kell megadni a TD és a
TH elemek segítségével. Bár zárótagja nem kötelező (a következő TR elem nyitótagja vagy a sorcsoportot illetve a
táblázatot lezáró elem egyben lezárja az elemet is), mégis célszerű megadni, mivel egyes böngészők hibásan kezelik
azokat a táblázatokat, amelyeknél nincs lezárva a sor. A Netscape régebbi verziói például a táblázat cellájába beágyazott
táblázat esetén a hiányzó zárótaggal rendelkező sorokat egyetlen sorba egyesítve jelenítették meg.

10.1.6. A táblázat cellái: a TH és a TD elem


A táblázat egy során belül a cellák kétfélék lehetnek : Fejléc információt tartalmazó TH (table header-cell) és adatot
tartalmazó TD (table data-cell).

92. A táblázat celláit létrehozó TH és TD elemek

<!ELEMENT (TH|TD) - O (%flow;)* -- table header cell, table data cell-->


<!-- Scope is simpler than headers attribute for common tables -->
<!ENTITY % Scope "(row|col|rowgroup|colgroup)">
<!-- TH is for headers, TD for data, but for cells acting as both use TD -->
<!ATTLIST (TH|TD) -- header or data cell --
%attrs; -- %coreattrs, %i18n, %events --
abbr %Text; #IMPLIED -- abbreviation for header cell --
axis CDATA #IMPLIED -- comma-separated list of related headers--
headers IDREFS #IMPLIED -- list of id’s for header cells --
scope %Scope; #IMPLIED -- scope covered by header cells --
rowspan NUMBER 1 -- number of rows spanned by cell --
colspan NUMBER 1 -- number of cols spanned by cell --
%cellhalign; -- horizontal alignment in cells --
%cellvalign; -- vertical alignment in cells --
>

111
93. A táblázat celláit létrehozó TH és TD elemek (folytatás. . . )

A TH elem fejléc információkat tartalmazó cellák, a TD adatot tartalmazó cellák létrehozására használatos. A TH
tartalmának alapértelmezett formázása középre zárt, félkövér szöveg. Ezzel szemben a TD tartalma balra zárt, normál
szövegként jelenik meg.
A két elem paraméterei – a „szokásos” paramétereken felül – a következők :
• headers: Amennyiben nem vizuálisan jelenik meg a táblázat, hanem például felolvasására kerül sor, akkor
hasznos tudni, hogy az adott cellához melyik fejléc-cella, vagy mely fejléc-cellák tartoznak. Ezeket lehet meg-
adni a headers paraméterrel, ahol fel kell sorolni egy szóközzel elválasztott listában a szóban forgó cellák
azonosítóit (id paraméter. . . )
• scope: az előző megfordításaként, megadható a fejléc-cellához is, hogy mely adatcellák tartoznak hozzá. Akár
a headers, akár a scope paramétert használjuk, azzal a beszédszintetizátoros feldolgozást segítjük. A scope
esetében azonban nem azonosítókat kell megadni, hanem :
– row esetén az adott sorban levő cellákra vonatkozik a fejléc;
– col esetén az adott oszlopra;
– rowgroup esetén az egész sorcsoportra, amelybe tartozik ;
– colgroup esetén az egész oszlopcsoportra.
• abbr: Ez a paraméter arra használható, hogy megadjunk egy rövidítést a cella tartalmára, amely akkor jelenik
meg a tényleges tartalom helyett, ha nincs hely annak megjelenítésére.

• axis: Egy n-dimenziós kategória-térbe lehet elhelyezni a cellákat ezzel a paraméterrel. Ez arra jó, hogy ka-
tegóriákat hozzunk létre a cellák számára, lehetővé téve – az erre alkalmas böngészőben – a felhasználóknak
a választást a megjelenített kategóriák közül. A paraméter értéke egy vesszővel elválasztott lista, melyben fel
vannak sorolva a kategóriák, amelybe a cella tartozik. (A kategórizálásról többet a [1]-ben lehet találni. . . )
• rowspan (alapértéke 1): Ez a paraméter meghatározza, hogy a cella a megadási helyétől kezdve hány sor-
ban található. Tulajdonképpen ezzel lehet az egymás alatti cellákat összevonni egy cellává. A 0 érték jelentése
speciális : a cella az aktuális sortól egészen az adott sorcsoport utolsó soráig tart.
• colspan (alapértéke 1): Ez a paraméter meghatározza, hogy a cella a megadási helyétől kezdve hány oszlopban
található. Tulajdonképpen ezzel lehet az egymás melletti cellákat összevonni egy cellává. A 0 értéknek itt is
speciális jelentése van: a cella az aktuális oszloptól egészen az adott oszlopcsoport utolsó oszlopáig tart a sorban.
• align, char, charoff, valign: a cella igazítását befolyásoló paraméterek, amelyek kiválthatóak a megfe-
lelő tulajdonságokkal is (ezekről a formázásnál lesz szó).

Egy cella lehet üres is, amely esetben a megjelenése több beállítástól is függ. . .

Több cella egyesítése


Nagyon sok esetben előfordul, hogy a táblázat valamely celláit szeretnénk egyesíteni egymással. Ez a HTML-ben inkább
azt jelenti, hogy egy cellát kiterjesztünk valahány vele szomszédos cella területére is.1 Ez a kiterjesztés azonban több
következménnyel is járhat.
1 Igazából más esetben is ezt jelenti, csak nem így szoktuk emlegetni. Gondoljunk csak arra, hogy egy táblázatkezelő programban a cellaegyesítés

eredményeként a kialakuló cella tartalma és azonosítója is az eredeti cellák közül a bal-felső celláéval fog megegyezni.

112
Egy cella kiterjeszthető az alatta levő sorok egy részébe a rowspan paraméter értékének megadásával. A mellette
levő oszlopokba a cella a colspan paraméter értékének megadásával terjeszthető ki. Természetesen mindkét irányú
kiterjesztés megadható akár együtt is, ezzel olyan cellát eredményezve, amely több sorra és oszlopra terjed ki.

<TABLE border="1">
<CAPTION>Cups of coffee consumed by each senator</CAPTION>
<TR><TH>Name<TH>Cups<TH>Type of Coffee<TH>Sugar?
<TR><TD>T. Sexton<TD>10<TD>Espresso<TD>No
<TR><TD>J. Dinnen<TD>5<TD>Decaf<TD>Yes
<TR><TD>A. Soria<TD colspan="3"><em>Not available</em>
</TABLE>

A fenti példa a [1]-ből származik. Ebben az utolsó sor egyik cellája van a sorban mellette levő cellák helyére kiter-
jesztve. A fenti példa valami ilyesmi kinézetű táblázatot fog eredményezni :
Name Cups Type of Coffee Sugar ?
T. Sexton 10 Espresso No
J. Dinnen 5 Decaf Yes
A. Soria Not available
A cellakiterjesztés kapcsán azonban felmerül a kérdés, hogy mi történik azzal a cellával, amelynek a helyét elfoglalja
egy kiterjesztett cella. A válasz: a sorban jobbra tolódik a következő szabad helyre. Ez azt jelenti, hogy amikor a táblázatot
létrehozzuk, akkor figyelni kell arra, hogy a kiterjesztéssel elfoglalt cellákhoz tartozó TH vagy TD elemet ne adjuk meg.
Az alábbi példa mutatja, hogy hogyan is kell a cellakiterjesztés során a többi cellát kezelni. Először megmutatjuk a
táblázatot, azután az ezt létrehozó HTML kódot:

<TABLE border=1>
<TR>
<TH>A</TH><TH colspan=2>B</TH><TH>C</TH>
</TR>
<TR>
<TH rowspan=2>D</TH><TH>E</TH><TH colspan=2 rowspan=2>F</TH>
</TR>

113
<TR>
<TH>G</TH>
</TR>
<TR>
<TH>H</TH><TH>I</TH><TH>J</TH><TH>K</TH>
</TR>
</TABLE>

A fenti példát illusztráló képen természetesen a cellák magassága és szélessége egységesre volt állítva, hogy jobban
látszódjon, melyik cella hová tartozik. Érdemes összehasonlítani a HTML kódot a belőle előállt táblázattal.
Végül felmerülhet még egy kérdés: mi a helyzet akkor, ha két cellát ugyanarra a helyre terjesztek ki, azaz ha két cella-
kiterjesztés eredményeként a cellák között átfedés jönne létre. Nos, az ilyen megoldások hibás HTML kódnak számítanak,
így ezek kezelése a böngészőtől függ. Íme egy példa az ilyen szabálytalan HTML kódra :

<TABLE border="1">
<TR><TD>1 <TD>2 <TD>3
<TR><TD>4 <TD rowspan="2">5 <TD>6
<TR><TD colspan="2">7 <TD>9
</TABLE>

Ennek eredményeként az „5” és „7” celláknak át kellene fedniük egymást, de ez nem lehetséges. Mindenki kipró-
bálhatja a saját böngészőjében az eredményt, vagy akár több böngészőben is kipróbálhatja, hogy kiderüljön : mennyiben
térnek el a szabálytalan kód kezelésében. . .

10.2. A táblázatok megjelenésének szabályozása


A táblázat a HTML-ben blokk-szintű objektumként jelenik meg.2 A táblázatnak van tartalma, belső és külső margója,
valamint kerete is.
A TABLE elem létrehoz egy névtelen dobozt, amely tartalmazza magát a táblázatot és a táblázat esetleges címkéjét (a
CAPTION elem tartalma számára) tartalmazó dobozokat. Mind a táblázat, mind a címke doboza blokk-szintű dobozként
viselkedik, és rendelkezik saját tartalom, margó és keret részekkel. Az e két dobozt magában foglaló névtelen doboz a
lehető legkisebb méretű, amelyben a két doboz teljesen elfér. A vízszintes margók egybeolvadnak a táblázat és a címke
dobozának találkozásánál. A táblázat minden pozícionálása, áthelyezése az egész tartalmazó dobozt mozgatja, tehát a
címke is vele együtt mozdul ilyen esetben.

10.2.1. A táblázat címének pozícionálása


Azt, hogy a táblázat dobozához képest a névtelen dobozon belül a cím doboza hogyan helyezkedjen el, a caption-side
tulajdonság határozza meg.
A táblázatcím tartalmának vízszintes igazítására a text-align (40. szabály) tulajdonságot lehet használni. A táblázat
mellé helyezett címnél hasznos lehet a függőleges igazítás megadása is, amelyre a vertical-align tulajdonság használható
(lásd 53. oldalon a 38. szabályt). Ez utóbbinál kizárólag a top, bottom és middle értékek értelmesek ebben az esetben.
A többi érték esetén felülre igazítja a böngésző a címet.
2 A CSS2 ismeri a sor-szintű táblázat fogalmát is, azonban a HTML nyelv TABLE elemét alapvetően blokk-szintű elemként illik a böngészőknek

kezelni. Azonban elképzelhető, hogy mégis egy sorban próbálja meg a böngésző elhelyezni a táblázatot, ha nem vigyázunk. Az XML-ben lehet definiálni
olyan elemet, amely blokk-szintű, és olyat is, amely szöveg-szintű táblázatot hoz létre, ezért van értelme a CSS-ben a szöveg szintű táblázatnak is. Mivel
azonban mi elsősorban a HTML nyelvnél maradunk, ezért most nyugodtan elfogadhatjuk, hogy a TABLE blokk-szintű objektumot hoz létre.

114
94. A caption-side tulajdonság

A caption-side tulajdonság meghatározza a táblázatcím dobozának helyzetét a táblázat dobozához képest. Lehetséges
értékei a következők:
• top (alapértelmezés): A cím a táblázat fölött jelenik meg.
• bottom: A cím a táblázat alatt jelenik meg.
• left: A cím a táblázattól balra jelenik meg.
• right: A cím a táblázattól jobbra jelenik meg.

Amennyiben a címet a táblázat mellé kell tenni, akkor ajánlott a cím szélességét a width tulajdonsággal pontos értékre
beállítani, különben nagyon böngészőfüggővé válhat a megjelenítés !

10.2.2. A táblázat belső elemei


A táblázat belső elemei – sorok, oszlopok és cellák – szintén téglalap alakú dobozokat hoznak létre. Ezeknek is van
tartalmuk, belső margójuk és keretük, azonban nincs külső margójuk. Emiatt ha a cellák között valamekkora hézagot
szeretnénk kialakítani, arra más módszert kell alkalmazni (lásd kicsit később). A cellák dobozai közvetlenül egymás
mellé kerülnek egy kétdimenziós tömb formáját felvéve.

A háttér beállítására vonatkozó szabályok


A táblázat egyes részeinek háttere a különböző elemekre megadott háttérbeállításokkal elég bonyolultan szabályozható.
Magának a táblázatnak a hátterét a TABLE elemnél kell beállítani, azonban minden oszlopcsoportnak, sorcsoportnak,
oszlopnak, sornak, cellának külön beállítható a háttere. Ezek után nem mindegy, hogy az egyes beállított hátterek milyen
sorrendben kerülnek alkalmazásra.
Ennek megoldására a CSS2 bevezeti a táblázat elemeire a rétegezést, amelyben minden elemnek definiált rétege van.
Ez a réteg egy részben átlátszó fóliaként képzelhető el : az előrébb levő fólia kitakarja az alatta levőn levő tartalmat,
azonban azon a helyen, ahol átlátszik, megjelenik az alatt levő fólia tartalma. A 10.1. ábrán a [2] ábrája mutatja az egyes
elemekhez tartozó rétegek elhelyezkedését. Mint az ábrán is látható, legalul a TABLE elem található, tehát ez adja meg
az alap háttért, legfölül pedig maga a cella. Amennyiben valamelyik szinten az elemnek nincs háttere beállítva, akkor
a háttér átlátszó, tehát a nála nagyobb egységekre beállított háttér fog megjelenni. Ugyancsak átlátszóak a teljesen üres
cellák.

115
10.1. ábra. A táblázat egyes elemeinek rétegekben való elhelyezkedése

A táblázat szélességének meghatározásának befolyásolása


A böngészők a táblázat szélességének meghatározására kétféle módszert alkalmazhatnak. Az, hogy ezek közül melyik az
alapértelmezett módszer, az adott böngészőre jellemző tulajdonság. Amennyiben szeretnénk pontosan előírni a böngésző-
nek, hogy melyik módszert használja, a table-layout tulajdonságot kell használnunk.3

95. A table-layout tulajdonság

A table-layout tulajdonsággal ki lehet kényszeríteni, hogy a böngésző a táblázat szélességét meghatározó eljárások
közül melyiket alkalmazza. Értékei lehetnek:
• auto: automatikus szélességbeállítás (igazából a böngészőtől függ). Ebben az esetben a szélességek meghatá-
rozásához ismerni kell a táblázat teljes tartalmát (a régi Netscape ilyenkor szokott elszállni memóriahiány miatt).
• fixed: a „fixed layout algorithm” nevű eljárást kell alkalmazni (lásd [2].) Ebben az esetben a táblázat széles-
ségének meghatározása nem függ a táblázat tartalmától, ami megkönnyíti a táblázat megjelenítését még a teljes
tartalmának letöltése előtt. Ekkor a táblázat és oszlopai szélességét pontosan meg kell adni.

A cella tartalmának igazítása


A cella tartalmát a korábban már ismertetett vertical-align tulajdonsággal (lásd a 53. oldal) lehet függőlegesen igazítani.
Azonban a tulajdonság értékei ezúttal más jelentéssel rendelkeznek.
A cella tartalmának vízszintes igazítására szintén a már ismert text-align (54. oldal) tulajdonság vonatkozik, azonban
ezúttal is más az értékek jelentése.
3A táblázat szélességének meghatározására alkalmazott módszerekről a [2] nyújt részletesebb információt, itt csupán a tulajdonságot említjük meg.

116
96. A vertical-align tulajdonság értékei táblázat cellájában

• baseline: A cella tartalma az első a cellához tartozó sor (ha a több sorba ér a cella) alapvonalához van igazítva.
• top: A cella tartalma a hozzá tartozó első sor tetejéhez van igazítva.
• bottom: A cella tartalma a hozzá tartozó utolsó sor aljához van igazítva.

• middle (alapértelmezés) : A cella tartalma középre van igazítva (függőlegesen).


• sub, super, text-top, text-bottom: Ezek az értékek a táblázat celláira nem használhatóak. Helyettük a
baseline kerül ilyenkor alkalmazásra.
A cella alapvonala a cella első szövegsorának alapvonalával egyezik meg. Amennyiben a cella üres, az alapvonala
megegyezik az aljával.

Amennyiben egy oszlop több cellájára van a szöveg érték beállítva, a cellákban a megadott szövegrész egy függőleges
vonal mentén helyezkedik el. Azaz ezzel a lehetőséggel lehet például a mértékegységekhez vagy a tizedesjelhez igazítani
a cellákba írt mennyiségeket. Ez a fajta igazítás csak egysoros cellatartalomnál egyértelmű, a többsoros cellatartalmaknál
nem egyértelmű, hogy a böngésző hogyan fogja kezelni ezt a fajta igazítást. Amennyiben a megadott szöveg nem szerepel
a cella tartalmában, akkor a tartalom jobb (fordított írásiránynál a bal) vége kerül a kívánt pozícióra. A szövegnek az
egyes cellákban még egy oszlopon belül sem kell megegyeznie, így akár különböző mértékegységekkel is be lehet állítani
az igazítást.

97. A cellaelemek char paramétere

A TD és TH vagy a TR elemek esetén, ha az align paraméternek char értéket adunk – vagy ugyanezt a text-align
tulajdonsággal tesszük meg –, akkor a char paraméter tartalmazza azt a szöveget, amelynek a cella tartalmában való
megjelenését az igazításnál használni kell. A böngészők nem feltétlenül támogatják ezt a paramétert.

Amennyiben például dollárban megadott árakat szeretnénk a tizedesponthoz igazítani, arra használhatjuk a következő
szabályokat:
TD { text-align: "." }
TD:before { content: "$" }
Ekkor a $ jel megjelenik a cellatartalom előtt és a tartalom a tizedesponthoz igazodik a következő HTML kódban :
<TABLE>
<COL width="40">
<TR> <TH>Long distance calls
<TR> <TD> 1.30
<TR> <TD> 2.50
<TR> <TD> 10.80
<TR> <TD> 111.01
<TR> <TD> 85.
<TR> <TD> 90
<TR> <TD> .05

117
<TR> <TD> .06
</TABLE>
Ez valahogy így jelenhet meg:
Long distance calls
$1.30
$2.50
$10.80
$111.01
$85.
$90
$.05
$.06
Megjegyzés. A fenti példa változtatás nélkül lett átmásolva a [2] megfelelő fejezetéből. . .

10.3. A táblázat keretei


A táblázat keretezésére a CSS2 két egymástól eltérő modellt definiál. Az egyik modell minden cellának saját, a szomszé-
daitól különálló keretet hoz létre, míg a másik modell a szomszédos cellák között egyetlen keretet helyez el, gyakorlatilag
a táblázat egyik szélétől a másik széléig tartó folyamatos vonal formájában.

98. A border-collapse tulajdonság

A border-collapse tulajdonság értéke adja meg, hogy a két lehetséges táblázat keretezési modell közül melyiket kell
használni. Ebből következően ez a teljes táblázatot létrehozó (HTML-ben a TABLE) elem tulajdonsága.
Értékei a következők:
• collapse (alapértelmezés) : A táblázat szomszédos cellái között egyetlen keret jelenik meg, vagyis a szomszé-
dos keretek egyetlen keretté olvadnak össze.
• separate: Minden cellának saját, a többitől független kerete van.

A következőekben a két modellre vonatkozó beállítási lehetőségeket külön-külön ismertetjük.

10.3.1. A „separate” modell


Ebben az esetben tehát minden cellának saját kerete van. Ennek stílusa, színe és vastagsága a doboz modellnél megismert
border- ? tulajdonságokkal állítható be. A keret és a cella tartalma közötti távolság a padding tulajdonságoktól függ.
Azonban a két szomszédos cella kerete közötti részt nem a cella margója állítja – mivel a celláknak nincs margójuk –,
hanem a border-spacing tulajdonság.

118
99. A border-spacing tulajdonság

A border-spacing tulajdonság a két szomszédos cella kerete közötti távolságot adja meg a margókhoz hasonlóan.
Amennyiben egy távolság van megadva, akkor az mind a vízszintes, mind a függőleges oldali távolságokat meghatároz-
za. Amennyiben két távolság van megadva, az első a vízszintes, a második a függőleges oldali távolságokat határozza
meg. A hosszértékek nem lehetnek negatívak, százalékérték nem adható meg.
A keretek közötti távolságon a táblázat háttere látszik.

Ebben a modellben a soroknak, oszlopoknak illetve ezek csoportjainak nem lehetnek kereteik.
Az üres cellák keretének megjelenését, vagy meg nem jelenését lehet szabályozni a empty-cells tulajdonsággal.

100. Az empty-cells tulajdonság

Az empty-cells tulajdonság show (alapértelmezett) értéke hatására az üres cella is megjelenik a hozzá tartozó kerettel
együtt. Amennyiben a tulajdonság a másik értékét, a hide értéket kapja, a cella teljesen láthatatlan marad (a kerete
sem jelenik meg); helyén a táblázat háttere jelenik meg. Amennyiben egy sor valamennyi cellája üres, és hide érték-
kel rendelkezik, az azzal azonos hatást eredményez, mintha a sor TR elemének display tulajdonsága none értékkel
rendelkezne, azaz teljesen hiányozni fog a weboldalról.

10.3.2. A „collapse” modell


Ebben a modellben a szomszédos cellák között legfeljebb egy keret jelenik meg. Akkor nem jelenik meg ez a keret, ha
mindkét cella esetén az van az adott oldalhoz beállítva, hogy ne jelenjen meg keret. Minden más esetben lesz valamilyen
keret. Ebben a modellben lehetséges az oszlop- illetve sorcsoportok köré is keretet húzni.
A TABLE elem rendelkezik egy frame és egy rule paraméterrel, amelyek a keretek megjelenését befolyásolják.

101. A frame paraméter

A frame paraméter a táblázat külső kereteinek megjelenését szabályozza. Értékei :

• void: Nincs keret egyik oldalon sem (alapértelmezés).


• above: Csak fölül legyen keret.
• below: Csak alul legyen keret.
• hsides: Alul és felül legyen keret.
• vsides: Balról és jobbról legyen keret.
• lhs: Csak baloldalt legyen keret.
• rhs: Csak jobboldalt legyen keret.

• box, border: Mind a négy oldalon legyen keret.

119
102. A rules paraméter

A rules paraméter a táblázat belső kereteinek, azaz a cellák közötti szegélyezésnek a megjelenését szabályozza.
Értékei:
• none: Sehol nincs belső szegély a cellák között.
• groups: A sor- illetve oszlopcsoportok határán jelenik meg keret, máshol nem.
• rows: A sorok között megjelenik keret, míg az oszlopok között nem.
• cols: Az oszlopok között megjelenik keret, míg a sorok között nem.
• all: A keretek mindenhol megjelennek.

103. A border paraméter

A border paraméter értéke a táblázatot körülvevő keret vastagságát határozza meg. Hatásával megegyezik a TABLE
elemre beállított border-width tulajdonság (amellyel ráadásul az egyes oldalakon más-más érték is beállítható). A para-
méter értéke mindenképpen képpontban (pixel) értendő, míg a border-width- ? tulajdonságoknál más mértékegységben
is megadható. Ajánlatosabb a tulajdonságokat használni helyette.

Ebben a modellben a táblázatnak nincs belső margója (de van margója). A keretek és a cellák belső margóinak elhe-
lyezkedését (ez utóbbi határozza meg a cellatartalom és a keret távolságát) mutatja a 10.2. ábra.

10.2. ábra. A cellák és keretük távolságai az őket szabályozó tulajdonságokkal a collapsing modell esetén

A két szomszédos cella tehát közös kerettel rendelkezik. Ez problémás lehet, amikor a két cellánál az adott keretre

120
nem ugyanazt a formázást állítunk be (például mert két más-más csoportba sorolt cella kerül egymás mellé, amely cso-
portokban más keret van meghatározva). Ekkor a keret tényleges megjelenését a következő szabályok határozzák meg:

1. Bármely elem a border-style tulajdonsághoz az adott keretre hidden értékkel rendelkezik : a keret nem jelenik
meg. (Ez az eset minden más esetnél erősebb prioritású.)
2. Bármely elem esetén a border-style tulajdonság none értéke a legkisebb prioritású : az adott keret csak akkor nem
jelenik meg, ha minden elem esetén erre az értékre van a keret állítva (kivéve, ha az előző pont teljesül).
3. Amennyiben egyetlen érintett elemnél sincs hidden érték beállítva, és legalább az egyik érintett elemnél a none
értéktől eltérő érték van beállítva, a keskenyebb keretet felülírja a vastagabb keret. Az azonos szélességű keretek
közül (lásd border-width) a stílus (border-style) dönt : a legmagasabbtól a legkisebb prioritásig a double, solid,
dashed, dotted, ridge, outset, groove, inset a sorrend.

4. Amennyiben a stílus megegyezik, de a szín eltér, a nyertes az elem szintjétől függ : a cella felülírja a sort, a sor
felülírja a sorcsoportot, a sorcsoport felülírja az oszlopot, az oszlop az oszlopcsoportot, az oszlopcsoport pedig a
táblázatot.

Lássuk erre a [2] példáját:


TABLE { border-collapse: collapse;
border: 5px solid yellow; }
*#col1 { border: 3px solid black; }
TD { border: 1px solid red; padding: 1em; }
TD.solid-blue { border: 5px dashed blue; }
TD.solid-green { border: 5px solid green; }
A fenti stíluslapot alkalmazzuk az alábbi HTML kódra :
<P>
<TABLE>
<COL id="col1"><COL id="col2"><COL id="col3">
<TR id="row1">
<TD> 1
<TD> 2
<TD> 3
</TR>
<TR id="row2">
<TD> 4
<TD class="solid-blue"> 5
<TD class="solid-green"> 6
</TR>
<TR id="row3">
<TD> 7
<TD> 8
<TD> 9
</TR>
<TR id="row4">
<TD> 10
<TD> 11
<TD> 12
</TR>

121
<TR id="row5">
<TD> 13
<TD> 14
<TD> 15
</TR>
</TABLE>
Az eredmény valami olyasmi lehet – egy jól működő böngészőben, mint ami a 10.3. ábrán látható.

10.3. ábra. Találkozó cellakeretek kezelése eltérő formázás esetén

10.3.3. A keretek stílusával kapcsolatos megjegyzések


A border-style tulajdonság egyes értékei a táblázat celláinak keretezésénél kicsit másképpen viselkednek a megszokottnál.
Az egyik ilyen eset a hidden, amely a „collapsing” modellnél magasabb prioritású minden más értéknél, egyébként a
none értékkel megegyezik. A másik eset az inset, amely szintén a „collapsing” modellnél tér el a hagyományos
viselkedéstől : ekkor a ridge értékkel egyezik meg. Hasonlóan az outset ilyenkor a groove értékkel azonosnak
számít.

122
11. fejezet

Több weboldal megjelenítése egyszerre :


keretek alkalmazása

A keretek lehetővé teszik, hogy a többoldalas dokumentumnak különböző részei egyszerre megjelenjenek, és egymástól
függetlenül változzanak. Ez a gyakorlatban a böngészőablak felosztását jelenti több részre, amely mindegyike egy-egy
oldalt tud megjeleníteni. A keretek használata rendkívül memóriaigényes a böngésző számára, ráadásul nem minden
böngésző képes a kereteket kezelni, ezért használata csak valóban indokolt esetben javasolt.
Ilyen indokolt eset lehet például, ha olyan dokumentumot akarunk készíteni, amelynek tartalomjegyzéke vagy menüje
folyamatosan látható a böngésző ablakának bal szélén. Ugyanez egyes esetekben más módszerekkel (JavaScripttel kezelt
DIV objektumok, vagy PHP-vel minden oldalra legenerált menü) is megoldható lehet. Másik példa, ha egy dokumentum
olyan illusztrációkat is tartalmaz, amelyeket úgy szeretnénk elhelyezni, hogy a szöveg továbbolvasása esetén is láthatóak
maradjanak. Ekkor az illusztráció külön keretbe kerülhet, és így az oldal görgetése nem tünteti el.
Íme egy példa a keretet létrehozó dokumentumra :
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
"http://www.w3.org/TR/html4/frameset.dtd">
<HTML>
<HEAD>
<TITLE>Egy egyszerű keret-dokumentum</TITLE>
</HEAD>
<FRAMESET cols="20%, 80%">
<FRAMESET rows="100, 200">
<FRAME src="contents_of_frame1.html">
<FRAME src="contents_of_frame2.gif">
</FRAMESET>
<FRAME src="contents_of_frame3.html">
<NOFRAMES>
<P>Ez a kereteket használó dokumentum a következőket tartalmazza:
<UL>
<LI><A href="contents_of_frame1.html">Valami tartalom</A>
<LI><IMG src="contents_of_frame2.gif" alt="Egy kép">
<LI><A href="contents_of_frame3.html">További tartalom</A>
</UL>
</NOFRAMES>
</FRAMESET>

123
</HTML>
Mint látható a fenti példából is, a keretet definiáló tartalom magának a keretnek a tartalmát nem adja meg, csupán azt
a másik dokumentumot határozza meg, amelyet az adott keretbe betöltve meg kell jeleníteni. Így a kereteket tartalma-
zó dokumentumok még több állományból állnak, amely esetben az egységes kinézet érdekében még fontosabb a külső
stíluslap használata a formázás megadására. . .
A fenti példában szereplő keret-dokumentum egyébként létrehoz egy baloldali sávot, amely a teljes szélesség 20
százalékát kapja, és ebben 1:2 arányban elhelyez két weboldalt (pontosabban az alsó keretben egy képet). A jobboldali,
nagyobb – egészen pontosan a rendelkezésre álló teljes szélesség 80 százalékát felhasználó – keretben egy újabb weboldal
jelenik meg.
A NOFRAMES részben levő tartalom nem jelenik meg, kivéve, ha a böngésző a keretek megjelenítésére bármely
okból képtelen, ekkor ugyanis az itt elhelyezett tartalom fog megjelenni. Egy böngésző akkor nem képes a keretek megje-
lenítésére például, ha – mint a lynx vagy egy beszédszintetizátoros megjelenítő, esetleg egy mobiltelefon – képtelen több
dokumentumot egyszerre megjeleníteni a megjelenítő eszköz képességei miatt (a lynx szöveges üzemmódban dolgozik,
amiben a kereteket nehéz lenne kezelni), vagy ha a keretek megjelenését letiltotta a felhasználó.
Mint a példakód első sorában látható, a kereteket alkalmazó dokumentumokban a frameset változatát kell a DTD-nek
használni, hiszen ez tartalmazza az ehhez szükséges elemeket és paramétereket.

11.1. Keretek definiálása


A fenti példában észrevehető még egy eltérés a hagyományos weboldalak kódjától. Eddig minden weboldal kódjában a
HTML elem tartalma először egy HEAD volt, majd ezt a weboldal tartalmát leíró BODY elem követte. Amikor viszont
kereteket definiáló weboldalt készítünk – nevezzük ezt a továbbiakban anyaoldalnak az egyszerűség kedvéért1 –, a BODY
elem hiányzik, hiszen az oldal nem rendelkezik tartalommal. Helyette a FRAMESET elem található, és ebben a végén
esetleg a NOFRAMES, amely a BODY-t helyettesíti arra az esetre, ha a böngésző nem tudja a kereteket megjeleníteni.
A FRAMESET elem definiálja a keretek elhelyezkedését a weboldal megjelenítésére rendelkezésre álló területen
belül. Ez a terület mindig az aktuális böngészőablak, tehát a keretek nem tölthetnek ki a látható területnél nagyobb helyet,
vagyis nem görgethető az anyaoldal. Görgethető lehet viszont az egyes keretekben megjelenő tartalom, ha szükséges.
Azok az elemek, amelyek a BODY elemben fordulhatnának elő, nem szerepelhetnek a FRAMESET elem előtt, mert
ha szerepelnek, akkor a FRAMESET elemet a böngésző teljes egészében figyelmen kívül hagyja. Amennyiben esetleg
egy weboldalba szeretnénk egy másik weboldalat keretszerűen beágyazni, arra a később ismertetésre kerülő IFRAME
elemet lehet majd használni. . .
A FRAMESET elem az egyes kereteket, az azokban megjelenítendő dokumentumrészt a FRAME elemek segítségével
definiálja.
1 Ennek az eredeti angol neve frameset document, ami magyarra elég nehezen fordítható. Az anyaoldal elnevezés semmilyen más, magyar nyelvű

szakkönyvben nem szerepelt – mostanáig. . .

124
104. A FRAMESET elem

<![ %HTML.Frameset; [
<!ELEMENT FRAMESET - - ((FRAMESET|FRAME)+ & NOFRAMES?) -- window subdivision-->
<!ATTLIST FRAMESET
%coreattrs; -- id, class, style, title --
rows %MultiLengths; #IMPLIED -- list of lengths,
default: 100% (1 row) --
cols %MultiLengths; #IMPLIED -- list of lengths,
default: 100% (1 col) --
onload %Script; #IMPLIED -- all the frames have been loaded --
onunload %Script; #IMPLIED -- all the frames have been removed --
>
]]>

A FRAMESET elem egy keretkészlet definiálására szolgál. Tartalma lehet újabb FRAMESET vagy az egyes kerete-
ket leíró FRAME elem, illetve legutolsó elemként szerepelhet a NOFRAMES elem, amely a keretek megjelenítésére
képtelen böngészők által megjelenítendő tartalmat adja meg.
Az elem paraméterei:
• rows: Ez a paraméter egy hosszérték-listát tartalmaz értékként. Ezzel a listával meghatározza egyrészt a sorok
számát (a listán levő hosszértékek száma), és az egyes sorok magasságát is (az egyes hosszértékekkel).
• cols: Ez is egy hosszérték-listát tartalmaz értékként. Ezzel a listával az oszlopok számát és szélességét lehet
megadni.
A rows és a cols paraméterekkel előállított táblázatszerű felosztás minden egyes cellája egy-egy keretet eredményez,
amelynek leírását fentről lefelé és balról jobbra haladva a FRAMESET-en belül egymás után felsorolt FRAME elemek
tartalmazzák.
A két paraméter hosszérték-listája egy vesszővel elválasztott lista, amely a következő hosszértékfajtákat tartalmazhatja :
számérték, amely képpontnak számít; százalék, amely a tartalmazó téglalap (a böngésző, vagy az egyel kintebb levő
FRAMESET által létrehozott keret) szélesség/magasság értékéhez relatív ; vagy egy speciális *-ot tartalmazó részekre
bontó érték. Mintkét paraméter alapértelmezése a 100%, vagyis a teljes sor/oszlop.

11.1.1. A sorokra és oszlopokra osztás


Ahogyan a 104. definíció is mutatja, a FRAMESET elem egy táblázatszerű felosztást hoz létre, amelynek sorai számát a
rows, az oszlopainak számát pedig a cols paraméter határozza meg.
Az egyes sorok magassága felülről lefelé haladva adható meg, az egyes oszlopok szélessége pedig balról jobbra
haladva.
A hosszértékek százalékban vagy pixelben adhatók meg. Ezek mellett létezik még egy speciális hosszérték, amelynek
a pontos mérete csak a többi hosszérték ismeretében határozható meg. Ez a speciális érték minden esetben egy számból
és utána egy * jelből áll. Ez azt jelenti, hogy a nem így megadott hosszértékek meghatározása után megmaradó helyet az
összes ilyen csillagos érték között arányosan kell felosztani.
Ez az arányos felosztás pedig a következőképpen történik :
1. Az egyes arányos hosszértékek (ezekben szerepel a *) előtt levő számot össze kell adni.
2. A rendelkezésre álló helyet annyi egyforma részre kell osztani, amennyi az összeadás eredményeként adódik.

125
3. Minden egyes arányos hosszérték az egyforma részekből annyit kap, amennyi a benne a csillag előtt szereplő szám.
Vagyis például a "1*, 2*, 3*" érték azt jelenti, hogy összesen 6 részre kell a rendelkezésre álló helyet felosztani,
és ebből az első egy, a második kettő, a harmadik három részt kap, vagyis 1 :2 :3 arányban osztoznak a rendelkezésre álló
helyen : az első kapja a hely 61 , a második a 26 = 13 , a harmadik a 36 = 12 részét.
Az alábbi példa a többféle hosszérték együttes használatát mutatja :
<FRAMESET cols="1*,250,3*">
...a definíció további része...
</FRAMESET>

A középső oszlop 250 képpont széles lesz, míg az ezután fennmaradó rész egy negyedét kapja az első oszlop, a háromne-
gyedét a harmadik oszlop.
Amennyiben csak abszolút hosszértékek szerepelnek, és nem töltik ki a rendelkezésre álló helyet, akkor a böngésző a
maradék helyet arányosan elosztja az egyes oszlopok/sorok között. Hasonlóan, ha kevés a hely, akkor arányosan csökkenti
a megadott hosszértékeket.
Megjegyzés. A FRAMESET elemek tetszőleges mélységben egymásba ágyazhatóak elméletileg. Gyakorlatilag azonban a
megjelenítéshez szükséges memória határt szabhat az egymásba ágyazásnak, így jobb csínján bánni a keretek egymásba
ágyazásával, ha nem akarjuk, hogy a dokumentunkat senki se nézze meg arra alkalmas böngésző hiányában !

11.1.2. Adatmegosztás a keretek között


Az egyes keretekben megjelenő dokumentumok egymás között adatokat oszthatnak meg az OBJECT elem segítségével.
Az erre a célra szolgáló OBJECT elemet a dokumentum HEAD elemén belül kell elhelyezni, amely így nem jelenik meg.
Ezen felül az id paraméterrel el kell nevezni az OBJECT-et. Ezután bármely másik dokumentum, amely éppen be van
töltve valamely keretbe, ezen az azonosítón keresztül hivatkozhat az objektumra, így minden abban definiált adatra is.

11.1.3. A keretek leírása: a FRAME elem


A FRAMESET elemen belül tehát az egyes definiált kereteket a FRAME elemmel kell leírni. Ez egyrészt meghatározza
a keret alapértelmezett tartalmát, amit az anyaoldal betöltésekor kell a keretbe betölteni ; valamint az azonosítót, amellyel
a későbbiekben hivatkozni lehet az adott keretre (például a tartalma lecserélése céljából).

126
105. A FRAME elem

<![ %HTML.Frameset; [
<!-- reserved frame names start with "_" otherwise starts with letter -->
<!ELEMENT FRAME - O EMPTY -- subwindow -->
<!ATTLIST FRAME
%coreattrs; -- id, class, style, title --
longdesc %URI; #IMPLIED -- link to long description
(complements title) --
name CDATA #IMPLIED -- name of frame for targetting --
src %URI; #IMPLIED -- source of frame content --
frameborder (1|0) 1 -- request frame borders? --
marginwidth %Pixels; #IMPLIED -- margin widths in pixels --
marginheight %Pixels; #IMPLIED -- margin height in pixels --
noresize (noresize) #IMPLIED -- allow users to resize frames? --
scrolling (yes|no|auto) auto -- scrollbar or none --
>
]]>

A FRAME elem egy keret tartalmát és azonosítóját, valamint a szomszédos keretekkel való kapcsolatát írja le. Paramé-
terei :
• name: A keret azonosítója, amely a későbbiekben a keretre való hivatkozásra használható. Ezzel az azonosítóval
lehet például egy másik keretben levő dokumentumból kezdeményezni a keretbe új tartalom betöltését az A elem
target paraméterében megadva az azonosítót.
• longdesc: Egy címet tartalmaz egy olyan dokumentumra, amely – a dokumentum TITLE eleme helyett – a
keret leírását tartalmazza. Különösen a nem képi megjelenítést alkalmazó böngészőknél lehet hasznos.
• src: A keretbe kezdetben betöltendő tartalmat megadó címet kell megadni ebben a paraméterben. Ez általá-
ban egy weboldal, de megadható bármely erőforrás, amelyet magában, mint weboldalt a böngészők képesek
megjeleníteni (például egy kép).
• noresize: Egy logikai kapcsoló. Ha szerepel, akkor a keretet az oldalán levő margóval nem lehet átméretezni.
Ha nem szerepel, akkor a margót a felhasználó megfoghatja, és a keretet átméretezheti.
• scrolling Lehessen-e a keret tartalmát görgetni, ha nem fér el a rendelkezésre álló helyen. Ha értéke az
alapértelmezett auto, akkor csak akkor jelenik meg gördítősáv, ha a tartalom nem fér el a rendelkezésére álló
helyen. yes esetén mindenképpen megjelenik a gördítősáv, míg no esetén akkor sem jelenik meg, ha szükség
lenne rá. Ez utóbbi esetben a nem látszó tartalomhoz semmiképpen nem lehet hozzáférni (legfeljebb a keret
átméretezésével).
• frameborder: Ha értéke 1, a keret szélén megjelenik egy látható margó, ha 0, akkor nem (ekkor nem lehet
megfogni, tehát átméretezni sem).
• marginwidth és marginheight: a keret szélén megjelenő margó vastagságát adja meg oldalt illetve felül
és alul.

A keretnek induláskor meg kell adni a tartalmát. Ha nem adjuk meg, akkor a böngésző üres keretet hoz létre. A kezdeti

127
tartalmat úgy lehet megadni, hogy a keretet leíró FRAME elem src paraméterében megadjuk a megjelenítendő weboldal
címét. Magától értetődő, hogy a keretben nem adható meg maga az anyaoldal, hiszen így egy végtelen ciklusba kergetnénk
a böngészőt a megjelenítés során. Az talán már nem ennyire magától értetődő, pedig ugyanígy igaz, hogy közvetve
sem tartalmazhatja egy weboldal kerete saját magát – legalábbis kezdetben. Amennyiben egy későbbi, hivatkozással
előidézett tartalomcsere eredményeként töltődik be egy keretbe maga a kereteket tartalmazó dokumentum, akkor nem
ennyire veszélyes a helyzet, de értelme nem igen van az ilyen megoldásoknak, ez inkább egy hibás weboldal eredménye
lehet.

11.2. Hivatkozás a keretre


Amennyiben a FRAME name paraméterének adtunk valamilyen értéket, akkor ez használható arra, hogy egy másik
keretben szereplő hivatkozást ebbe a keretbe töltsön be a böngésző. Ehhez a hivatkozás (általában az A, de lehet az
AREA elem is egy képtérkép esetén) target paraméterét kell használni.

106. A hivatkozások target paramétere

A target paraméter az A vagy az AREA (esetleg LINK) elem esetében arra használható, hogy megadjuk, hol kell
megjelennie a hivatkozott dokumentumnak. Űrlap feldolgozása szintén szabályozható ezzel a paraméterrel : a FORM
elemre megadva az action paraméterben megadott, az űrlap feldolgozását végző erőforrás melyik ablakba vagy
keretbe legyen betöltve.
Értéke lehet egy már definiált keret azonosítója, amely esetben a hivatkozott erőforrás a megadott azonosítójú keretben
fog megjelenni. Amennyiben egy még nem használt azonosítót adunk meg, akkor a hivatkozott erőforrás számára egy új
ablakot nyit a böngésző, amelynek a továbbiakban ez lesz az azonosítója. Ennek értelme, hogy a további hivatkozások
ugyanezzel a célpont-azonosítóval ugyanebben az ablakban fognak megjelenni. További, speciális jelentésű értékek :
• _top: az erőforrás a teljes böngészőablakot fogja használni, azaz akárhány keretre van is jelenleg felosztva az
ablak, mindegyik keret eltűnik.
• _parent: az előzőhöz hasonló, azonban többszintű keretezés esetén csak annak az anyaoldalnak a helyére kerül
az erőforrás, amelyik a hivatkozást tartalmazó keretet definiálta.
• _blank egy új ablakot nyit az erőforrásnak a böngésző, amelynek nincs azonosítója, amellyel a későbbiekben
más erőforrást lehetne beletölteni. Ennek használata – bár régen eléggé elterjedt volt – kerülendő, mivel minden
alkalommal új ablakot nyit, ami a felhasználó gépén jelentős memóriát igényel !

Lehetőség van arra is, hogy az adott oldal hivatkozásai számára beállítsunk egy alapértelmezett célpontot. Erre ak-
kor lehet szükség, amikor például egy menüt hozunk létre, amelyben levő hivatkozásoknak a fő („main”) keretben kell
megjelenniük. Erre a hivatkozások alapértelmezett címének megadására szolgáló BASE elemet (lásd 73. szabályt a 83. ol-
dalon) használhatjuk, megadva a target paraméterben a használandó keret azonosítóját. Vigyázat : ettől kezdve minden
hivatkozás, amelyben nem szerepel a target paraméter, a BASE-ben szereplő keretet használja, így ha például a menüt
akarjuk lecserélni egy másik menüre a hivatkozással, akkor külön meg kell adni a menü keretének azonosítóját !
Például ha a menü egy „menu” azonosítójú keretben van, akkor az alapértelmezett keretet a
<BASE target="main">
elemmel megadva, ha le akarjuk cserélni a menüt egy másikra valamely hivatkozás segítségével, akkor arra az alábbi
formájú hivatkozásokat kell használni:

<A href=’submenu1.html’ target=’menu’>...</A>

128
11.3. Mikor a böngésző nem jeleníti meg a kereteket
Amennyiben a böngésző nem képes megjeleníteni a kereteket vagy ha le van tiltva a keretek megjelenítése, akkor a
NOFRAMES elem tartalmát jeleníti meg, mintha a BODY elem lenne.

107. A NOFRAMES elem

<![ %HTML.Frameset; [
<!ENTITY % noframes.content "(BODY) -(NOFRAMES)">
]]>
<!ENTITY % noframes.content "(%flow;)*">
<!ELEMENT NOFRAMES - - %noframes.content;
-- alternate content container for non frame-based rendering -->
<!ATTLIST NOFRAMES
%attrs; -- %coreattrs, %i18n, %events --
>

A NOFRAMES elem a megjelenítendő tartalmat adja meg minden olyan esetre, ha bármilyen ok miatt a böngésző a
keretek megjelenítésére képtelen. Amennyiben a keretek megjeleníthetők, a böngésző figyelmen kívül hagyja az elem
tartalmát.
Mindenképpen a FRAMESET elemen belül, annak utolsó közvetlen leszármazottjaként kell megadni, amennyiben
alkalmazzuk.

11.4. Dokumentum beágyazása másik dokumentumba kerettel


A keretekhez tartozik logikailag az IFRAME elem. Ez a hagyományos, BODY-t tartalmazó oldalakon belül teszi lehetővé
egy téglalap alakú keret létrehozását, amely ettől kezdve ugyanúgy viselkedik, mintha a FRAMESET/FRAME elemekkel
jött volna létre : tartalmazhat egy másik weboldalt.
A belső keretek nem átméretezhetőek.

129
108. Az IFRAME elem

<!ELEMENT IFRAME - - (%flow;)* -- inline subwindow -->


<!ATTLIST IFRAME
%coreattrs; -- id, class, style, title --
longdesc %URI; #IMPLIED -- link to long description
(complements title) --
name CDATA #IMPLIED -- name of frame for targetting --
src %URI; #IMPLIED -- source of frame content --
frameborder (1|0) 1 -- request frame borders? --
marginwidth %Pixels; #IMPLIED -- margin widths in pixels --
marginheight %Pixels; #IMPLIED -- margin height in pixels --
scrolling (yes|no|auto) auto -- scrollbar or none --
align %IAlign; #IMPLIED -- vertical or horizontal alignment --
height %Length; #IMPLIED -- frame height --
width %Length; #IMPLIED -- frame width --
>

Az IFRAME elem blokk-szintű elemként egy téglalapot hoz létre (amelynek így van margója, kerete, belső margója
és háttere, valamint szövegszíne is), amelybe egy újabb weboldal tölthető be, mint keretbe (frame). Mint a paramé-
terlista is mutatja, ugyanazokkal a paraméterekkel rendelkezik, mint a FRAME elem, mely paraméterek ugyanazzal a
jelentéssel is rendelkeznek. Ezenfelül a blokk-szintű elemekre jellemző paraméterekkel és tulajdonságokkal is rendel-
kezik. További két kötelezően megadandó paramétere – vagy elhagyása esetén az azonos funkciót ellátó tulajdonságai
adandók meg :
• height A belső keret magassága;
• width: A belső keret szélessége.
Mivel a keret egy másik oldalban jelenik meg, így a keret méreteit mindenképpen meg kell határozni, ezért kötelező
ezen paraméterek, vagy a velük azonos nevű és hatású tulajdonságok megadása.
Az elem zárótagja csupán arra szolgál, hogy megadható legyen az elem tartalma. Amennyiben a böngésző nem képes
keretek megjelenítésére, akkor az elem tartalma jelenik meg a létrejövő téglalapban. Ha a böngésző képes a keretek
megjelenítésére, akkor létrehozza a megadott méretű belső keretet, és abban az src paraméterrel megadott tartalmat
jeleníti meg, az IFRAME tartalmát pedig figyelmen kívül hagyja.

130
Második rész

Weboldalkészítés haladó szinten

131
12. fejezet

A JavaScript programozási nyelv

12.1. A nyelv alapjai


12.1.1. A JavaScript nyelv kialakulása, feladata és fejlődése
A JavaScript nyelvet a Netscape Communications Corporation – a Netscape böngésző készítői – fejlesztették ki kifeje-
zetten a weboldalak interaktívvá tételének támogatására. Azóta a legtöbb webböngésző képes a JavaScript programok
végrehajtására, bár vannak olyan böngészők, amelyek erre valószínűleg soha nem lesznek képesek.1
A nyelv éppen ezért aránylag egyszerű, hogy a programozásban nem nagyon jártas emberek is könnyen tudjanak
olyan weboldalakat készíteni, amelyek JavaScript alkalmazásokat tartalmaznak. Kifejezetten a weboldallal való együtt-
működésre kiélezett nyelvről van szó, amely alaphelyzetben minden információt a weboldaltól kap, és azon helyez el.
Szerencsére rendelkezik olyan elemekkel is, amelyen keresztül egy önálló párbeszédablakon keresztül is tud kommuni-
kálni, így az egyszerű algoritmusok bemutatására is alkalmas.
Íme néhány példa a nyelv webes alkalmazására :
• Fényreklámok és változó üzenetek elhelyezése a böngésző állapotsorában.
• Űrlapok kitöltés alatti és utáni ellenőrzése, módosítása.
• Üzenetek megjelenítése a weboldalon vagy önálló párbeszédablakban.
• A weboldal tartalmának dinamikus megváltoztatása (például kép megváltoztatása ha az egeret a felhasználó a képre
viszi).
A jelenlegi legújabb böngészők már ismerik a szabványosodó JavaScript 1.5-ös változatát, azonban a régebbi böngé-
szőkhöz hasonlóan még itt is előfordul, hogy valamelyik böngésző bizonyos esetekben nem úgy működik, ahogyan az elő
van írva. Az ilyen problémák elkerülhetők a böngésző típusának lekérdezésével – amely szintén elvégezhető a JavaScript
segítségével.

12.1.2. A JavaScript beillesztése a weboldalba


A HTML kód fejlécében elhelyezhetünk a <script type="text/javascript"> . . . </script> elembe Ja-
vaScript utasításokat. Ezek a weboldal megjelenítése előtt hajtódnak végre. Az oldal belsejében ugyanezzel az elemmel
további utasítások helyezhetők el, amelyek akkor fognak végrehajtódni, amikor a böngésző elér odáig a weboldal feldol-
gozása során.
1 Ilyen a Lynx nevű teljesen karakteres böngésző, amely éppen azért őrzi a népszerűségét, mert nagyon egyszerűen kezelhető, a megjelenítési

problémákkal nem kell törődnie, így nagyon gyors.

132
A fejlécen belül ugyanakkor elhelyezhetünk olyan script elemet is, amely egy külső állományt tölt be. Ezzel önálló
állományban található – és esetleg több weboldalon is felhasználható – JavaScript kódot érhetünk el. Ennek formája :
<script type="text/javascript" src="filename.js"></script>, ahol a filename.js a külső állo-
mány neve.
A legtöbb esetben a weboldalon valamilyen esemény bekövetkezésekor akarunk valamilyen JavaScript programot
végrehajtani. Erre szolgálnak az eseménykezelők, amelyek valamely HTML-elem paramétereként adhatók meg. Ilyen
eseménykezelő például az onClick, amely akkor teljesül, ha az adott elemre rákattintunk az egér valamelyik gombjával.
Az eseménykezelőkről az interaktív weboldalak készítésénél ejtünk majd szót.

12.1.3. Egy egyszerű példa JavaScript programra


A következőkben egy weboldal HTML kódja látható. A program nem csinál mást, mint kiírja egy weboldalra a letöltés
pillanatában érvényes időt.

<html>
<head><title>Az idő és dátum kiírása JavaScript segítségével</title>
</head>
<body>
<h1>Az éppen aktuális dátum és idő</h1>
<p>
<script type="text/javascript">
most = new Date();
localtime = most.toString();
utctime = most.toGMTString();
document.write("<strong>Helyi idő:</strong> "+localtime+"<br>");
document.write("<strong>UTC idő:</strong> "+ utcatime);
</script>
</p>
</body>
</html>

Ezt egy böngészőbe betöltve kiírja a gépen beállított időzóna szerint, valamint alatta az UTC szerinti időt – ahogy a
gép órája jár. Persze ez még nem az az óra-alkalmazás, amire a JavaScript-et használni szokás, hiszen az óra áll, és az idő
múlását nem követi. Ráadásul nem éppen a legszebb a kiírása sem.
Módosítható a program úgy, hogy külön tároljuk az órát, percet, másodpercet és azokat szebb formátumban íratjuk ki.
Ehhez a localtime és utctime értékadása és kiíratása helyett – vagy mellett – a következő kódot kell szerepeltetni:

ora = most.getHours();
perc = most.getMinutes();
mperc = most.getSeconds();
document.write(ora+" : "+perc+" : "+mperc);

A módosítás után újratöltve a böngészőben az oldalt már a kívánt információk jelennek meg.
Megjegyzés. Ebben a témakörben a JavaScript-et elsősorban nem a weboldal tartalmának módosítására fogjuk hasz-
nálni, így elsősorban nem a document.write() függvényt, hanem az alert() függvényt fogjuk kiírásra használni
a programokban. Adatbekérésre a prompt() függvényt fogjuk használni, amely egy párbeszédablakban megjeleníti a
paraméterébe írt szöveget, majd a párbeszédablak beviteli mezőjébe ért szöveget adja vissza.

133
12.2. A JavaScript nyelv szabályai
A következőkben tömören a nyelv alapvető szabályai szerepelnek..

Változók A szokásos programozási nyelvekkel ellentétben a JavaScript-ben a változók használata sokkal egyszerűbb:
nem kell a típusukat előre megadni. Ha egy olyan értéket adunk egy változónak, amely más típusú az előzőnél, azt
sem veszi zokon, csupán egy teljesen új változónak tekinti.
Objektumok A JavaScript részben objektum-orientált nyelv. Ez azt jelenti ebben az esetben, hogy az objektumok hasz-
nálatához nem kell teljesen érteni az objektum-orientált programozás lényegével. Gyakorlatilag anélkül használha-
tunk objektumokat, hogy tisztában lennénk azzal, hogy objektumokat használunk.
Tulajdonképpen minden szöveges változó, számérték egy-egy objektum, így valójában minden változó egy objek-
tumot tárol.
Tömbök A tömbök az Array objektum példányai. Arra szolgál, hogy több értéket tárolhassunk együtt. A tömb elemei
folyamatosan számozva vannak, amely számozást a tömbelem indexének nevezzük. Sok hasznos tulajdonságuk van
a hagyományos nyelvek tömbjeivel szemben :
• A tömb elemszáma dinamikusan változtatható – ellentétben például a Pascal-beli tömbökkel, amelyek mé-
retét a létrehozásukkor meg kell határozni. A tömb pillanatnyi elemszámát a tömb length tulajdonsága adja
meg. Például ha létrehozunk egy tomb nevű változót a var tomb = new Array(); utasítással, akkor
a későbbiekben ennek számosságát bármikor megtudhatjuk a tomb.length értékéből. Ez a tömb elemein
végighaladó algoritmusoknál nagyon hasznos tulajdonság.
Az előző példából már kiderült az egyik mód, ahogyan egy tömböt létre lehet hozni. Ha az Array konstruktor-
nak egy számot adunk paraméterül, akkor egy ennyi elemű tömböt hozunk létre, amelynek elemei léteznek,
de üresek. Később a tömb elemszáma változhat. Ha több értéket adunk paraméternek, akkor ezek lesznek a
tömb elemei.
• Tömb egy adott elemét elérni az indexével lehet, amelyet a tömb azonosítója után szögletes ([]) zárójelek
között kell megadni: a tomb[3] a tomb tömb negyedik elemét adja, mert az indexelés mindig nullával
kezdődik.
• Vannak a tömbnek olyan metódusai, amelyekkel valamely tömbelemet törölhetünk, másikra cserélhetünk, új
tömbelemmel bővíthetjük a tömböt, sorbarendezhetjük a tömb elemeit stb.
Függvények A JavaScript függvényei valójában az objektumok metódusai. Az Alert függvény például az általában el-
hagyható window objektum metódusa. A Math objektum például rengeteg matematikai függvényt tartalmaz, ame-
lyekre mindig úgy kell hivatkozni, hogy eléírjuk a Math. objektum meghatározást. A függvényeknél – a C-hez
hasonlóan – akkor is szerepeltetni kell a zárójelpárt, ha nincs a függvénynek paramétere. Ez különbözteti meg a
függvényt a változótól.
Bármikor definiálhatunk új függvényt is. Ez az egyik leggyakrabban használt eszköze a JavaScript-nek : esemény-
kezelőhöz függvény rendelése, amely az adott esemény bekövetkezésekor elvégzendő teendőket tartalmazza.

Kifejezések A C/C++ nyelvből jól ismert operátorok használhatók a JavaScriptben is.


Vezérlési szerkezetek Szintén a C/C++ nyelv vezérlési szerkezeteivel találkozhatunk leginkább, bár itt már van némi
eltérés, mivel van a JavaScript-nek néhány speciális eszköze is.

A következőkben a függvények, változók, tömbök, kifejezések és vezérlési szerkezetek részletesebb ismertetése kö-
vetkezik.
Tudni kell a JavaScript nyelvről, hogy a C/C++ nyelvhez hasonlóan a kis és a nagybetűket megkülönbözteti egymástól.

134
12.2.1. Adattípusok
A JavaScript a következő alapvető adattípusokat alkalmazza – ilyen típusú értékek adhatók meg konstans formájában:
Számok : Numerikus értékek, alapvetően tízes számrendszerben megadva. Lehetnek egész számok vagy lebegőpontos
számok (tizedesponttal, illetve kitevőt megadó E-vel). Ezeken kívül létezhetnek még speciális numerikus értékek :
Number.MAX_VALUE A legnagyobb megjeleníthető/ábrázolható szám
Number.MIN_VALUE A legkisebb ábrázolható szám
Number.NaN Not-a-Number, nem szám
Number.POSITIVE_INFINITY a végtelent jelölő érték
Number.NEGATIVE_INFINITY a negatív végtelent jelölő érték

Ezek a Number objektumhoz tartozó értékek.


Karakterfüzérek: Másképpen sztringek (angolul string), betűk, számok, egyéb nyomtatható karakterek sorozatai. Tet-
szőleges számú karaktert tartalmazhatnak. Egyszeres vagy kétszeres idézőjelek közé kell őket írni. A PHP-val
ellentétben az egyszeres és a kétszeres idézőjelek teljesen azonos jelentésűek, de mindenképpen azzal kell lezárni
a sztringet, amelyikkel kezdődik. A C/C++ nyelv speciális karaktermegadási módját itt is használhatjuk (pl. "\n"
egy újsor-jelet tartalmazó sztring).
Logikai értékek : true (igaz) és false (hamis) logikai értékeket használhatunk. Ez ellentétes a C nyelvvel, ahol a nulla
érték számít hamisnak, minden más érték igaznak ; önálló logikai (boolean) típust a C nyelv nem ismer.
null Ez az érték a semmi jelölésére szolgál. Nem egyenlő a 0 értékkel !

undefined Definiálatlan változót jelent.

12.2.2. Változók
A változók érték tárolására szolgáló elemei a programozási nyelveknek. A bennük tárolt érték valójában a memóriában
található, és a program végrehajtása során akárhányszor megváltoztatható.
A JavaScript dinamikusan típusos nyelv, azaz amikor a változókat deklaráljuk, akkor nem kell nekik típust adni. Ez a
Java és a PHP nyelvre is hasonlóképpen igaz. Amennyiben egy változót a korábbitól eltérő típusú értékkel látunk el, az
sem jelent problémát: a változó ettől kezdve más típusú lesz.
Változó definiálására a var kulcsszót kell használni. Ekkor akár azonnal adhatunk is neki értéket, vagy azt későbbre
halaszthatjuk. Bár a kulcsszó néhol elhagyható, mégis célszerű minden alkalommal, amikor egy új változót először sze-
repeltetünk, a var kulcsszóval deklarálni. Függvényekben ez például kötelező. Egy deklarációban, vesszővel elválasztva
akár több változó is szerepelhet. Íme néhány deklaráció :

var a=8, b="Szöveg",c=new Array(),d;

Itt az a változó rögtön értéket is kap, ahogyan a b is. A c változó egy tömb típusú változó lesz, míg a d változó nem
kap értéket (undefined értékű).

12.2.3. Megjegyzések
A C++ nyelvben megszokott megjegyzések használhatóak : // után a sor végéig minden megjegyzés lesz, /* után a */
szimbólumig minden – akár több sor is – megjegyzésnek számít.

135
12.2.4. Kifejezések
A C/C++ kifejezéseihez nagyon hasonlók a JavaScript kifejezései is. A függvényhívás éppúgy kifejezésnek számít, mint
az értékadás. A kifejezésekben használatos operátoroknak lehetnek mellékhatásaik, mint például a függvényhívásnak a
függvény végrehajtása, az értékadó operátoroknak pedig az operátor baloldalán álló változó értékének megváltoztatása
az operátor jobboldalán álló kifejezés alapján. A következő táblázat összefoglalja, és röviden ismerteti a JavaScript-ben
használható operátorokat.

12.1. táblázat: Operátorok összefoglalása

Operandusainak
Operátor száma típusa Leírás
+ 2 számok, karakterfüzérek Számokat ad össze, karakterláncokat fűz egymás mögé.
+= 2 számok, karakterfüzérek Elvégzi a két oldalán álló értékre a + operandus által vég-
zendő műveletet, majd az eredményt mellékhatásként a
baloldali változóba helyezi annak régi értéke helyett.
++ 1 számok Az előtte álló operandus értékét mellékhatásként növe-
li egyel miután a kifejezés értéke már ismert. Az utána
álló operandus értékét mellékhatásként megnöveli egyel,
majd ezután a már megnövelt értéket használja a kifeje-
zés.
- 2 számok Kivonja a baloldali operandusból a jobboldalit.
-= 2 számok Kivonja a baloldali operandusból a jobboldalit, majd a
kivonás eredményét elteszi a baloldali változóba.
-- 1 számok Az előtte álló operandus értékét mellékhatásként az ér-
ték felhasználása után csökkenti egyel. Az utána álló ope-
randus értékét mellékhatásként csökkenti egyel, és ezután
felhasználja az új értéket.
* 2 számok A két operandust összeszorozza.
*= 2 számok A két operandus szorzatának eredményét a baloldali ope-
randus által megadott változóba helyezi.
/ 2 számok A baloldali operandust elosztja a jobboldali operandus-
sal.
/= 2 számok A baloldali operandust elosztja a jobboldali operandus-
sal, majd az eredményt elhelyezi a baloldali operandus
által megadott változóba.
% 2 számok A baloldali operandust egész osztást végezve elosztja
a jobboldali operandussal, és az osztás maradékát adja
eredményül.
%= 2 számok A baloldali operandust egész osztást végezve elosztja a
jobboldali operandussal, és az osztás maradékát elhelyezi
a baloldali operandus által megadott változóba.
< 2 számok vagy Igaz, ha a baloldali operandus értéke kisebb a jobbolda-
karakterfüzérek linál, különben hamis. Karakterfüzéreken lexikografikus
összehasonlítást végez.
> 2 számok vagy Igaz, ha a jobboldali operandus értéke kisebb a balolda-
karakterfüzérek linál, különben hamis. Karakterfüzéreken lexikografikus
összehasonlítást végez.
<= 2 számok vagy Igaz, ha a baloldali operandus nem nagyobb a jobbolda-
karakterfüzérek linál, különben hamis.

136
12.1. táblázat: Operátorok összefoglalása (folytatás)

Operandusainak
Operátor száma típusa Leírás
>= 2 számok vagy Igaz, ha a baloldali operandus nem kisebb a jobboldali-
karakterfüzérek nál, különben hamis.
== 2 tetszőleges Igaz, ha a két operandus értéke megegyezik.
=== 2 tetszőleges Igaz, ha a két operandus azonos.
! 1 logikai érték Az utána álló operandus negáltját adja vissza : igaz, ha az
operandus hamis ; hamis, ha az operandus igaz.
!= 2 tetszőleges Igaz, ha a két operandus értéke nem egyenlő.
!== 2 tetszőleges Igaz, ha a két operandus nem azonos.
&& 2 logikai érték Igaz, ha a két operandus közül legalább az egyik igaz (lo-
gikai VAGY).
|| 2 logikai érték Igaz, ha mindkét operandus igaz (logikai ÉS).
, 2 tetszőleges Két kifejezést választ el egymástól. Olyan helyen hasz-
nálva, ahol csak egy szerepelhet, mindet kiértékeli, és az
utolsó értéke lesz az egész kifejezés értéke.
. 1+1 objektum; tulajdonsága A baloldalán levő objektumnak a jobboldali tulajdonsá-
ill. metódusa gát illetve metódusát éri el.
[] tömb és egy egész érték Az előtte szereplő tömbnek, a zárójelek között szereplő
indexű elemét éri el.
() függvény és kifejezék Az előtte szereplő azonosítójú függvényt hívja meg a zá-
rójelek között szereplő kifejezésekkel, mint paraméterek-
kel.
? : 3 logikai érték; Feltételes operátor : ha a kérdőjel előtti logikai kifejezés
tetszőleges ; tetszőleges igaz, akkor a kérdőjel és a kettőspont közti értéket adja
eredményül, különben a kettőspont utánit.
delete objektum, tulajdonsága Objektumot, tulajdonságát vagy tömbelemet töröl.
vagy tömbelem
new objektumtípus A konstruktora segítségével létrehoz egy új objektumpél-
dányt.
typeof tetszőleges Visszaadja az operandus típusát.
void tetszőleges Kiértékel egy kifejezést és nem definiált értéket ad vissza.
& 2 egész értékek Bitenkénti ÉS művelet.
&= 2 egész értékek Bitenkénti ÉS művelet a két operandus között, aminek
az értéke a baloldali operandus által megadott változóba
kerül.
| 2 egész értékek Bitenkénti VAGY művelet.
|= 2 egész értékek Bitenkénti VAGY művelet a két operandus között, ami-
nek az értéke a baloldali operandus által megadott válto-
zóba kerül.
^ 2 egész értékek Bitenkénti KIZÁRÓ VAGY művelet.
^= 2 egész értékek Mint a ^, de az eredményt belerakja a baloldali operandus
által megadott változóba.
~ 1 egész érték Bitenkénti negáció az utána álló operanduson.
<< 2 egész értékek A baloldali operandusnak a jobboldali operandussal tör-
ténő balra eltolása (szorzás 2-vel a jobboldali operandus
értékeszer megismételve).

137
12.1. táblázat: Operátorok összefoglalása (folytatás)

Operandusainak
Operátor száma típusa Leírás
<<= 2 egész értékek Az előzővel azonos, de az eltolás eredményét a baloldali
operanduson érvényre is juttatja.
>> 2 egész értékek A baloldali operandusnak a jobboldali operandussal tör-
ténő jobbra eltolása (egész osztály 2-vel a jobboldali ope-
randus értékeszer megismételve).
>>= 2 egész értékek Mint az előző, de a baloldali operandusban keletkezik az
eredmény.

A műveletek precedenciája
Az alábbi táblázat csökkenő precedenciával mutatja az operátorokat :
Magas szint ., [], ()
++, --, ~, !, delete, new, typeof, void
*, /, %
+, -
<<, >>
<, >, <=, >=
==, !=, ===, !==
&
^
|
||
&&
?:
=, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
Alacsony szint ,

Az operátorok asszociativitása
Nem minden operátorra igaz, hogy a két oldalán levő operandus kiértékelését balról jobbra haladva végzi. A kétoperan-
dusú operátorok közül fordított, jobbról balra haladó kiértékelést végeznek a következő operátorok : valamennyi értékadó
operátor, a szorzás és osztás operátorai.

12.2.5. A JavaScript utasításai


A JavaScript legtöbb utasítása a C/C++ megfelelő utasításával megegyező szerkezetű. Az értékadást a C/C++ nyelvhez
hasonlóan itt is kifejezésnek tekintettük, de tekinthetnénk a megszokott módon utasításnak is, azonban ebben az esetben
figyelembe kell vennünk, hogy nem a = az egyetlen értékadást előíró operátor !
Olyan helyekre, ahol definíció szerint csak egy utasítás szerepelhet a blokk- vagy utasításcsoport-utasítás segítségével
tehetünk több utasítást. Ez is a C-vel megegyező módon, a { } zárójelpárral lehetséges.
A JavaScript nyelv definíciója a változó deklarálását és a függvény definiálását is utasításként tekinti. Előbbi a var
kulcsszó utáni változó, vagy vesszőkkel elválasztva változók megadását jelenti, ahol a változóhoz azonnal értéket is
lehet rendelni. Az utóbbi pedig a function kulcsszó után a függvény azonosítójának megadását, majd a paraméterek
azonosítóinak felsorolását és egy kapcsos zárójelek közé írt utasításlistát jelent, amely utasításlista jelenti a függvény
meghívásakor végrehajtandó műveleteket.

138
Ezen belül használhatók a paraméterben megadott azonosítók változóként, valamint a return utasítás, amely a return
kulcszóból és egy kifejezésből áll. A kifejezés értéke lesz az az érték, amelyet a függvény eredményképpen visszaad. A
return utasítás a függvény végrehajtásának befejezését is jelenti, így bármely ezután szereplő utasítás már nem kerül
végrehajtásra.
A Pascal nyelvből ismerős, de a C/C++ nyelvben nem szereplő utasítás a with. Ez a JavaScript-be azért került be, mert
a leggyakoribb weboldalas használat során nagyon sokszor kell objektumokat használni, így sokszor fordul elő olyan is,
hogy egy-egy objektumnak egymás után többször kell elérni a tulajdonságait vagy a metódusait. A with utasítás éppen
arra jó, hogy ilyenkor ne kelljen minduntalan újra és újra leírni az objektum nevét. A Pascal nyelvben használatosnál
egyszerűbb a szintaxisa: a with kulcsszó után kerek zárójelben szerepel az objektum, amelyet használni akarunk, majd
egy blokkban az objektum tulajdonságait és metódusait úgy használhatjuk, mintha önálló változók illetve függvények
lennének. Például:

with (document.MyForm) {
if ((nev.value == "Grover") && (jelszo.value == "szezam")) {
submit();
}
}

Ez a with utasítás nélkül így nézne ki:

if ((document.MyForm.nev.value == "Grover") &&


(document.MyForm.jelszo.value == "szezam")) {
document.MyForm.submit();
}

Üres utasítás a Pascal és C/C++ nyelvekben is létezik, itt ugyanaz a szerepe : lehessen olyan helyről az utasítást lespó-
rolni, ahova a szintaxis szerint kell. Például olyan for utasításnál használjuk, ahol az utasítás fejléce elvégzi a szükséges
teendőket.2
A try. . . catch utasítás a JavaScript saját egyedi utasítása. Segítségével hibákat lehet kezelni. A try kulcsszó után írt
utasításblokk tartalma lefut. Ha ebben hiba lépett fel, akkor hibaüzenet és a program leállása helyett a catch kulcsszó
utáni blokk kerül végrehajtásra. A catch kulcsszó után megadható egy kerek zárójelben egy változó azonosítója. Ebbe
a változóba kerül az az Event objektum, amely a bekövetkezett hibát leírja. Ezt a blokk utasításaiban fel lehet használni a
hibakezelésre.
Az utóbbiban több az elgépelés lehetősége, és az ebből eredő potenciális hiba. . .

Elágazások
if. . . else Logikai feltétel alapján történő elágazást tesz lehetővé. Az if kulcsszó után kerek zárójelben adandó meg a
logikai értéket eredményül adó kifejezés (C-ből ismert módon egyben akár értékadás is lehet), majd következik a blokk,
amelynek utasításai akkor hajtódnak végre, ha a logikai feltétel igaz értékű. Ezzel akár véget is érhet az utasítás. Például :

if (a<b) {
alert("A második szám a nagyobb.");
}

Azonban a blokk bezárása után folytatódhat az utasítás, mégpedig kétféleképpen :


1. Jön egy else kulcsszó, majd utána egy újabb blokk, amely akkor fog végrehajtódni, ha a logikai feltétel hamis
volt :
2 A C/C++ nyelven programozók gyakran használják ezt a megoldást, ha kifejezés kiértékeléssel elvégezhető a ciklusmag : beteszik a for harmadik,

léptető paraméterébe a kifejezéseket egy-egy vesszővel elválasztva egymástól. Így a ciklusmag látszólag üres.

139
if (a<b) {
alert("A második szám a nagyobb.");
} else {
alert("Nem nagyobb a második szám.");
}

2. Az else kulcsszó után egy újabb if utasítás kezdődik :

if (a<b) {
alert("A második szám a nagyobb.");
} else if (a>b) {
alert("Az első szám a nagyobb.");
} else {
alert("A két szám egyenlő.");
}

Ez utóbbi eset lehetőséget biztosít arra is, hogy egy egész feltételsoron haladjunk végig, azaz esetvizsgálatot vé-
gezzünk.

Esetszétválasztás Amennyiben a feltételek mind egy kifejezés valamely értékével való egyenlőséget firtatják, az if
utasítással így nézne ki a kód:
if (a=1) {
// 1. eset
} else if (a=2) {
// 2. eset
} else if ... {
// n. eset
} else {
// egyéb eset
}
A fenti kód helyett használható a switch utasítás az alábbi módon :
switch (a) {
case 1:
// 1. eset
break;
case 2:
// 2. eset
break;
...
case n:
// n. eset
break;
defaul:
// egyéb eset
break;
}

140
Ez azonban többet tud az if -es megoldásnál, mivel ha elhagyjuk valamely eset végéről a break utasítást, akkor a
vezérlés ráfut a következő esetre, és az is végrehajtásra kerül.3 A default rész elhagyható, amennyiben nincs teendő
abban az esetben, ha egyetlen eset sem teljesül.

Ciklusok
Elöltesztelő ciklus Az elöltesztelő ciklus megvalósítását a C/C++ nyelvbelivel azonos módon működő while utasítás
teszi lehetővé : A while kulcsszó után zárójelben egy logikai értéket adó kifejezés, majd egy blokk, ami a ciklusmag
utasításait tartalmazza, és mindaddig ismételten végrehajtódik, ameddig a logikai kifejezés értéke igaz (true).

Hátultesztelő ciklus Ez is megegyezik a C/C++ nyelvben használatossal : egy do kulcsszó utáni blokk adja a ciklusma-
got, amelyet a while kulcsszó és a kerek zárójelben a feltételt megadó logikai kifejezés követ. Az ismétlésnek a feltétele
ezúttal is a kifejezés igaz értéke.

Számlált ciklus A C/C++ stílusú for utasításban a for kulcsszó utáni kerek zárójelen belüli három, egymástól pontos-
vesszővel elválasztott kifejezés szerepe sorban:
1. inicializáló kifejezés: a ciklus első végrehajtása előtt kerül kiértékelésre.
2. belépési feltétel: logikai igaz értéke esetén fog a ciklusmag lefutni.
3. léptető kifejezés: a ciklusmag utolsó utasításának végrehajtása után kerül kiértékelésre, általában a ciklusváltozó
léptetésére szokás használni.
Ezek után következik a ciklus magját tartalmazó blokk.
Gyakorlatilag a for utasítás megvalósítható lenne while utasítással is.

szum=0;
for (i=0;i<t.length;i++) {
szum+=t[i];
}

A fenti kód két más formában is írható. Az első a while utasítással való összehasonlítás kedvéért :
szum=0;
i=0;
while (i<t.length) {
szum+=t[i];
i++;
}
A másik a for utasítás C/C++ programozók által alkalmazott tömörítése, aminek szintén két módja lehet. Íme az első,
amikor mindkét inicializáló kifejezést elhelyezzük a fejlécbe, és kiürítjük a ciklusmag blokkját :

for (szum=0,i=0;i<t.length;szum+=t[i],i++) {
}

Ennek a C/C++ programokban használt még nagyobb tömörítése,4 amely kihasználja, hogy a ++ operátor az operan-
dus után használva csak azután növeli az operandus értékét, miután már felhasználta az értékét :
3 Itt jelentős eltérés van a Pascal Case utasítása és a C/C++ switch utasítása között : A Pascal-ban egyszerre csak egy eset hajtható végre, míg a

C/C++-ban megfelelő elrendezéssel ugyanaz az utasítás több esetben is végrehajtásra kerülhet. Ugyanakkor a Pascal-ban egy esethez egynél több érték
is megadható, míg a C/C++-ban ehhez éppen az kell, hogy az egyes esetekről a következőre átengedhető a vezérlés : minden értékhez külön case sor
kell, de ezek közvetlenül is követhetik egymást, ami így az esetek összevonását jelenti.
4 Nem biztos, hogy a blokk a JavaScript-ben is elhagyható!

141
for (szum=0,i=0; i<t.length; szum+=[i++]) ;
Megjegyzés. A fenti kódrészletek mindegyike a következőt csinálja : a t tömb elemein végigfut – kihasználva, hogy a tömb
length tulajdonsága a tömb elemeinek számát tartalmazza – és az elemek összegét kiszámolja a szum változóba. Ez tehát
valójában a tömbelemek összegzését végző algoritmus megvalósítása JavaScript-ben. C/C++ nyelvben a t.length nem
használható, ez kifejezetten a JavaScript előnye. . .

Halmaz elemein futó ciklus A for utasítás kerek zárójelén belül a fentiek helyett használható még egy (változó in
tömbazonosító) forma is. Ez azt jelenti, hogy a változó végigmegy a tömbazonosító minden elemének megfelelő indexen,
és minden ilyen indexértékre pontosan egyszer végrehajtódik a ciklus. A fenti példában szereplő kódrészlet tehát – csak
JavaScript-ben, C/C++-ban nem – azonos végeredménnyel lecserélhető az alábbira is :
szum=0;
for (i in t) {
szum+=t[i];
}

Végrehajtás megszakítása ill. ciklus folytatása a következő menettel


Van két speciális kulcsszó, mint utasítás, amely normális utasítás végrehajtási rendet töri meg.
Az egyik a break, amelyet a végrehajtás alatt álló blokkból való kilépésre lehet használni. A switch utasításból
az eset végéről való továbbhaladás megakadályozására szokás használni. Cikluson belül alkalmazva kilép a vezérlés a
ciklusból, és a ciklus utáni első utasítással folytatódik a program végrehajtása.
A másik a kifejezetten cikluson belül használatos continue, amely befelyezi a ciklusmag végrehajtását, de a ciklust
nem. Ehelyett a feltétel újra kiértékelésre kerül, mintha a ciklusmag végére értünk volna. Tehát ezzel az utasítással a
ciklusmag következő végrehajtásával folytatódhat a program.

12.2.6. Függvények
Tulajdonképpen a JavaScript-ben a legtöbbet használt nyelvi elemek a függvények. A Pascal nyelvben aránylag későn
kerülnek először szóba a programban definiált függvények ; ezzel szemben itt szinte magától értetődő a használatuk.
Fontos szabály: a függvény attól függvény, hogy azonosítóját – akár üres, akár paramétereket tartalmazó – kerek
zárójel követi.
Függvény definiálása a function kulcsszóval kezdődik. Utána a függvény neve, majd paraméterlistája következik,
amit a függvény utasításait tartalmazó blokk követ.
A C/C++ nyelvvel ellentétben függvényen belül is elhelyezhetünk függvény definícióját, amely ekkor értelemszerűen
az őt magába záró függvény végéig létezik, azon kívül nem használható.

12.2.7. Objektumok
Az objektumok a JavaScript fontos elemei, de a szokásos objektum definíciótól eltérően működnek. A C++ és a Pascal
egyaránt elvárja, hogy előbb pontosan definiáljuk az objektumot. Ezzel szemben a JavaScript esetében nem kell megadni
előre az objektum elemeit, mindössze a konstruktorát. Ez tartalmaz this.azonosító = kifejezés értékű utasításokat. Ez
hozza létre az azonosító nevű tulajdonságot, amelynek értéke kifejezés lesz. Amennyiben a kifejezés helyett egy függvény
azonosítóját adjuk meg, akkor azzal egy metódusként adjuk az objektumhoz azt a függvényt.5
Egy objektum tulajdonságaira és metódusaira – akár előre definiált, akár általunk létrehozott objektumtípusról van szó
– az objektumpéldány azonosítója után írt ponttal lehet hivatkozni. A pont után a tulajdonság illetve metódus következik.
Például a document.write() a document objektum write metódusát jelenti.
A következőkben a legfontosabb objektumokat nézzük még végig, amelyek használata a legtöbbször elkerülhetetlen.
5 Ezúttal a függvénynek csak az azonosítója szerepel. Ha a zárójelt is megadjuk, akkor egy függvényhívást tartalmazó kifejezést adunk meg, nem

magát a függvényt!

142
12.2.8. Tömbök
Tömbök használata valójában az Array objektum egy-egy példányának használatát jelenti. Tömbök létrehozása tehát az
Array() konstruktorral lehetséges. Ennek három módja van.
Az első, amikor egy üres tömböt hozunk létre:
var t = new Array();

Ekkor a t tömb üres lesz. A length tulajdonság értéke 0. A másik lehetőség, hogy felsoroljuk a tömb paramétereit.
Ennek két formája látható az alábbi kódrészleten:
var t1 = new Array("Honda","Ford","Toyota");
var t2 = ["Honda","Ford","Toyota"];

A két tömb ugyanazokat az elemeket fogja tartalmazni, a length értéke 3. Harmadik megoldásként megadható az
Array() konstruktor paramétereként az elemszám. Ekkor egy ennyi elemű üres tömb jön létre.
A tömb elemeire hivatkozni a tömb azonosítója után megadott szögletes zárójelekbe írt index-szel lehet, nullától
length-1 értékig. Ha értéket adunk egy ennél nagyobb indexű tömbelemnek, azzal új tömbelemmel bővítjük a tömböt,
amelynek elemszáma így megfelelően módosul.
A tömböknek a következő tulajdonságai és metódusai vannak :
concat() A paraméterében szereplő értékeket a tömb végére fűzi egy-egy új elemként.
join() A paraméterében megadott sztringet alkalmazva elválasztó karaktersorozatként, visszaadja a tömb elemeinek
összefűzésével kapott sztringet.
length A tömb elemeinek számát tartalmazza.

pop() A tömb utolsó elemét törli.


push() A tömb végére felveszi a paraméterében szereplő értékű tömbelemet.
reverse() A tömb elemeinek sorrendjét megfordítja.
shift() A tömb első elemét törli úgy, hogy a többi elem indexe egyel csökken.
slice() A tömb egy részét új tömbként adja vissza. Két paramétere adja meg, hogy hanyadik elemtől hány elemet kell
kivágni.
short() Rendezi a tömb elemeit, és a rendezett tömböt visszaadja.

splice() A megadott indextől kezdve megadott számú elemet töröl a tömbből, és beteszi a helyükre a további paraméte-
rekként szereplő értékeket.
toString() A tömb karaktersorozattá alakított változatát adja vissza.
unshift() A tömb elejére beszúrja a paraméterében szereplő értékeket.

12.2.9. Dátumkezelés
A Date objektum segítségével lehet a dátumokat kezelni. Amennyiben úgy hozzuk létre az objektum egy példányát, hogy
a konstruktornak nem adunk paramétert, akkor az adott példány a létrehozáskori időpont adatait fogja tartalmazni, a
metódusaival tehát ezeket lehet lekérdezni:

143
most = new Date();
document.write("Mostani idő:"+most.getFullYear+". "+
most.getMonth()+". "+most.getDate()+"<br>");
document.write(most.getHours()+" óra "+most.getMinutes()+
" perc "+most.getSeconds()+" másodperc.");
Amennyiben a konstruktornak egy egész értéket adunk paraméterben, akkor az a UnixTimestamp kezdődátumától,
1970. január elseje éjféltől eltelt ezredmásodpercek számaként értelmezve adja meg azt az időpillanatot, amit az objek-
tumpéldányba kell elhelyezni.
A másik lehetőség a konstruktor paraméterezésére, ha felsoroljuk a dátum komponenseit év, hónap, nap, óra, perc,
másodperc sorrendben. Ennek egy része természetesen el is hagyható :
szulinap = new Date(2001,04,12);
Ez az adott nap éjfélre állítja a szulinap változóban levő objektumot.
A metódusok felsorolásától ezúttal tekintsünk el. Mindenesetre a getValami lekérdezi a Valami részt a dátumból, míg
a setValami beállítja azt.

12.2.10. Matematikai eszközök


A statikus Math objektum segítségével lehet elérni különböző matematikai függvényeket illetve konstansokat. Az, hogy
a Math statikus objektum, az azt jelenti, hogy nem lehet a szokásos módon példányát létrehozni, mindössze a metó-
dusait és tulajdonságait érhetjük el a Math. szöveg után írva őket. Ennek megfelelően a továbbiakban – nem teljes –
ismertetésüknél a teljes használandó szöveggel adjuk meg ezeket.

Trigonometrikus függvények
A szinusz, koszinus, tangens függvények rendre a Math.sin(), Math.cos(), Math.tan() függvényekkel számolhatók ki.
Ugyanezek visszaszámolására alkalmas az Math.asin(), Math.acos() és Math.atan() függvény.

Kerekítés és abszolút érték


A paramétere abszolút értékét adja a Math.abs() függvény.
Hagyományos matematikai értelemben vett kerekítést hajt végre a Math.round() függvény, míg minden esetben felfelé
illetve lefelé kerekít a Math.ceil() illetve a Math.floor() függvény.

Hatványozás és logaritmus
Alapvetően természetes alapú logaritmusokkal lehet dolgozni a JavaScript-ben. az Math.exp() függvény a paraméterét
mint kitevőt, a természetes alapú logaritmus alapszámát mint hatványalapot tekintve hatványoz. Magyarul Math.exp(x)
értéke ex lesz. Ennek ellenkezőjét, vagyis a paraméter természetes alapú logaritmusát adja a Math.log() függvény. A
Math.LN10 a 10 természetes alapú logaritmusát adja. Hasonló konstans a Math.LN2. Az e tízes illetve kettes alapú loga-
ritmusa a Math.LN10E illetve Math.LN2E konstansokban található.
Az xy hatvány kiszámítását a Math.pow(x,y) √ függvénnyel lehet elvégezni. Négyzetgyökvonásra a Math.sqrt()
függvény használható: Math.sqrt(x) értéke x.

Véletlenszámgenerátor
Álvéletlen számok előállítására használható a Math.random() függvény. Ez minden esetben egy 0 és egy közötti valós
számot ad eredményül.

144
Legkisebb és legnagyobb érték kiválasztása
A paraméterei közül – két paramétere lehet – a nagyobbat adja a Math.max() függvény. Hasonlóan a kisebbik értéket a
Math.min() függvény adja vissza.

12.2.11. Megyjegyzések
Hasznos lehet, ha a programjainkba olyan megjegyzéseket írhatunk, amelyet nem kell végrehajtani, azonban segítenek
később megérteni a program működését, ha már nem emlékszünk a program kódjára. Erre a legtöbb programozási nyelv
kínál valamilyen lehetőséget.
A C/C++ nyelvcsalád eredetileg a /* és */ szimbólumpárok közé írt szöveget tekinti megjegyzésnek, de a C++
nyelvben bevezették az egysoros megjegyzéseket is, amelyek a // után írandók. Az első változatban a két szimbólum
közti szöveget, míg a második változatban a // szimbólumtól a sor végéig tartó szöveget hagyja figyelmen kívül a
program feldolgozója. Mind a Java, mind a JavaScript, mind pedig a PHP ismeri mindkét megjegyzésfajtát.

12.3. Alapvető algoritmusok


A következő fejezetben olyan algoritmusok szerepelnek, amelyek ismerete elengedhetetlen programok írásakor.6 A bemu-
tatásukra a JavaScript azon képességét fogjuk kihasználni, hogy bár weboldal interaktívvá tételére készült nyelv, biztosít
egyszerű beviteli és kiíró eszközöket. Némelyik algoritmusra olyan példa is szerepelni fog, amely csak később bemuta-
tandó eszközöket használ az algoritmus működésének bemutatására. Ilyenek lesznek elsősorban a rendező algoritmusok.

12.3.1. Adott elem keresése tömbben


Adott egy tömb, amelyben szeretnénk megkeresni egy elemet, és megkapni annak indexét a tömbön belül. Erre a követ-
kező algoritmus használható:

1. Vegyük a tömb legkisebb indexű elemét.


2. Ha az elem a keresett elem akkor jegyezzük meg az indexet, és fejezzük be a keresést, különben vegyük a követ-
kező tömbelemet, és ismételjük meg ezt a lépést.

Ez a fenti leírás nem tökéletes leírása az algoritmusnak, hiszen az máris sejthető az „ismételjük meg” szövegből, hogy
itt bizony ciklusra van szükségünk. Íme az algoritmus helyes leírása mondatszerű leírás használatával :

1. Legyen i a T tömb legkisebb elemének indexe7


2. Amíg T [i] 6= keresett érték és van még tömbelem ismételd :
(a) növeld meg az i értékét egyel (vedd a következő tömbelemet)

3. Ciklus vége
4. Ha T [i] = keresett érték
akkor eredmény: i
különben a tömbben nem szerepel a keresett érték.

Az algoritmus folyamatábrája a 12.1 ábrán látható.


Az algoritmust megvalósító – egyik lehetséges – program a következő :
6 Éppen ezért az emelt szintű érettségin is tudni kell ezeket megvalósítani.
7 Ez a C-nyelvcsalád esetén mindig nulla, Pascalban lehet más is a tömb kezdő indexe. . .

145
y
?
i←0

?
T [i] 6= keresett ? @
@
nem igen
?
i ← i+1

?
igen nem
T [i] = keresett ? @
@
? ?
i @ „nincs ilyen” @

y
?

12.1. ábra. A tömbelem keresésének folyamatábrája

<script type="text/javascript">
function tombben_keres(tomb,ertek) {
var i;
i=0;
while ((tomb[i]!=ertek) & (i<tomb.length)) {
i++;
}
if (tomb[i]==ertek) {
return i;
} else {
return -1; // ilyen érték úgysem lehet, tehát alkalmas hibajelzésre
}
}
</script>
A függvényt egy weboldalba beillesztve, és valamilyen módon egy tömböt és egy értéket megadva neki, a függvény
visszaadja az indexét annak az elemnek, amely értéke a második paraméterrel megegyezik, vagy −1-et, ha nem szerepel
a keresett érték a tömbben.
Az algoritmus egy C-nyelven programozókra jellemzőbb megvalósítása a következő :

<script type="text/javascrip">
function tombben_keres(tomb,ertek) {
var i;
for (i=0;(tomb[i]!=ertek) & (i<tomb.length);i++);
if (tomb[i]==ertek) {
return i;

146
} else {
return -1;
}
}
</script>

A http ://pc2.mfg-kkfhaza.sulinet.hu/downloads/jegyzet/js.tgz címről letölthető csomagban levő tombkeres.html


weboldal tartalmazza a függvény használatát, amelyben egy űrlapban kell megadni tíz tömbelemet, majd a keresendő
elemet, és megkapjuk válaszul, hogy van-e, és ha igen – először – hanyadik tömbelemként ez az érték a tömbben.

12.3.2. Keresés intervallumfelezéssel


Amennyiben a tömbünk rendezve van, akkor az előbbi algoritmusnál gyorsabb módszer is van a keresésre, amely ki-
használja a tömbelemek rendezettségét. Minden lépésben megfelezzük azt az intervallumot, amelyben a keresett elem
található, így a ha a tömbnek n eleme van, akkor log n lépésben az intervallum egyetlen elemet tartalmazóvá válik, amely
elem vagy a keresett elem, vagy az elem nincs jelen a tömbben.
Ehhez szükségünk van az intervallum két határát jelölő indexre, és a kettő közötti felezési pontra. Az algoritmus
ezután rekurzív algoritmusként pillanatok alatt felírható :

inter-keres(tomb,a,b,mit):
a+b
1. tipp ← 2

2. Ha tomb[tipp]=mit
akkor visszaad: tipp
különben :
• Ha tomb[tipp] < mit
akkor inter-keres(tomb,tipp+1,b,mit)
különben inter-keres(tomb,a,tipp-1,mit)
3. eljárás vége
JavaScript-ben a fenti függvény a következőképpen nézne ki :
function interKeres(tomb,a,b,mit) {
var tipp; // lokális változó

if (a>=b) {
return -1; // nincs intervallum, amiben a keresett elem benne van
}

tipp = (a+b)/2; // ez nem feltétlenül egész!


tipp = floor(tipp); // vesszük az alsó egész részét
if (tomb[tipp]=mit) {
return tipp; // megvan az eredmény!
} else if (tomb[tipp] < mit) {
return interKeres(tomb,tipp+1,b,mit)
} else {
return interKeres(tomb,a,tipp-1,mit)
}
}

147
Az első if utasítás a rekurzió leállításáról gondoskodik abban az esetben, ha a keresett elem nincs a tömbben. Ekkor
ugyanis az intervallum két határa összeér anélkül, hogy a keresett elemet megtaláltuk volna.
Természetesen a fenti algoritmus illetve programkód átalakítható rekurziót nem igénylő formába is. Ekkor a rekurzív
hívás helyett a megfelelő intervallumhatárt kell átállítani, és az egész függvényt egy ciklusba helyezni :
function interKeres2(tomb,mit) {
var a,b,tipp; // most az intervallumhatárok is belső változók

a=0; b=tomb.length-1;
tipp = (a+b)/2; // első tippünk
while (tomb[tipp]!=mit && a<b) {
if (tomb[tipp]<mit) {
a=tipp+1;
} else {
b=tipp-1;
}
tipp = (a+b)/2; // új tipp
}
if (tomb[tipp]==mit) {
return tipp; // megvan a keresett elem
} else {
return -1; // nincs meg a keresett elem
}
}

12.3.3. Legkisebb és legnagyobb elem megkeresése


Egy tömbben a legkisebb és a legnagyobb elem megkeresése egyszerű feladat : nézzük végig az összes elemet, és jegyez-
zük föl minden esetben, ha az addiginál kisebb illetve nagyobb elemet találtunk. A tömb végére érve a feljegyzett elem
biztosan a legkisebb illetve legnagyobb elem lesz. Mondatszerű leírással ez a következőképpen néz ki :

• min,max ← tomb[0]
• Ciklus tomb minden i indexére:
– Ha tomb[i]<min akkor min ← tomb[i]
– Ha tomb[i]>max akkor max ← tomb[i]
• Ciklus vége
• Ki : min,max

A JavaScript megvalósítás valahogy így nézhet ki8

var min,max = tomb[0];


var mini,maxi = 0;
var i;
for(i=1; i<tomb.length; i++) {
if (tomb[i]<min) {
8 A programkódnak ez egy részlete, amely feltételezi, hogy a tomb nevű változó tartalmazza a tömböt, és a programkód után a min és max változóban

lehet a legkisebb és a legnagyobb tömbelemet megtalálni, azok indexét pedig a mini és maxi változók tartalmazzák.

148
min = tomb[i];
mini = i;
}
if (tomb[i]>max) {
max = tomb[i];
maxi = i;
}
}

Természetesen a fenti programrészlet függvényként is megvalósítható, azonban ebben az esetben a legkisebb és a


legnagyobb érték illetve indexük visszaadása a JavaScript-ben problémás lehet, mert négy értéket kell visszaadni. Meg-
oldás lehet két függvény alkalmazása, amelyek a legkisebb illetve legnagyobb érték indexét adják csak vissza. PHP-ben
elhelyezhető a négy érték egy tömbben is, és az a tömb adható vissza. Ugyanez persze JavaScript-ben is lehetséges, de a
PHP asszociatív tömbje helyett ezúttal csak indexek használhatóak. . .

12.3.4. Rendezések
Ahhoz, hogy az előző algoritmus működjön, rendezett tömbre van szükségünk. Kell tehát legalább egy algoritmus, ami-
vel egy tömb elemeit valamilyen szempont szerint rendezni tudjuk. A következőkben több ilyen rendező algoritmust is
mutatunk.9

Buborékrendezés
Kis méretű tömbök hatékony – nagyobb méretűeken van gyorsabb – a buborékrendezés. Ez úgy működik, hogy addig
megyünk végig a tömbön, két-két szomszédos elemet összehasonlítva, és szükség esetén megcserélve, amíg minden elem
a helyére nem kerül.
Minden menetben egy elem a helyére kerül, így a következő menetben már egyel kevesebb elemet kell vizsgálni, és
ebből következően legkésőbb az n-edik menet végére az n elemű tömb rendezetté válik. Ebből látható, hogy nagyjából
n2 összehasonlítás árán lehet ezzel a módszerrel rendezni egy tömböt.
Az algoritmus folyamatábrája a 12.2 ábrán látható, mondatszerű leírása a következőképpen néz ki :

• Ciklus i n-től 2-ig terjedő értékeire:


– voltcsere ← Hamis
– Ciklus j 0-tól i − 1-ig terjedő értékeire :
∗ Ha tomb[i]>tomb[i + 1] akkor cserél(tomb[i],tomb[i + 1]) ; voltcsere ← Igaz
– Ciklus vége
– Ha nem voltcsere akkor kilépés a ciklusból
• Ciklus vége

Mint látható, az algoritmus gyorsítható, ha adunk egy menekülési utat a ciklusból abban az esetben, ha egy menetben
nem történt egyetlen csere sem, hiszen ez azt jelenti, hogy már minden tömbelem a helyén van, tehát a további menetekben
sem lesz csere. Erre szolgál a minden elején hamis értékre állított voltcsere változó, amelyet egy-egy cserénél igazra
állítunk.
Az algoritmus hagyott egy nyitott kérdést: hogyan cserélünk ki két elemet ? Ez minden rendező algoritmusnál fel fog
merülni, hiszen a rendezés mindig az elemek cseréjével valósítható meg.
9A JavaScript tömbjei rendelkeznek rendező metódussal, azonban az alaphelyzetben szövegek rendezésére alkalmas, nem számok rendezésére. Más
programozási nyelveknél nincs tömböt rendező függvény, azt szükség esetén a programozónak kell megírnia, ezért célszerű ismerni az alapvető rendező
algoritmusokat.

149
@
?
i←n
-
? nem  
i ≥ 2? @ - STOP
@  
igen
?
j←0

?
i ← i+1  j < i? @
nem @
igen
?
tömb[j]>tömb[j + 1] ? @
nem @
igen
?
csere(tömb[j],tömb[j + 1])
-
?
j ← j +1

12.2. ábra. A buborékrendezés folyamatábrája

A csere során az egyik tömbelemet át kell tenni a másikba. Igen ám, de ezzel töröljük annak korábbi tartalmát. Hogy ez
ne következzen be, azt az elemet előbb el kell menteni valahova, egy ideiglenes munkaváltozóba. Tehát a csere valójában
három értékadó utasítással és egy segédváltozóval valósítható meg :
1. munka ← a
2. a ← b
3. b ← munka
Az algoritmust megvalósító JavaScript függvény tehát a következő :
function Buborek(tomb) {
var i,j,munka,voltcsere;

i = n;
do {
voltcsere = false;
for (j=0; j<(i-1); j++) {
if (tomb[j]>tomb[j+1]) {
voltcsere = true;
munka = tomb[j];

150
tomb[j] = tomb[j+1];
tomb[j+1] = munka;
}
}
} while (i>1 && voltcsere)
return tomb;
}
A fenti algoritmus a rendezett tömböt vissza is adja értékként, ami talán felesleges, de lehetséges, hogy a JavaScript
függvények egy adott böngésző esetén úgy adják át a paramétereiket, hogy azokat a függvény hiába módosítják, az az
eredeti változóra nincsen hatással. Ezt célszerű valószínűsíteni, mivel a függvényen belül a paramétere lokális változónak
számít. Így a rendezés eredményét jobb visszatérési értékként visszaadni.

Beszúró rendezés
Ez a rendező algoritmus gyakorlatilag azt az esetet modellezi le, amikor egymás után keressük meg a tömbben az elemek
helyét a már elhelyezett elemek között. Ez azt jelenti, hogy az i-edik elem esetén a [0, i−1] indexű elemekhez hasonlítjuk,
és ha a sorrendben utána következőt találunk, annak a helyére beillesztjük, és a további elemeket egyel hátrébb toljuk.
Mivel ezt minden elemre meg kell tenni, gyakorlatilag a buborékrendezés idejével azonos az időigénye. Az algoritmus
mondatszerű leírása a következő (folyamatábrát ezúttal nem adunk meg) :

1. Ciklus j 2-től n-ig terjedő értékeire (n a tömb elemszáma) :


2. kulcs← tömb[j]
3. i ← j −1
4. Amíg i > 0 és tömb[i]>kulcs ismételd:
5. tömb[i + 1]←tömb[i]
6. i ← i−1
7. Ciklus vége
8. tömb[i + 1]←kulcs
9. Ciklus vége

A JavaScript tömbkezelő függvényeivel a fenti algoritmus egyszerűbben is megvalósítható, hiszen ott bármely két
tömbelem közé egyetlen lépésben be lehet szúrni egy új elemet. Ezt a fenti algoritmus úgy valósítja meg, hogy minden
egyes tömbelemet egyel hátrább pakol, így csinálva helyet a beszúrandó elemnek. Először lássuk a fenti algoritmusnak
teljesen megfelelő – más programnyelven is alkalmazható megoldást :

for (j=2; j<=tomb.length;j++) {


kulcs=tomb[j]; // éppen ennek keressük a helyet
i = j-1;
while (i>0 && tomb[i]>kulcs) {
tomb[i+1]=tomb[i];
i=--;
}
tomb[i+1]=kulcs
}

151
És most lássuk, hogyan lehet mindezt a JavaScript tömbök metódusainak felhasználásával megoldani :
for (j=2; j<=tomb.length; j++) {
kulcs=tomb[j]; // éppen ennek keressük a helyet
tomb.slice(j,1); // kivesszük az elemet a tömbből
// megkeressük az új helyét:
for (i=j-1;i>0 && tomb[i]>kulcs;i--);
tomb.slice(i+1,0,kulcs); // beillesztjuk a helyére az elemet
}

Minimum-elvű rendezés
Ha egy tömbrészben megtudjuk keresni a legkisebb elemet, akkor ezt kihasználva képesek vagyunk egy tömböt emelkedő
sorrendben rendezni is:
• Ciklus i 0-tól n − 1-ig terjedő értékeire:
• Keressük meg a legkisebb elemet i és n között, és cseréljük ki ezt az elemet a tömb[i]-vel

• Ciklus vége
Mint látható, itt nem a teljes algoritmus szerepel, hanem felhasználtuk a minimum keresésére korábban látott algorit-
must. Azt természetesen módosítva kell alkalmaznunk, hiszen szükségünk van annak megadására, hogy a tömb hanyadik
elemétől kezdjük a legkisebb elem keresését, valamint a megtalált legkisebb elem indexére van szükségünk az értéke
helyett.
Ez alapján a minimum-elvű rendezés gyakorlati megvalósítása már nem jelenthet gondot.

Rekurzión alapuló rendezések


A következő két algoritmus rekurzión alapul. Ennek eredményeként a korábbiaknál gyorsabban is tud működni. Ezek
ugyanis képesek kihasználni azt a lehetőséget, hogy a rendezési feladatot két fél-tömbre vezetik vissza, amelyek mérete
éppen fele az eredetinek. Sajnos mindkét algoritmusnak van hátránya. Az első, az összefésülő rendezés, minden rekurzív
lépésben újabb tömböket hoz létre, és azokat rendezi. A második, a gyorsrendezés pedig nem garantálja a tömb felezését,
így előfordulhat olyan eset is, amikor a buborékrendezésével azonos ideig tart, azonban az átlagos rendezési idő ennél
jóval gyorsabb szokott lenni.
Van még egy harmadik rekurzión alapuló rendezés, amelyet bonyolultabb adatszerkezet igénye miatt nem ismertetünk
– egyenlőre –, a kupacrendezés, amely e két hátrányt kiküszöböli, és mindig a lehető legjobb, n log n nagyságrendű időben
rendezi az n elemű tömböt, szemben a gyorsrendezés várhatóan n log n idejével.
Ezeket a rendezéseket már csak vázlatosan ismertetjük.

Összefésülő rendezés
Azon az elven alapul, hogy két rendezett tömb egyetlen rendezett tömbbé összefésülése a két tömb elemszámának össze-
gével arányos lépésben elvégezhető: mindig abból a tömbből kell kivenni a soron következő elemet, amelyik értéke
alapján előbb következik.
Egy elemű tömböt rendezettnek tekintünk, így arra már nem kell rekurzív hívást alkalmazni. Egyébként pedig felbont-
juk a tömböt a felénél, és a két felét egy-egy új tömbbe másoljuk, amelyet aztán az összefésülő algoritmussal rendezünk.
Az így visszakapott két tömböt azután a fentebb említett módon összefésüljük egyetlen rendezett tömbbé.

152
Gyorsrendezés
A gyorsrendezésnél is kétfelé próbáljuk bontani a tömböt, de nem másoljuk át másik tömbbe, hanem helyben rendezzük.
Ehhez első lépésben valamilyen módon egy adott – a tömbben szereplő – értéknél kisebb elemeket a tömb elejére,
a többit a végére gyűjtjük, majd ennél a bizonyos értéknél kettévágjuk a tömbböt, és a két felén külön-külön végzünk
gyorsrendezést (itt is rendezettnek számít az egy elemű tömb).
Ezután a két féltömb rendezve van, és mivel úgy vágtuk ketté a tömböt, hogy az első felében levő minden elem kisebb
a második felében levő valamennyi elemnél, így a teljes tömb rendezett lett.
A probléma annak az értéknek a megválasztása szokott lenni, amely alapján a tömbböt ketté kell vágni. Erre nincs
olyan megoldás, amely biztosan a tömb megfelezését eredményezi. Többféle módszert alkalmaznak erre, de mindegyik
módszernél előfordulhat olyan eset, hogy a tömböt egy 1 elemű és egy n−1 elemű résztömbre sikerül bontani. Ha minden
menetben ez fordul elő – aminek persze kicsi a valószínűsége –, akkor bizony az algoritmus futási ideje nagyságrendileg
n2 lesz, akár a buborékrendezésé. . .
Az elemek szétválogatása olyan módon történik, hogy két indexet indítunk el : egyet a tömb elejéről, egyet pedig a
végéről. Először az elejéről indult indexet léptetjük az első olyan tömbelemig, amely nagyobb a kiválasztott elemnél,
majd hasonló módon keresünk egy elemet a tömb végéről indulva, amely a kiválasztott elemnél kisebb. Ezt a két elemet
megcseréljük, majd folytatjuk mindezt egészen addig, amíg a két index össze nem találkozik valamely tömbelemnél. Itt
kell a tömböt kettévágni.

Gyorsrend(a,b)
• neo←tömb[ a+b
2 ]

• alsó← a; felső← b

• Amíg alsó<felső és tömb[alsó]>neo ismételd :


• alsó ← alsó +1
• Ciklus vége
• Amíg alsó<felső és tömb[felső]≤neo ismételd :

• felső ← felső −1
• Ciklus vége
• Ha alsó<felső

• akkor Cseréld(tömb[alsó],tömb[felső])
• folytasd a 3. lépéstől
• különben
• Ha a 6=alsó akkor Gyorsrend(a,alsó)
• Ha b 6=felső akkor Gyorsrend(felső,b)
A tényleges gyorsrendezés tehát úgy indítandó, hogy a fenti eljárást a 0,és tömb.length paraméterekkel hívjuk meg.
Megjegyzés. A fenti algoritmus egy nagyon egyszerű, de ritkán hatékony módszert alkalmaz az elemkiválasztásra : a
tömb középső elemének értékét használja.
Az algoritmusban a neo elnevezés a kiválasztott elemre akar utalni. Az elnevezés egy korábbi (2003/2004) évben
érettségizett osztály diákjaitól származik. . .

153
Kupacrendezés
Érdekességként említsünk meg még egy rekurzión alapuló rendező algoritmust, a kupacrendezést.
Ez a rendező algoritmus egy kupac nevű, speciális adatszerkezetet használ, amelynek felépítése után a kupac tetején
mindig a legnagyobb elemt található, amelyet a tömb végére lehet tenni, majd a kupac lineáris időben újraépíthető, és
folytatható az elemeknek a kivétele a rendezendő tömbbe. A kupac előállításának algoritmusát most nem ismertetjük –
bár nem túl bonyolult.
Ez tehát egy szintén n log n nagyságrendű lépésben működő algoritmus (a kupac előállítása minden elem megkeresé-
sekor log n lépést igényel), amely a gyorsrendezéssel ellentétben minden esetben ennyi idő alatt fut le.

154
13. fejezet

Interaktív weboldalak készítése

A továbbiakban a JavaScript azon lehetőségeivel foglalkozunk, amely miatt a JavaScript nyelv egyáltalán létrejött : a
weboldal interaktív elemekkel való ellátásával.
Ennek keretében először bemutatjuk a DOM (Document Object Model) elemeit. Ezután megismerkedünk az esemény-
kezelők fogalmával, és használatukkal.
Az egyik nagy erőssége a JavaScript nyelvnek az űrlapok kezelésével függ össze. Mivel ezt később a PHP nyelvnél
is sokat fogjuk használni, azért a következő fejezet a HTML nyelv űrlap elemeivel, azok megjelenítését szabályozó CSS-
szabályokkal, valamint a JavaScript-ből való elérésükkel foglalkozik majd. Ezek után a képtérképek létrehozásáról lesz
majd szó, végül néhány egyéb trükköt ismerünk meg, amely a JavaScript és a CSS összekapcsolásával valósítható meg.

13.1. A Document Object Model (DOM)


A weboldalon levő egyes dokumentumelemeket a DOM-on keresztül lehet elérni a JavaScript programokban. Ez a DOM,
a Document Object Model egy objektumok hierarchiájából álló rendszer, amely leírja a böngésző, és a benne megjelenített
dokumentum minden elemét.
A DOM-ban minden objektum szülője a window objektum. Amennyiben egyértelmű, hogy melyik böngészőablakról
van szó, akkor ez esetenként elhagyható. Ez valójában a dokumentumot tartalmazó ablakot adja meg. Ebben az ablakban
egy – keretek használata esetén több – dokumentum található. Ezt adja meg a document objektum. Minden, a webolda-
lon levő objektum ebből származik. Például egy image9 címkével rendelkező elemre ezek szerint a JavaScript programban
a következő objektummal hivatkozhatunk:

window.document.image9

A [3]-ban a DOM JavaScript-en belüli elhelyezkedésére szerepel egy ábra a 125. oldalon. Eszerint tehát minden
objektum a window objektumból származik. Ennek három leszármazottja a document, amely leírja az ablakban lát-
ható weboldalt, a history, amely az ablakban meglátogatott oldalak történetét tartalmazza, és a location, amely a
weboldal címét írja le.
A W3C (World Wide Web Consortium) felelős annak a szabványnak a karbantartásáért, amely a DOM különböző
részeit definiálja. A szabvány – a HTML és a CSS szabványához hasonlóan – letölthető a honlapjukról is
(http ://www.w3c.org/).1
1 A későbbiekben e könyv tervezett bővítéseként elképzelhető, hogy a szabványból egyes részletek bekerülnek egy-egy fejezet formájában ebbe a

könyvbe is.

155
13.1.1. A böngészőablakhoz kapcsolódó objektumok
Minden window objektum egy böngészőablakot képvisel. Az objektum többek között a következő tulajdonságokkal és
metódusokkal rendelkezik:
_content Megjeleníti az adott ablak tartalmát.
closed Logikai érték, mely igaz, ha az ablak zárva van.
defaultStatus Az ablak státussorában megjelenő alapértelmezett üzenetet tartalmazza.
frames Egy tömb, amely az ablakban levő kereteket (maguk is window objektumok) tartalmazza.
history Az ablak History objektumára hivatkozik.
length A fentebb említett frames tömb elemszámát tartalmazza.
location Az ablak által tartalmazott Location objektumra hivatkozik.
locationbar Látható-e a „location bar” része az ablaknak ?
menubar Látható-e az ablak menüje?
name Az ablak nevét tartalmazza.
opener Arra a window objektumra hivatkozik, amelynek az open metódusa megnyitotta az ablakot.
status A státussor pillanatnyi tartalma.

statusbar Látható-e a státussor?


alert Figyelmeztető párbeszédablakot hoz létre, amelyben megjelenik a paraméterül adott szöveg.
confirm Igen-nem választ kérő párbeszédablakot jelenít meg a paraméterében megadott szöveggel.
prompt Egy párbeszédablakban megjeleníti a paraméterében szereplő szöveget, majd a beviteli mezőjébe írt szöveget
adja vissza a meghívó kifejezésbe.
A későbbiekben még további tulajdonságok illetve elemek használata is előkerül majd. . .

13.1.2. A dokumentum objektumai


A document objektum – amely a window objektumból származik – az ablakban látható weboldalt írja le. Amennyi-
ben az aktuális ablakban látható dokumentumról van szó, akkor a window.document helyett elegendő a document
használata is.
A document objektum tartalmaz néhány tulajdonságot, amelyek magáról a dokumentumról adnak információt :

• A document.URL megadja a weboldal URL-jét. Nem módosítható. Amennyiben már oldalt akarunk betölteni,
akkor a window.location értékét kell megváltoztatni.
• A document.title a dokumentum <title> elemének tartalmát tartalmazza, vagyis a címsorba kerülő szö-
veget.
• A document.referrer annak a weboldalnak a címét tartalmazza (ha van ilyen), amelyről erre az oldalra érke-
zett a felhasználó egy hivatkozáson keresztül.
• A document.lastModified a dokumentum utolsó módosításának időpontját tartalmazza.

156
• A document.bgColor és document.fgColor a megfelelő színeknek az értékét tartalmazza. Kérdés, hogy
vajon a stíluslapon történő színbeállítást is követi-e vagy csak a már elavultnak számító, <body>-paramétereket. . .
A fenti tulajdonságok egyikét, az utolsó módosítás időpontját tartalmazót használva az oldalon meg lehet jeleníteni,
hogy mikor módosítottuk utoljára – anélkül, hogy ezt minden alkalommal át kelljen írni :
...
<script type="text/javascript">
document.write(document.lastModified);
</script>
</body>
</html>
A fenti programrészletben a document.write függvény – a document objektum metódusa – a weboldalba írja
ki a paraméterében szereplő szöveget.

13.1.3. A meglátogatott oldalak története


A history objektum segítségével elérhetjük az ablak történetét. Az objektum tulajdonságai és metódusai :
length Az előzménylista elemeinek számát tartalmazza.
go A paraméterében megadott egész szám által meghatározott elemet keresi ki az előzménylistából, és az ahhoz tartozó
oldalt tölti be annak URL-je alapján. Negatív szám a visszafelé lépegetést, pozitív szám az előre lépegetést jelenti.
back megfelel a Vissza gombra kattintásnak: az előzménylistában az aktuális dokumentum előtti oldalt tölti be.
forward megfelel az Előre gombra kattintásnak: az előzménylistában az aktuális dokumentum utáni oldalt tölti be (ha
van ilyen).

13.1.4. Location
A location objektum is a window objektum gyermeke, akárcsak a document és a history. Az egyes tulajdonságai
az ablakban levő dokumentum címének egyes részeit írják le :
protocol Az URL protokolját tartalmazza. (Általában „http”)
hostname A gép nevét tartalmazza.
port A gépen a portszámot, amelyre a kérés irányult.
pathname Az dokumentumnak a gépen belüli elérési útvonalát tartalmazza.
search Az URL lekérdezési részét tartalmazza. A lekérdezési résszel majd a PHP-nál fogunk foglalkozni.
hash Az URL-nek a # jel utáni részét tartalmazza, amely az oldalon belüli azonosítót ad meg.
A location objektum két metódussal is rendelkezik :
• A location.reload() metódus újratölti az aktuális dokumentumot az ablakban.
• A location.replace() metódus a paraméterében szereplő URL által megadott dokumentumot tölti be az
ablakba. Az így betöltött dokumentumról azonban nem lehet a Vissza gombbal visszalépni az előző oldalra.

157
13.2. Események és eseménykezelők
Egy weboldalon amikor azt valaki olvassa, bekövetkezhetnek bizonyos események. Ilyen esemény például, ha az olvasó
rákattint egy gombra vagy egy hivatkozásra, ha az egérmutatót egy adott terület fölé viszi,2 vagy amikor az oldal be-
töltése befejeződött. Ezen események alkalmasak arra, hogy egy-egy JavaScript utasítást – akár függvényhívással egész
függvényt – hajtassunk végre az esemény bekövetkezésekor. Tulajdonképpen ettől válhat egy weboldal interaktívvá.
Az egyes események bekövetkezéséhez rendelhető programrészletek tulajdonképpen az eseménykezelők. Ezek akkor
hajtódnak végre, ha az esemény, amelyhez hozzá vannak rendelve, bekövetkezik.
Az egyes weboldali objektumoknak fajtájuk szerint különböző típusú eseménykezelőik lehetnek. A legtipikusabb
események, amelyekhez eseménykezelő rendelhető, a következők :
onMouseOver Az elem fölé került az egérmutató.

onMouseOut Az egérmutató elhagyta az elem területét.


onMouseMove Az egérmutatót elmozdították. Az Event objektum tulajdonságai közül a clientX és a clientY megadja az
egérmutató koordinátáit.

onClick Az elemen kattintott a felhasználó az egérrel.


onDblClick Az elemen duplán kattintott a felhasználó az egérrel.
onMouseDown Az egér gombját lenyomták az elem területén.
onMouseUp Az egér gombját elengedték az elem területén. Ennél és az előző három eseménynél az event objektum
which vagy a button – böngészőtől is függ sajnos – tulajdonsága adja meg, hogy melyik gombbal következett be az
esemény :
1. Az 1 érték esetén a bal gomb;
2. A 2 érték esetén a középső gomb;
3. A 3 érték esetén pedig a jobb gomb volt az „áldozat”.
Mindezeken kívül még az event objektum rendelkezik néhány olyan tulajdonsággal,
 amely tárolja, hogy a legutol-
jára bekövetkezett esemény során le volt-e nyomva az Alt (altkey), a Ctrl (ctrlkey) vagy a Shift (shiftkey)
billentyű. Ha igen, akkor a megfelelő tulajdonság értéke igaz értékű lesz, különben hamis.

13.2.1. Az eseménykezelők létrehozása


Az eseménykezelő tehát egy-egy elemmel van kapcsolatban, ezért logikusnak tűnik, hogy a megadása is valahol az elem
megadásába kerüljön. Így is van: a HTML-elem nyitótagjában kell elhelyezni mint az elem paraméterét, ahol a paraméter
neve a fenti – vagy az ott nem szereplő, mert nem minden elemnél létező – eseménynév, a paraméter értéke pedig az
esemény bekövetkezésekor végrehajtandó programkód.
Itt azonban felmerül néhány kérdés. Először is honnan tudja a böngésző, hogy a végrehajtandó programkód melyik
lehetséges nyelven van megadva? Másodszor pedig mi van akkor, ha a programkódban is kellene idézőjeleket használni ?
Az első kérdésre a válasz egyszerű: a weboldal HEAD elemén belül elhelyezkedő META elemek egyikével megadható
az alapértelmezett programnyelv, JavaScript esetén a következőképpen :
<meta http-equiv="Content-Script-Type" content="text/javascript">
2 Egy adott terület fölé vitt egérmutató hatására bizonyos változásokat a CSS nyelvű stílusdefiníciókkal is be lehet állítani, gondoljunk csak a:hover

pszeudoosztályra, vagy az :active-ra, amely akkor érvényes, ha az olvasó valamilyen elemre rákattint.

158
A második kérdés az egyik ok, ami miatt mind az egyszeres, mind a kétszeres idézőjelet lehet használni a HTML
elemek paraméterei értékének megadásához és a JavaScript-beli szövegek megadásához egyaránt. Így akár egyszeres
akár kétszeres idézőjeleket használunk az eseménykezelő kódjának bezárásánál, a másik idézőjelfajtát használhatjuk a
kódon belüli karaktersorozatok megadására.
Például a következő HTML részlet egy hivatkozást ad meg, amelynél ha az egeret a hivatkozás szövege fölé visszük,
akkor a böngésző állapotsorában megjelenik egy magyarázó szöveg a hivatkozásról :

<a href="http://www.valahol.com/valami.html"
onMouseOver="window.status=’Ez a hivatkozás valahova mutat...’;"
>Kattints rám!</a>

13.2.2. Eseménykezelők módosítása


Arra is van lehetőség, hogy elemtől függetlenül egy esemény kezelésére beállítsunk egy függvényt. Ezzel a lehetőséggel
akár menet közben is megváltoztathatjuk egyes események működését azzal, hogy lecseréljük a rájuk reagáló függvényt.
Az alábbi, a [3]-ból vett példa a mousealert függvényt rendeli az onMouseDown eseményhez, előírva a függvény
végrehajtását, ha lenyomják az egér valamelyik gombját :

function mousealert() {
alert("Kattintottál az egérrel");
}
document.onMouseDown = mousealert;

(Mint látható, a függvény hozzárendelése során a függvénynek csupán az azonosítója szerepel. Ha a zárójeleket is
megadnánk, akkor az a függvény azonnali meghívását jelenteni, amely esetben a függvény – jelenleg nem is létező –
visszatérési értéke lenne átadva értékül az eseménykezelőnek.)

13.2.3. Billentyűzet-események
A JavaScript 1.2-es verziója óta van lehetőség arra, hogy egy weboldal a billentyűzet eseményeit elérje. Az onKeyPress
esemény akkor következik be, ha a felhasználó lenyom egy billentyűt, majd el is engedi azt. Csak a lenyomást a onKeyDown,
csak a felengedését a onKeyUp eseményen keresztül figyelhetjük.
Azt, hogy melyik billentyűt nyomta le a felhasználó, az event objektum megfelelő tulajdonságain keresztül tudthatjuk
meg. A Netscape – és valószínűleg a Mozilla, Galeon is ezt használja – esetén az event.which tulajdonság, míg MS-IE
esetén a event.keyCode tulajdonság tartalmazza a lenyomott billentyű kódját.3
Hasznos lehet ezeknek a karakterkódoknak a szöveggé visszaalakítására a String objektum fromCharCode metó-
dusa :

Key = String.fromCharCode(event.which);

13.2.4. További események


Az onLoad esemény akkor következik be, amikor az oldal teljesen betöltődött. Amennyiben valamely műveletet akkor
akarunk végrehajtani, ha az oldal már teljesen megjelent a böngészőben, azt adhatjuk meg a BODY elemben ezzel az
eseménykezelővel.
Az onUnload esemény ellenben akkor következik be, ha az ablakot, amelyben a weboldal látható, a felhasználó
bezárja, vagy ha egy másik oldal betöltése kezdődik az ablakba.
Az egyes eseménykezelők elérhetők a window objektum tulajdonságaiként is, amikor a fentebb (13.2.2 szakaszban)
említett módon lehet az eseményhez egy függvényt rendelni. Ilyen módon használhatók a következő események :
3 Az MS még ebben is külön utakon jár. Vigyázni kell a kódolással is : saját tapasztalat, hogy a Galeon például a prompt függvény által bekért

adatokat másképpen (UTF) kódolja, mint a Mozilla (iso-8859), ami sokszor problémákat okozhat, és az event-nél is felléphet hasonló gond. . . !

159
window.onblur az ablak elveszti a beviteli fókuszt.
window.ondragdrop a felhasználó egy objektumra vagy az ablak egy objektumára használja a rendszer drag-and-drop
műveletét.
window.onerror JavaScript hiba lépett fel. Hibakezelő írására alkalmas.
window.onfocus Az ablakhoz kerül a beviteli fókusz.
window.onload A weboldal betöltődött.
window.onmove A felhasználó mozgatja az ablakot (nem azonos tehát az egér mozgatással).
window.onresize Az ablakot átméretezték.
window.onunload A weboldal helyett új weboldal letöltése kezdődött, vagy az ablakot bezárják.

13.3. Ablakok kezelése JavaScript-tel


Biztosan mindenki talákozott már olyan weboldalakkal, amelyek megnyitásakor egy vagy több újabb ablak ugrott elő.
Ezek a legtöbbször idegesítőek, de néha ilyenek készítése is hasznos lehet. A másik hasznos dolog, amit a JavaScript se-
gítségével könnyedén megvalósíthatunk, hogy egyetlen hivatkozásra kattintva több része is megváltozzon egy keretekből
álló dokumentumnak. A következőkben ezek megvalósításáról lesz szó.
Maga a window azonosító, az éppen aktuális böngészőablakot jelenti. Ennek az objektumnak minden tulajdonsága
tehát ennek az ablaknak az adatait írja le. A metódusai pedig ennek az ablaknak a műveletei.

13.3.1. Ablak nyitása és bezárása


Egy új ablak nyitása az open metódussal történik:
window.open(url,nev,tulajdonsagok, csere);
A metódus egy Window típusú objektumot ad vissza, amely a megnyitott ablakot írja le. A paraméterek jelentése a követ-
kező :

url Az újonnan nyitott ablakba betöltendő weboldal címe. Ha ezt a paramétert üresen hagyjuk, a megnyíló ablak üres
lesz.
nev Az új ablak neve, amely megfelel az A HTML-elem name paraméterének, amellyel tehát a későbbiekben az ablak
egyedi azonosítása lehetséges lesz.

tulajdonsagok A megnyitandó ablak tulajdonságai, amelyek általában igaz vagy hamis értékűek lehetnek. Ha csak a
tulajdonság nevét adjuk meg, akkor bekapcsoljuk azt. Egyéb esetben a tulajdonságnév = érték formát kell használ-
nunk. Az egyes tulajdonságokat egymástól vesszővel kell elválasztani, és az egész tulajdonságlistát idézőjelek közé
kell tenni. A megadható tulajdonságok a következők :
alwaysLowered : Az új ablak az összes többi ablak mögé kerüljön.
alwaysRaised : Az ablak az összes többi ablak elé kerüljön. Ez és az előző tulajdonság inkább csak az olvasó
kiborítására, és az olvasó előli tevékenységek eltitkolására alkalmas.
channelmoda: Megadja, hogy az ablak channel-módban jelenjen-e meg (ennek jelentése ismeretlen. . . )4
4 Ha bárki meg tudja pontosan magyarázni, hogy egy ebben a könyvben ismeretlen jelentésűnek nevezett fogalom mit jelent, az tudassa a szerzővel

a rendelkezésére álló információt. . . !

160
dependent : Az új ablak leszármazottja legyen-e az aktuálisnak.
directories: A „könyvtár” gombok (What’s new, What’s cool, MandrakeStore stb.) megjelenjenek-e.
fullscreen : Az ablakot a böngésző teljes képernyős módba kapcsolva jelenítse-e meg.
height : Az ablak pixelben (képpontban) mért magasságát állítja be. Konkrét méretű ablakok létrehozására hasznos.
width : Az ablak pixelben (képpontban) mért szélességét állítja be.
hotkeys : Letiltja vagy engedélyezi a billentyűkombinációk használatát az ablakban.
innerHeight, innerWidth: A dokumentumot megjelenítő terület magasságát és szélességét adja meg, pixelben
mérve.
left, top : Az ablak bal felső sarkának x illetve y koordinátáját adja meg.
screenX, screenY: Ugyanaz, mint a left és a top, de míg azok IE-ben használhatók, ezek a NetScape 4.0-tól kezdve
használhatóak.5
location : Látszódjék-e az URL-t mutató sor ?
menubar : Látszódjék-e a menü sora?
outerHeight, outerWidth: Az ablak teljes magassága illetve szélessége pixelben (Netscape specifikus).
resizable : Átméretezhető-e az ablak?
status : Látszódjék-e az állapotsor?
toolbar : Látszódjék-e az eszköztár? (Ezen vannak a vissza és előre gombok is !)
z-lock : Netscape használata esetén ezzel le lehet tiltani az ablaknak a többi ablakhoz képesti előre ill. hátra moz-
gatását.
A fenti értékek közül azokat, amelyeket nem sorolunk fel, a böngésző valamilyen alapértelmezett értékkel fogja
figyelembe venni. (A [4]-ben található a window objektum néhány olyan tulajdonsága és metódusa még, amelyekkel
ezek az értékek lekérdezhetők, esetleg be is állíthatóak.)
csere Amennyiben true (igaz) az értéke, akkor az ablak előzmény-listája törlődik új dokumentum betöltése esetén, azaz
nem lehet visszalépni az előző dokumentumra.

Az ablak bezárása a close metódussal lehetséges :


window.close();
Például ha majd a későbbiekben egy több lépéses adatbakérést szeretnénk megvalósítani, akkor ott az esetleges vissza-
lépéseket megakadályozhatjuk, ha az első űrlapot tartalmazó oldalt egy önálló ablakban nyitjuk meg például a következő
utasítással :
adatBeker = window.open(’bevitel1.html’,’input’,
’toolbar=0,status=0,location=0,directories=0,resizable=0’,true);
Ez a parancs ráadásul eltünteti a fölösleges sallangokat (URL-sor, eszköztár, állapotsor, reklámkönyvtárak), és letiltja
az oldal átméretezését is.
Ha tudjuk, hogy az adatbekérés végén egy teljesen haszontalan done.html oldalra kerül ez az ablak, akkor ennek
segítségével akár az ablak eltüntetéséről is gondoskodhatunk :
while (adatBeker.location != ’done.html’) {
// várunk, amíg az adatbekérés és feldolgozás tart...
}
adatBeker.close(); // bezárjuk az ablakot
5 Mind a Mozilla, mind a Galeon, mind pedig a Konqueror Netscape-szabályokat követő böngésző (a Mozilla a Netscape nyílt kódú változata). . .

161
13.3.2. Ablak mozgatása és átméretezése
A moveTo és a moveBy metódusok az ablak bal-felső sarkát, az ablak referenciapontját változtatják meg, míg a resizeTo
és a resizeBy metódusok a méretét. Mind a négy metódus egy (x,y) koordinátát vár paraméterként, „mindössze” abban
van különböznek, hogy azt miként értelmezik.
A két . . . To metódus a megfelelő értéket a megadott paraméterre állítja, míg a két . . . By a megfelelő értékhez hozzáadja
a megadott paramétert.
Tehát :
• A window.moveTo metódus a paraméterben megadott koordinátákra állítja be az ablak referenciapontját (left és
top).
• A window.moveBy metódus a paraméterben megadott x és y értékekkel eltolja az ablakot a referenciapont koordi-
nátáihoz a paraméterek értékét megadva.
• A window.resizeTo metódus a width és height értékeit az ablaknak a megadott első illetve második paraméter-
ben szereplő értékre állítja, ezzel a paraméterben megadott értékűre állítja az ablak méreteit.
• A window.resizeBy metódus a width és height értékeihez adja a paraméterben szereplő első illetve második
koordináta-értéket, azaz a megadott paraméterekkel megnöveli az ablak aktuális szélességét ill. magasságát (negatív
értékre csökkenti azt).

13.3.3. Párbeszédablakok megjelenítése


Talán már hamarabb kellett volna említeni, de mivel a window objektum metódusai, térjünk most ki arra a három metó-
dusra, amellyel egyszerű párbeszédablakok jeleníthetőek meg.
Egyszerű üzenet megjelenítésére alkalmas az alert metódus, amely a paraméterében szereplő szöveget és egy „Ok”
feliratú gombot tartalmazó párbeszédablakot nyit. A programfutás felfüggesztődik addig, amíg az „Ok” gombbal vagy
más módon a párbeszédablak el nem tűnik.
Egy eldöntendő (igen-nem) kérdést lehet intézni a felhasználóhoz a confirm metódussal. Ez a paraméterében megadott
szöveget jeleníti meg egy párbeszédablakban két gombbal : egy „Ok” és egy „Mégsem” gombbal. Előbbire kattintva a
metódus igaz értéket, utóbbira kattintva vagy az ablakot más módon bezárva a metódus hamis értéket ad eredményül az
őt hívó kifejezésnek.
Szöveg bekérésére alkalmas a prompt metódus, amely a paraméterében megadott szöveget, alatta egy beviteli mezőt,
és az alatt egy „Ok” gombot tartalmazó párbeszédablakot hoz létre. Ha nem az „Ok” gombbal zárjuk be az ablakot, akkor
üres sztringet ad vissza, míg az „Ok” gombra kattintva a beviteli mező aktuális tartalmát adja vissza.

13.3.4. Keretek kezelése JavaScript-ben


A window objektum rendelkezik egy parent tulajdonsággal, amely tartalmazza az aktuális keret vagy ablak létrehozóját.
Az open metódussal létrehozott ablak esetében hasonló funkciójú az opener tulajdonság.
A frames tulajdonság pedig egy tömb, amely az ablakba ágyazott kereteket tartalmazza a 0. indextől kezdve olyan
sorrendben, ahogyan azok a HTML kódban definiálásra kerültek (fentről lefele, soronként balról jobbra haladva).
A parent és a frames tulajdonságok segítségével az egyes keretek egymás objektumaihoz is hozzáférhetnek. Ezenkívül
ha a FRAME elemben szerepel a name paraméter, akkor az ott megadott névvel a megfelelő keret szintén elérhető : Ha
például az alábbi HTML kódot adjuk meg a kereket definiálására:
<frameset rows="*,*">
<frame name="fent" src="fent.html">
<frame name="lent" src="alul.html">
</frameset>
Akkor a felül megjelenő keretben akár a

162
parent.frames[1]
kifejezés, akár a
parent.lent

kifejezés egyaránt az alsó keretet fogja jelenteni, amely egy window típusú objektum lesz.

13.3.5. Időzített tevékenységek


Időnként előfordul, hogy bizonyos tevékenységet nem azonnal szeretnénk végrehajtani. Ilyen lehet például egy documen-
tumelem időnkénti újragenerálása – például egy futó óra készítése céljából.
Korábban már láthattuk az állapotsorba történő futó felirat készítésénél ennek módját, de mert ez is a window objek-
tumhoz kapcsolódik, most ismételjük meg ezt itt újra !
A window.serTimeout metódus az első paraméterében szövegként megadott JavaScript utasítás(oka)t a második para-
méterben – ezredmásodpercben – megadott késleltetés után hajtja végre.
A window.setInterval metódus az első paraméterében szövegként megadott programrészletet, vagy – másik változat-
ként – függvényt a második paraméterében – szintén ezredmásodpercben – megadott időközönként újra és újra végrehajt-
ja. A függvényes változatban harmadik paraméterként megadhatók a függvénynek paraméterek is.
Amennyiben a késleltetést úgy adjuk meg, hogy a setTimeout által visszaadott azonosítót tároljuk egy változóban,
akkor lehetőségünk van a késleltetést törölni a clearTimeout metódusnak ezt az azonosítót megadva. Ekkor ha még nem
telt le a beállított idő, akkor az előírt művelet végrehajtása törölhető.
Mivel késleltetett végrehajtás megadható függvényen belül is, így lehetőség van késleltetett rekurzióval bizonyos te-
vékenység ismételt végrehajtására. Ilyen a változó státussor előállítása vagy az óra kijelzése is. Mindkettő esetében a
függvény belsejében beállításra kerül egy késleltetett függvényhívás, amelynek hatására bizonyos időközönként a függ-
vény újra végrehajtódik.
Másik felhasználási lehetőség, ha valamit az oldal teljes betöltése után egy meghatározott idővel szeretnénk végre-
hajtani. Például több oldalból álló sorozat időzített betöltése oldható meg, ha a BODY elem onLoad eseménykezelőjében
definiálunk egy értékadást a window.location számára a következő oldal címével. Ekkor ha az oldal teljesen betöltődött,
elkezdődik a visszaszámlálás a következő oldal betöltéséig.

13.4. HTML elem beazonosítása


Hogyan is találhatunk meg egy HTML elemet, amikor szeretnénk a tulajdonságaihoz hozzáférni ? Ehhez először az elmé-
leti háttérrel, azaz a DOM-mal kell egy kicsit megismerkedni.

13.4.1. A DOM: Document Object Model


Korábban már említettük, hogy van egy modell, amely leírja a dokumentum tartalmát. Ezt a struktúrális felépítést a HTML
nyelv is használja. A JavaScript számára a dokumentum minden eleme egy-egy objektumként érhető el, amely tulajdon-
ságai az elem tulajdonságai. Ezért itt a szerkezetet leíró modellt DOM-nak, azaz Dokumentum-Objektum Modellnek
(Document Object Model) hívják.
Aki weboldal készítésére például a Quanta-t használja, az már találkozhatott ezzel a struktúrával, amely valójában
az elemek egymásba ágyazását mutatja faszerkezetként. Ehhez a DOM esetében annyit kell még hozzá tenni, hogy a
document objektum tartalmazza az egészet. Ennek egy tulajdonsága a html objektum, amely valójában a HTML elemnek
felel meg (ez tartalmazza az összes többi HTML elemet).
A [3]-ból átvett példán látható mindez. Az alábbi egyszerű weboldal DOM-ábrázolása a 13.1 ábrán látható.

163
<html>
<head>
<title>Egy egyszerű HTML dokumentum</title>
</head>
<body>
<h1>Ez egy címsor</h1>
<p>Ez egy bekezdés</p>
</body>
</html>

document

html
 H
 HH
 H
 HH
 H
head body
 HH
 H
title h1 p

„Egy egyszerű HTML „Ez egy címsor” „Ez egy


dokumentum” bekezdés”

13.1. ábra. Példa a DOM-ábrázolásra

A 13.1 ábrán látható faszerkezetben a téglalapokkal jelölt objektumokat csomópontnak nevezzük. Ezek lehetnek belső
csomópontok és levelek.
A JavaScript-ben gyakorlatilag mindig ezeket a csomópontokat kell tudni elérni valamilyen formában. Lehetőség
van arra is, hogy a gyökértől kezdve végigjárjuk a fát a keresett csomópontig, de arra is, hogy valamilyen azonosító
segítségével közvetlenül próbáljuk megtalálni. A későbbiekben mindkettőre látunk majd példát.
Mint az ábrán is látható, az egyes elemek tartalma a fában mint az elemet jelentő csomópont gyermeke jelenik meg.
Abban az esetben, ha egy elem tartalma pusztán valamilyen szöveg, akkor az a szöveg lesz a csomópont, mint levél.
Ebben az esetben azonosítóval nem lehet elérni, de még így is könnyen hozzá lehet férni – akár módosítani is lehet.

13.4.2. Az egyes csomópontok elérése


A következőkben megnézzük, hogyan lehet az egyes csomópontokhoz hozzáférni, illetve a csomópontot leíró objektum
tulajdonságait is röviden ismertetjük.
A csomópontot leíró objektum három számunkra ezen a ponton fontos tulajdonsága :
nodeName a csomópont neve, azaz az elem neve (pl. body). A szöveget leíró objektumok esetében #text az értéke.

nodeType egy egész szám, amely a csomópont típusát adja meg :


• 1 : normál HTML elemek esetén;
• 3 : szöveges csomópontoknál;

164
• 9 : dokumentum-csomópontoknál.
nodeValue a szöveges csomópont tényleges szövege (módosítható).
innerHTML egy tetszőleges csomópont HTML tartalma. Ennek a tulajdonságnak akár új csomópontot leíró objektumot
is értékül adhatunk, így dinamikusan módosítva a weboldal szerkezetét. Ennek módját alább ismertetjük.
firstChild a csomópont első gyermekét tartalmazza objektumként. Azoknál a HTML elemeknél, ahol csak szöveg az
elem tartalma, ez a tulajdonság tartalmazza azt a levelet, amely az elem tartalmát alkotó szöveget írja le.
lastChild a csomópont utolsó gyermekét tartalmazza, mint objektumot.
childNodes a gyermek-objektumokat tartalmazó tömb. Nulladik eleme értelemszerűen a firstChild objektummal
egyezik meg.
previousSibling a csomópont előző testvére/szomszédja.6
nextSibling a csomópont következő testvére.
Aki a fenti felsorolást figyelmesen elolvasta, az egy módszert már találhat egy adott HTML elem megkereséséhez :
induljunk el a document objektumtól és a childNodes tömbökön haladjunk végig a megfelelő indexeket használva.
Persze az így kapott változómegadások nem igazán használhatóak a hosszú
....childNodes[3].childNodes[1].firstChild.firstChild.childNodes[2]...
kód miatt.
Helyette hasznosabb, ha egyedi azonosítóval látjuk el a később elérni kívánt elemeket, mert akkor használható a
getElementById függvény az elérésükhöz. Ez a függvény egy objektumot ad vissza, amely valójában az a csomópont,
amelyhez a paraméterében megadott azonosítójú HTML elem tartozik.
Ha nem adunk egyedi azonosítót (id) az elemnek, akkor az elem nevével érhetjük el a getElementByTagName függ-
vény segítségével. Ez egy tömböt ad vissza, amelyben előfordulásuk sorrendjében szerepel az összes olyan elem, amely
a megadott névvel szerepel a dokumentumban.
A createTextNode függvény egy új csomópontot leíró objektumot hoz létre, ami szöveges objektumként a paraméte-
rében megadott szöveget tartalmazza.
Hasonlóan a createElement egy új HTML elemet hoz létre. Mindkettőt később hozzá lehet adni a dokumentumhoz a
megfelelő csomópont innerHTML tulajdonsága segítségével.
Ebben segítenek még a következő metódusok, amelyek az éppen módosítandó csomópont objektumaként érhetőek el :
appendChild a paraméterében megadott új csomópontot elhelyezi ez eddigi gyermekek után új gyermekként.
insertBefore az első paraméterében megadott új csomópontot elhelyezi a második paraméterében megadott régi gyer-
meke elé új gyermekként.
replaceChild az első paraméterében megadott új csomópontra cseréli a második paraméterében megadott régi gyerme-
két.
removeChild a paraméterében megadott régi gyermeket törli.
hasChildNodes egy logikai értéket ad: igazat, ha az objektumnak vannak gyermekei, hamisat, ha nincsenek.
cloneNode egy új csomópontot hoz létre, amely pontos másolata az aktuális csomópontnak. Amennyiben a paraméter
nélkül is hívható eljárást a true paraméterrel hívjuk meg, akkor a csomópontot mint részfát másolja, azaz a
gyermekeit is másolja.
A fenti felsorolásban az „új” mindenhol azt jelenti – az utolsó metódust kivéve –, hogy a createTextNode, a createEle-
ment, vagy az utolsó metódus segítségével létrehozott csomópontot kell megadni. A „régi” szó jelentése : a faszerkezetnek
pillanatnyilag eleme az adott csomópont.
6A faszerkezetek esetében testvérnek azokat a csomópontokat nevezik, amelyek ugyanannak a csomópontnak a gyermekei.

165
13.5. Stílus módosítása JavaScript-ben
Talán nem meglepő, hogy a JavaScript akár a formázást leíró stílusdefiníció megváltoztatására is alkalmas. Ehhez nem
kell mást tenni, mint a megfelelő elem style tulajdonságát, amely maga is egy objektum, elővenni. Természetesen ehhez
először valahogyan meg kell találnunk azt az adott elemet. Erre alkalmas a 13.4 szakaszban ismertetett getElementById
függvény. Ehhez tehát használni kell az elemnél az id paramétert.
Mindezek ismeretében már nem nehéz a dolgunk : Minden egyes DOM-csúcspontot leíró objektumnak van egy style
tulajdonsága, amely maga is egy objektum. Ennek az objektumnak pontosan azok a tulajdonságai vannak – ugyanazzal a
névvel – amellyel az adott csúcspont által megadott HTML elem rendelkezik a CSS szabvány szerint.
Így például ha egy EM elem objektumát kapta értékül a node változó, akkor a node.style objektum ennek
tulajdonságait adja meg. A színét pedig a JavaScript kódban bármikor kékre változtathatjuk ennek az elemnek a
node.style.color = "blue";
vagy a
node.style.color = "rgb(100%, 0%, 0%)";
utasítással.
Kicsit mélyebb programozói tudással rendelkezők számára talán nem túl meglepő a következő – szintén a [3]-ból
átvett – példában szereplő megoldás. Tegyük fel, hogy van egy H1 elemünk, amelynek a színét szeretnénk egy bizonyos
felhasználói akció esetén megváltoztatni. A megoldás egyszerű : a H1 elemnek adjunk egyedi azonosítót :
<h1 id="head1">Ez egy színváltó címsor</h1>
Ezután az elemet elérhetjük a getElementById függvénnyel :
elem = document.getElementById("head1");
A fenti függvény megkeresi a head1 azonosítójú elemhez tartozó objektumot, és azt adja vissza. Ezután az elem változón
keresztül az elem tulajdonságai megváltoztathatóak.
Azonban ha csak egy tulajdonság megváltoztatása a cél, akkor a változó használata megspórolható a már említett,
mélyebb programozói gyakorlat esetén természetesnek tűnő, ugyanakkor felületes programozói ismeretekkel rendelkezők
számára talán meglepő megoldással: használjuk a kívánt objektum meghatározására közvetlenül a függvény visszatérési
értékét.7

document.getElementById("head1").style.color="blue";

A fenti módszerrel történő tulajdonság-módosítás több hasznos célra is felhasználható. Az egyik lehetőség, hogy a
display tulajdonság segítségével dinamikusan ki/be kapcsolhatjuk bizonyos elemek megjelenését a weboldalon. Másik
lehetőség – inkább csak játszadozásnak tűnhet – a [3] példája, ahol a felhasználó maga választhatja ki a weboldal megje-
lenítésére használt színeket. A példát itt most nem ismételjük meg, de a mellékletben a tényleges weboldal megtalálható
(color.html).

Megjegyzés. A weboldal forráskódját ha megnézzük, akkor látható példa arra is, hogy hogyan kell megadni azokat a
tulajdonságokat, amelyekben a CSS szabvány szerint kötőjelnek kell szerepelnie : a kötőjelet elhagyjuk, és a kötőjel utáni
betűt nagybetűvel írjuk. Így lett a background-color tulajdonságban a JavaScript kódban backgroundColor. . .
További hasznos lehetőség, amit a stíluslapok alkalmazása tesz lehetővé, a weboldal elemeinek mozgatása lehet. Erről
a következő szakasz szól részletesebben.
7 A C/C++ programozói gyakorlatban az ilyen megoldások nagyon elterjedtek. Ennek nem csak az az oka, hogy kevesebbet kell így gépelni, hanem az

is, hogy tömörebb, gyorsabban végrehajtásra kerülő kódokat lehet létrehozni az ilyen trükkök alkalmazásával. Hátránya a módszernek, hogy a program
forráskódja kevésbé olvashatóvá válik ezáltal.

166
13.5.1. Elemek helyzetének és méretének befolyásolása
Mielőtt az elemek helyzetének meghatározásáról ejtenénk szót, idézzük fel a SPAN és a DIV elemekről tanultakat ! Ez
a két elem szövegbeli illetve blokk objektumok létrehozására alkalmas, amelyhez azután önálló tulajdonságokat lehet
megadni. Ezzel a módszerrel lehet a weboldal egyes elemeit egy együtt mozgatható csoportba foglalni – az úsztatás is
ennek egy módja volt.
A CSS segítségével az egyes elemeket négyféleképpen lehet elhelyezni :
1. Normál pozícionálás esetén a szokásos módon, egymás után balról jobbra és fentről lefelé kerülnek az objektumok
elhelyezésre.
2. Úsztatás esetén az úsztatott objektum a megadott oldalra csúszik, és a normál megjelenítésű szöveg körbefolyik
mellette (lásd ?? Úsztatás, ??. oldal).
3. Relatív pozícionálás esetén egy másik objektum helyzetéhez viszonyítva rögzíthető az objektum helyzete.
4. Abszolút pozícionálás esetén a weboldalon belül pontosan meghatározható a megjelenése az objektumnak.

A position tulajdonság A position tulajdonság az elem pozícionálási módját határozza meg. Lehetséges értékei a
következők :
static érték esetén az objektum a normál pozícionálás szabályai szerint jelenik meg. Ez az alapértelmezett érték. Ilyen-
kor a pozíciót megadó tulajdonságok nincsenek figyelembe véve a megjelenítés során.
relative érték esetén az objektum helyzete először a normál pozícionálás szabályai alapján kerül kiszámításra, majd a
pozíciót megadó tulajdonságok által megadott értékkel eltolásra kerül. Ez azt jelenti tehát, hogy a környezetéhez
képest relatív pozíció adható meg a lentebb ismertetett tulajdonságokkal.
absolute érték esetén az objektum többé nem része a normál pozícionálásnak. A pozíciót megadó tulajdonságok értéke
alapján az elemet tartalmazó dobozhoz képest fix pozíció kerül beállításra. Az így elhelyezett doboz margói nem
olvadnak össze egyetlen más doboz margóival sem.

fixed érték esetén az előzőhöz hasonlóan viselkedik az objektum doboza, azonban a pozíció a megjelenítő ablakhoz
képest állítható be, és a dokumentum gördítése esetén is a helyén marad az objektum, mintha egy üveglapon
a dokumentum elé helyezték volna. Nyomtatás esetén (tehát a lapokra bontott megjelenítésnél) az objektum
minden lapon ugyanazon a helyen jelenik meg. Ez tökéletes megoldás lehet például több oldalas, fejléces körlevél
nyomtatására.

167
Helyzetmegadó tulajdonságok Amennyiben a position tulajdonság nem static értékkel rendelkezik, a top,
bottom, left és right tulajdonságok segítségével lehet megadni az elem helyzetét.
Mind a négy tulajdonság ugyanazokat az értékeket kaphatja : távolság megadására alkalmas értékeket, melyek lehetnek
• abszolút távolságok: valamely távolság mértékegység használatával vagy annak hiányában képpontban megadva;
• relatív távolságok: százalékban megadva mely esetben az elemet tartalmazó doboz magasságához – a right és
a left esetén szélességéhez – relatív értékekként értelmezi a böngésző őket.
A top tulajdonság azt adja meg, hogy a referencia objektum tetejétől – hogy ez mi, azt a position tulajdonság dönti
el – milyen messze van az objektum tartalom-dobozának felső éle.
A right tulajdonság azt adja meg, hogy a referencia objektum jobboldalától milyen messze van az objektum tarta-
lom-dobozának jobboldali éle.
A bottom tulajdonság azt adja meg, hogy a referencia objektum aljától milyen messze van az objektum tartalom-do-
bozának alja.
A left tulajdonság azt adja meg, hogy a referencia objektum baloldalától milyen messze van az objektum tartalom-
dobozának baloldala.
Amennyiben a doboz relatív pozícionálást kapott, akkor a normál pozícionálás esetén ahova a doboz kerülne, az a
referencia objektum. Abszolút pozícionálás esetén az elemet tartalmazó elem doboza a referencia objektum, míg fix
pozícionálás esetén a weboldalt megjelenítő ablak a referencia objektum.

Az abszolút pozícionálás működése Abszolút pozícionálás – beleértve a fixed érték használatát is – esetén a doboz és
tartalma többé nem része a normál pozícionálás során alkalmazott megjelenítési szabályoknak. Ez azt is jelenti, hogy
a forráskódban utána szereplő HTML elemek úgy kerülnek megjelenítésre, mintha ez az elem nem is létezne, sem a
benne levő többi elem.
Egy abszolút pozícióval rendelkező elem egy teljesen új tartalmazó dobozt hoz létre a leszármazottai számára, amely
leszármazott elemek megjelenése ezen a tartalmazó dobozon belül a normál pozícionálás szabályai szerint történik.
Azonban ezek az elemek nem fogják körbefolyni az útjukba kerülő esetleges úsztatott objektumokat, hanem átfedésbe
kerülnek vele. Hogy ebben a helyzetben melyik objektum fog látszani, az a lentebb ismertetendő tulajdonságokkal
befolyásolható.

Fix pozícionálás esetén teljesen mindegy, hogy az elem melyik elemen belül szerepel, mert a tartalmazó doboz he-
lyett referencia objektumnak a megjelenítő ablak számít. A másik különbség, hogy az absolute értékkel pozícionált
elem az oldal görgetésekor elmozdul a többi elemmel együtt, míg a fixed értékkel pozícionált elem az ablaknak
mindig ugyanazon a pontján marad.
Lapokra bomló megjelenítés esetén – például nyomtatásnál – a fixed elemek minden lap azonos pozícióján megis-
métlődnek, az absolute elemek nem.

13.5.2. Az objektumok átfedésének szabályozása


A fentebb említett átfedés lehetővé teszi különleges effektusok létrehozását. Ezek közül egyre a későbbiekben még lá-
tunk példát, amikor az összegyűjtött ismeretek segítségével egy folyamatosan felfelé gördülő szöveget tartalmazó dobozt
hozunk létre egy weboldalon.
Ehhez szükség lesz arra, hogy a szöveget tartalmazó dobozt egy másik doboz mögé helyezzük, amely doboz eltakarja
egy részét a szövegnek. Ehhez tudni kell definiálni, hogy melyik objektum van elől, melyik hátul, illetve azt is, hogy az
átfedéseknél a megjelenítésre milyen megoldást kell alkalmazni. Erre szolgálnak a következőkben ismertetett stílus-tulaj-
donságok.
Először ejtsünk szót arról, hogy a böngésző mi alapján dönti el, hogy az egymást átfedő objektumok közül melyik-
nek kell a másikat takarnia. Erre a réteg-modellt lehet alkalmazni. Eszerint a weboldal minden objektumának van egy

168
mélység értéke, amelyet a z-axis tulajdonság ad meg. Minden doboz egy réteg-halmazba tartozik. Ezen belül minden
doboz rendelkezik egy értékkel, amely alapján a mélysége meghatározható az adott réteg-halmazon belül. A nagyobb
z-axis értékű elemek közelebb vannak a felhasználóhoz, aki a képernyőt nézi, így kitakarhatják a kisebb z-axis
értékű elemeket. Ha két elemnek azonos a mélysége, akkor a dokumentum struktúrájában lentről felfelé haladva takarják
egymást.
Egyes elemek új réteg-halmazt hozhatnak létre. Ilyenkor nekik két mélység értékük van : az egyik, amellyel az elem
az őt tartalmazó elem réteg-halmazában szerepel, a másik 0, mint az új réteg-halmaz referencia mélysége. Minden elem
az őt tartalmazó elemmel azonos mélységű, hacsak nem állítunk be más értéket a z-axis tulajdonságnak.

A z-axis tulajdonság A z-axis tulajdonságot a pozícionált elemekre lehet alkalmazni. Segítségével megadható az
esetleges átfedések viselkedéséhez, hogy melyik elem van felül. A tulajdonság a pozícionált elem számára a következőt
adja meg :
1. A doboz mélységét az aktuális réteg-halmazban.
2. A doboz létrehoz-e új réteg-halmazt?
A lehetséges értékei a következők:
egész szám : A megadott érték lesz a doboz mélysége az őt tartalmazó réteg-halmazban. Emellett a doboz egy új,
lokális, csak a leszármazottaira vonatkozó réteg-halmazt hoz létre, melyen belül a doboz mélysége 0. Lehet
negatív mélységet is beállítani.

auto : Ez az alapértelmezett érték. A doboz mélysége megegyezik az őt tartalmazó elemével. Nem hoz létre új réteg-
halmazt.
Mint látható a fentiekből, a réteg-halmazok létrehozása azt jelenti, hogy minden alkalommal, amikor beállítunk egy
mélységet ezzel a tulajdonsággal, akkor az az őt tartalmazó elem mélységéhez relatív mélység lesz.

Természetesen az még kevés, hogy az elemek mélységét tudjuk állítani, hiszen ez magában csak annyit jelent, hogy
ha két objektum átfedi egymást, akkor melyiket fogja eltakarni a másik. Azonban alaphelyzetben ez az átfedés csak az
objektumon belüli olyan részekre fog vonatkozni, ahol a háttértől eltérő részek is vannak. Alapértelmezésben ugyanis
minden doboz esetén a belső illetve a külső margó, valamint a háttér területén átlátszik a mögötte levő objektum.

169
Az overflow tulajdonság Bizonyos helyzetekben előfordulhat, hogy egy elem tartalma nem fér el az elem tartalmának
helyt adó dobozba. Ennek oka lehet a következők valamelyike :
1. Egy sor nem törhető el mielőtt a doboz végére érne a szöveg (túl hosszú szó miatt például).
2. Egy belső doboz túl széles vagy túl magas a rendelkezésre álló helyhez képest.
3. Egy doboz abszolút pozícionálása miatt átfedésbe kerül az elemmel.
4. A doboznak negatív margói vannak beállítva.

Bármelyik eset is álljon fenn, a dobozok között átfedés jön létre. Ebben az esetben az overflow tulajdonság szabá-
lyozza, hogy mi történjen a doboz határán átnyúló elemrészekkel. A clip (170. oldal) tulajdonság segítségével pedig
azt lehet megadni, hogy pontosan hol legyen az a határ, ahol az esetleges elvágást végre kell hajtani.
Az overflow tulajdonság a következő értékek valamelyikét kaphatja :
visible esetén a clip által megadott határokon kívül eső objektumok is látszanak az elem mögött, tehát nincs levágva
a kívül eső rész. Ez az alapértelmezés.
hidden esetén a clip által megadott határokon kívül eső, az elem mögött elhelyezkedő (lásd z-axis tulajdonság,
169. oldal) objektumok nem jelennek meg : levágásra kerülnek. Ezekhez az objektumrészekhez semmilyen mó-
don nem tud a felhasználó hozzáférni, mivel gördítősáv sem jelenik meg.
scroll esetén a hidden-hez hasonlóan levágásra kerül a megadott határokon kívüli rész, de megjelenik – ha kell, ha
nem – a scrollozást lehetővé tevő gördítősáv, így elérhető a mögöttes objektum elmozdításával a nem látszó rész
is.
auto esetén általában (sajnos ez böngészőfüggőnek van megadva a szabványban is) akkor jelenik meg a gördítősáv, ha
szükséges.

A levágás helyének megadása: a clip tulajdonság A clip tulajdonság segítségével lehet pontosan definiálni, hogy az
elem melyik részén belül kell látszania a mögöttes objektumoknak. Alapértelmezésként ez a terület megegyezik az
elem dobozának éleivel. Az auto érték ezt a helyzetet jelenti. Megadható ugyanakkor egy terület, amelynek határa
kezelendő levágási határként. A CSS2 szabvány ilyen területnek csak téglalap alakú terület megadását teszi lehetővéa
rect(top,right,bottom,left)

alakú értékként, ahol a top, right, bottom és left helyére az elem dobozához relatív távolságot kell megadni.
Lehet bármelyik helyett az auto értéket is megadni, ami a nulla távolságnak felel meg. Lehet továbbá az érték negatív
is, amely esetben a dobozon kívülre helyeződik az él.
aA későbbi szabványok talán majd megengednek más alakú kivágásokat is. . .

További két CSS-tulajdonságot ismertetünk még, amelynek a változtatásával a JavaScript kódon keresztül módosítható
a weboldal megjelenése. Ezek a visibility és a display.

170
A visibility tulajdonság A visibility tulajdonság határozza meg, hogy egy adott elem által megjelenített tartalom
látszódjék-e ténylegesen vagy sem. A láthatatlan dobozok azonban még elfoglalják azt a helyet, amit a tartalmuk
megjelenítése igényelne. Lehetséges értékei a következők :
visible esetén az elem által létrehozott doboz és annak tartalma látható.
hidden esetén az elem által létrehozott doboz ugyan elfoglalja azt a helyet, amit akkor is elfoglalna, ha látható lenne,
de a doboz és tartalma nem látható.
collapse esetén a táblázat sora illetve cellája a körül nem jelenik meg semmilyen keret, a sor illetve cella számára szük-
séges hely nem kerül kihagyásra. Amennyiben más elemre van ez az érték beállítva, akkor a hidden értékkel
azonos a viselkedése az elemnek.
inherit esetén az elemet tartalmazó elemtől örökli az értéket (alapértelmezés).

A display tulajdonság A display tulajdonság – többek között – használható arra, hogy egy elem megjelenését befo-
lyásolja. A lehetséges értékei közül a pozícionálásához is kapcsolódóak a következők :
block esetén az elem blokk elemként, önálló dobozzal jelenik meg a weboldalon.

inline esetén az elem sorbeli elemként jelenik meg a weboldalon.


list-item esetén az elem az LI elemhez hasonlóan viselkedik megjelenés szempontjából (az LI-nél ez az alapértelme-
zése).
none esetén az elem egyáltalán nem jelenik meg a weboldalon. Ez nem azt jelenti, mint a visibility elem hidden
értéke, ezúttal az elem tényleg nem fog semmilyen dobozt sem létrehozni.

13.5.3. Példa a stílus változtatásra


Most pedig lássuk, hogyan is lehet a gyakorlatban a fent ismertetett tulajdonságokat felhasználni a weboldalon !

Elem megjelenítése/elrejtése
Amennyiben szeretnénk egy elemet hol láthatóvá tenni, hol pedig nem láthatóvá tenni, akkor erre a megoldás a visibility
tulajdonság használata. Ezt kell tehát a JavaScript programban módosítani.
Az alábbi weboldal két H1 elemet tartalmaz, amelyek láthatóságát az alattuk elhelyezett kapcsolókkal lehet állítani.
(Az űrlapokról és elemeiről a 14.1 fejezetben lesz szó.)
Bármelyik kapcsoló állításakor végrehajtásra kerül a ShowHide függvény, amely a megfelelő elem visibility tulajdon-
ságát állítva megjeleníti vagy elrejti a szükséges elemet. Íme a weboldal teljes forráskódja:8

<html>
<head>
<title>Objektumok megjelenítése és elrejtése</title>
<script type="text/javascript">
function ShowHide() {
var head1 = document.getElementById("head1");
var head2 = document.getElementById("head2");
var showhead1 = document.form1.head1.checked;
8A példa szerepel a [3]-ben. . .

171
var showhead2 = document.form1.head2.checked;
head1.style.visibility = (showhead1) ? "visible" : "hidden";
head2.style.visibility = (showhead2) ? "visible" : "hidden";
}
</script>
</head>
<body>
<h1 id="head1">Ez az első címsor</h1>
<h1 id="head2">Ez a második címsor</h1>
<p>A következő két kapcsolóval a fenti címsorok
láthatóságát lehet ki/be kapcsolni:</p>
<form name="form1">
<input type="checkbox" name="head1" checked onClick="ShowHide();">
Az első címsor megjelenítése.<br>
<input type="checkbox" name="head2" checked onClick="ShowHide();">
A második címsor megjelenítése.
</form>
</body>
</html>

Folyamatosan mozgó szöveg megjelenítése


Erre két példát is fogunk mutatni. Az egyik a weboldalon vízszintesen mozgó szöveget fog eredményezni fényreklámsze-
rűen. A másik pedig arra példa, hogy hogyan lehet egész bekezdésekből álló szöveget függőlegesen mozgatni. Mindkét
példa megtalálható a [3]-ban is, bár esetleg kicsit más változatban.
Az első változatban egy táblázat cellájában fog megjelenni és folyamatosan vándorolni egy egysoros szöveg, ahogyan
az az ablak státuszsorában is megjelenhetne. A szöveg létrehozása és módosítása hasonlóan fog történni ahhoz, csupán
most egy TD elemben fogjuk a szöveget elhelyezni.
Ehhez nem kell mást tenni, mint a megfelelő elem tartalmát mindig módosítani :

var cella = document.getElementById("scroll");


cella.firstChild.nodeValue = newtext;
Tulajdonképpen a fenti két sor jelent újat a státuszsort használó megoldáshoz képest:
<html>
<head>
<title>Fényreklámot tartalmazó weboldal</title>
<script type="text/javascript">
msg = "Ez a szöveg fog megjelenni fényreklámként a weboldalon.";
msg += " Jó hosszú szöveget is írhatunk, így nem fog minden ";
msg += "egyszerre látszani... ";
pos = 0;
function ScrollMessage() {
var newtext = msg.substring(pos,msg.length) + msg.substring(0,pos);
var cella = document.getElementById("scroll");
newtext = "..."+newtext.substring(0,100)+"...";
cella.firstChild.nodeValue = newtext;
pos++;
if (pos > msg.length) pos = 0;
window.setTimeout("ScrollMessage()",150);

172
}
</script>
</head>
<body onload="ScrollMessage();">
<h1>Fényreklámot tartalmazó weboldal</h1>
<table width="90%" border="1">
<tr>
<td id="scroll" width="90%"
style="text-align:center">A fényreklám ide kerül.</td>
</tr>
</table>
</body>
</html>
Sokkal bonyolultabb kódot igényel a másik fajta szövegmozgatás. Ebben az esetben nem egy HTML elem tartalmát
módosítjuk, hanem azt használjuk ki, hogy az egyes objektumok eltakarhatják egymást. Ezt a példát részletesebben fogjuk
ismertetni.
Először is szükségünk lesz a weboldalon egy dobozra, amely megadja azt a keretet, amelyen belül a szöveg látható.
Ez lesz az ablak. Ennek a HTML kódja:

<div id="ablak">
</div>

A hozzá tartozó CSS szabály:


div#ablak {
width: 200px;
height: 5em;
border-color: red;
border-style: groove;
border-width: 0.5em;
padding: 0.5em;
position: fixed;
top: 100px; left: 200px;
overflow: hidden;
}
Ebben az ablakban kellene megjelennie a szövegnek folyamatosan felfelé haladva. Ehhez van beállítva az utolsó
tulajdonság, amely azt jelenti, hogy az elem határától befelé levő téglalapon kívül semmi nem látszik.
A megjelenítendő szöveget az ablakon belül levő újabb DIV elemekkel kell megadni (akár többet is, amelyek egy-
más után jelennek meg, majd ha az utolsó is elfogyott, kezdődhetnek elölről). Amennyiben sok szöveg van, akkor azokat
célszerű két ilyen elemet használva elhelyezni, és mindig az éppen távozó elem tartalmát módosítani a következő megje-
lenítendő szöveggel, majd a megjelenő elem alá helyezni. Ezért most csupán két – állandó szövegű – elemet helyezünk
el, és ezeket mozgatjuk.
Amennyiben módosítjuk a szöveget, akkor persze gondoskodnunk kell arról, hogy a doboz mérete alapján helyezzük
el az alsó dobozt a fölső alá.
A példában szereplő dobozok így néznek ki:
<div id="text1">
<p>Ez itt az első szöveget tartalmazó doboz.</p>
<p>Van benne két bekezdés, némi szöveggel mindkettőben.</p>
</div>

173
<div id="text2">
<p>Ez pedig a második szöveget tartalmazó doboz.</p>
<p>Ebben kicsit több szöveg van.</p>
<p>A módszer alkalmazható sok-sok szövegre is, ha
minden alkalommal, amikor az egyik doboz már kiment a képből,
mielőtt a másik alá helyeznénk, a tartalmát módosítjuk.</p>
<p>Persze több bekezdésnyi szöveg esetén magukat a
<em>P</em> elemeket is bele kell tenni...!</p>
</div>

Ehhez alaphelyzetben a következő CSS szabályok tartoznak :


div#text1 {
width: 200px;
position: absolute;
top: 5em;
}
div#text2 {
width: 200px;
position: absolute;
top: 10em;
}
Ez azt fogja eredményezni, hogy semmi nem látszik a kereten belül, mert minden alatta van.
Ezután következik a JavaScript kód, amellyel a dobozokat mozgásba hozzuk :
<script type="text/javascript">
pos1 = 0;pos2 = 0;
function Start() {
var text2 = document.getElementById("text2");
var text1 = document.getElementById("text1");
text2.style.top=text1.offsetHeight + 10;
// letoltjuk a második dobozt az első aljáig
pos1 = text1.offsetTop;
pos2 = text2.offsetTop;
setTimeout("ScrollBoxes()",20);
}
function ScrollBoxes() {
var text1 = document.getElementById("text1");
var text2 = document.getElementById("text2");
if (pos1 < pos2) {
pos1 -= 1; pos2 -= 1;
text1.style.top = pos1;
text2.style.top = pos2;
if (pos2 < 0) { // kiért a felső doboz
pos1 = pos2 + text2.offsetHeight + 10;
// ide lehet még betenni a szöveg cseréjét...
}
} else {
pos2 -= 1; pos1 -= 1;
text2.style.top = pos2;

174
text1.style.top = pos1;
if (pos1 < 0) { // kiért a felső doboz
pos2 = pos1 + text1.offsetHeight + 10;
}
}
setTimeout("ScrollBoxes()",20);
}
</script>
A ScrollBoxes függvény végzi a tényleges mozgatást. A pos1 és pos2 változók az egyes dobozok tetejének helyzetét
tartalmazzák. Ezeket módosítjuk folyamatosan a mozgatás során, majd ha a felső doboz teljesen kicsúszott az ablakból,
akkor a másik alá tesszük.
A weboldal teljes kódja itt látható:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>scroll</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-2">
<meta name="GENERATOR" content="Quanta Plus">
<style type="text/css">
div#ablak {
width: 200px;
height: 5em;
border-color: red;
border-style: groove;
border-width: 0.5em;
padding: 0.5em;
position: fixed;
top: 100px; left: 200px;
overflow: hidden;
clip: rect(10,10,10,10);
}
div#text1 {
width: 200px;
position: absolute;
top: 5em;
}
div#text2 {
width: 200px;
position: absolute;
top: 15em;
}
</style>
<script type="text/javascript">
pos1 = 0;pos2 = 0;
function Start() {
var text2 = document.getElementById("text2");
var text1 = document.getElementById("text1");
text2.style.top=text1.offsetHeight + 10;

175
// letoltjuk a második dobozt az első aljáig
pos1 = text1.offsetTop;
pos2 = text2.offsetTop;
setTimeout("ScrollBoxes()",20);
}
function ScrollBoxes() {
var text1 = document.getElementById("text1");
var text2 = document.getElementById("text2");
if (pos1 < pos2) {
pos1 -= 1; pos2 -= 1;
text1.style.top = pos1;
text2.style.top = pos2;
if (pos2 < 0) { // kiért a felső doboz
pos1 = pos2 + text2.offsetHeight + 10;
// ide lehet még betenni a szöveg cseréjét...
}
} else {
pos2 -= 1; pos1 -= 1;
text2.style.top = pos2;
text1.style.top = pos1;
if (pos1 < 0) { // kiért a felső doboz
pos2 = pos1 + text1.offsetHeight + 10;
}
}
setTimeout("ScrollBoxes()",20);
}
</script>
</head>
<body onload="Start();">
<div id="ablak">
<div id="text1">
<p>Ez itt az első szöveget tartalmazó doboz.</p>
<p>Van benne két bekezdés, némi szöveggel mindkettőben.</p>
</div>
<div id="text2">
<p>Ez pedig a második szöveget tartalmazó doboz.</p>
<p>Ebben kicsit több szöveg van.</p>
<p>A módszer alkalmazható sok-sok szövegre is, ha
minden alkalommal, amikor az egyik doboz már kiment a képből,
mielőtt a másik alá helyeznénk, a tartalmát módosítjuk.</p>
<p>Persze több bekezdésnyi szöveg esetén magukat a
<em>P</em> elemeket is bele kell tenni...!</p>
</div>
</div>

</body>
</html>
Megjegyzés. A fenti kód nem minden böngészőben működik helyesen. A Mozilla illetve a Galeon nem mozgatja folya-
matosan a dobozokat, így azokban nem látszik az egészből semmi. Az Internet Explorer – szokásos szabványtalanságát

176
bizonyítandó – az overflow tulajdonságot hagyja figyelmen kívül, így a fenti kódot használó weboldalt ebben megnézve a
kereten kívüli részek is látszanak, demonstrálva, hogy hogyan is kellene működnie a scrollozásnak. Ugyanakkor a Quanta
gyorsnézete és a Konqueror tökéletesen megvalósítja a célul kitűzött eredményt – mindössze az a baj vele, hogy a kereten
is megjelenik a hátsó szöveg.
Ugyanakkor ha a fenti kódban az ablak doboz position tulajdonságának értékét fixed-ről lecseréljük absolute-
ra, akkor az Internet Explorer helyesen működik, a Konqueror nem jelenít meg semmit, a Galeron és a Mozilla esetén
nincs változás.
Az ablak clip tulajdonságát auto-ra állítva (vagyis elhagyva) a Konqueror ismét helyesen működik, de a Mozilla és
a Galeon esetében ez sem segít.
A megoldás : amikor a top tulajdonság értékét állítjuk, nem elég a számértéket átadni, hanem a mértékegységre is
szükség van. Amennyiben a fenti kódban a
text1.style.top = pos1;
utasítást a
text1.style.top = pos1 + "px";

utasításra cseréljük – vagyis a mértékegységet is megadjuk –, és a másik dobozzal is hasonlóan járunk el, akkor a Mozilla
és a Galeon lesz az, amelyik pontosan azt teszi, amit kell. Az Internet Explorer és a Konqueror viselkedése nem változik
(a megadott belső margót mindkettő figyelmen kívül hagyja), míg a Mozilla és a Galeon a beállított belső margón belül
jeleníti csak meg a szöveget, ahogyan kell.
Ezzel a JavaScript-ről szóló résznek a végére értünk. Azonban ez nem jelenti azt, hogy ebben a dokumentumban töb-
bet nem esik szó a JavaScript-ről, hiszen az ezután ismertetendő űrlapok kapcsán még jócskán előkerül a JavaScript, sőt
még a PHP-ről szóló fejezetekben is találkozhatunk majd a JavaScript használatát igénylő megoldásokkal. További isme-
retek találhatók a JavaScript-ről az interneten is, valamint a jegyzet végén található irodalomjegyzék [3] és [4] tételeiben
megadott könyvekben is. Érdemes azokat is tanulmányozni további példák, és itt nem említett lehetőségek – például a
böngészőtől függő viselkedés lehetőségei – után kutatva. . .

177
14. fejezet

Egyéb HTML lehetőségek

A következő fejezetben két olyan eszközről lesz szó, amelyek akár JavaScript nélkül, akár azzal együtt biztosítanak
interaktivitást a weboldalakon. Ez első eszköz a dinamikus weboldalak készítéséhez is nagyon fontos eszköz, ezért a
leírása jóval alaposabb lesz annál, mint amit a JavaScript bemutatása igényelne. Ez az űrlap készítés, amelynek ismerete
fontos akkor is, ha dinamikus weboldalak használatával szeretnénk például valamilyen információt feldolgozni.
A másik eszköz segítségével képeket lehet hivatkozásként használni, mégpedig egy képet több hivatkozásként. Ezt az
eszközt nevezzük angol neve (image map) alapján képtérképnek. Használható ez akár egy valódi interaktív térképként is
de akár egy ábra leírással ellátására is.

14.1. Űrlapok
Az űrlapok a weboldalak olyan objektumai, amelyek segítségével adatokat lehet kezelni, feldolgozni. Űrlapot feldolgozni
több módon is lehet, ezek közül két módszert fogunk bemutatni : a kliens oldali feldolgozást JavaScript programokkal és
a szerver oldali feldolgozást PHP programokkal. Ez utóbbival a dinamikus weboldalaknál fogunk foglalkozni.
Amennyiben az űrlapot a kliens oldalán akarjuk feldolgozni, akkor eseménykezelőket kell az űrlap elemeihez rendelni,
amelyeken keresztül a böngészővel a szükséges műveletek végrehajtathatóak. Ennek módja már ismert, így külön nem
kell vele foglalkozni, csupán azzal, hogy a JavaScript kódban hogyan lehet az űrlap elemeihez hozzáférni.
Ha viszont az űrlapot a szerver oldalán akarjuk feldolgozni, akkor az űrlap definiálásakor meg kell adni annak a
weboldalnak a címét, amely az adatokat fel fogja dolgozni. Ilyenkor a böngésző elküldi az igényt a megadott weboldal
letöltésére, és egyben elküldi az űrlapban megadott adatokat is. A webszerver feladata ezután gondoskodni arról, hogy
a kért weboldalt feldolgozó program megkapja az adatokat. PHP esetén a weboldalt feldolgozó program valójában egy
PHP-értelmező, amely bemenő adatként kezeli az űrlap adatait, és így hajtja végre a PHP utasításokat.
Mindezen bevezető után lássuk, hogyan, milyen HTML elemekkel lehet az űrlapot és részeit létrehozni!

14.1.1. A FORM elem


Űrlap létrehozása a FORM elemmel történik:

178
A FORM elem :
A FORM elem egy űrlapot definiál. Nyitó- és zárótagját is kötelező használni, mivel ezek jelzik az űrlap kezdetét és
végét. Az elem tartalma bármilyen szöveges vagy blokk elem lehet, amely egyébként is használható. Ezen felül az elem
tartalma lehet a többi, űrlap-elem bármelyike, tetszőleges kombinációban.
Az elem nyitótagjában a következő paraméterek használhatóak :
• Minden alapvető paraméter, mint például a name, id vagy a class.
• action: Annak a hálózati erőforrásnak a címe (URI), amely az űrlap adatait fel fogja dolgozni. A böngésző az
űrlap érvényesítésekor ezt a címet fogja lekérni, miközben az adatokat elküldi.
• method: Az adatok elküldési módja. Két lehetséges értéke van :
get hatására a böngésző az action paraméterben megadott címhez egy ? után hozzáfűzi a név=érték párok &
jellel elválasztott listáját, ahol minden egyes páros egy űrlapelem nevét és értékét jelenti.
post hatására a böngésző nem a címhez fűzi az adatokat, így azok a felhasználó számára láthatatlanul kerülnek
postázásra. Elegánsabb, de nem minden esetben működőképes megoldás az űrlap adatainak elküldésére.
• enctype: Az űrlap adatainak elküldésére használt tartalomtípus megadására szolgál. Ha nem adjuk meg, akkor
az értéke „application/x-www-form-urlencoded” lesz, amely a legtöbb esetben megfelelő. Amennyiben azonban
állományok feltöltését is tartalmazza az űrlap (lásd az INPUT elem type paraméterét a „file” értékkel : 14.1.5 sza-
kasz), az értékét a következőre kell cserélni : „multipart/form-data”.
• accept-charset: a szerver által megértett karaktertáblák, amelyekkel az űrlap elküldhető.a Alapértelmezett
értéke : „UNKNOWN”, amely azt eredményezi, hogy a böngésző a weboldalhoz használt kódolással küldi az
adatokat.
• accept: Állományok feltöltésekor lehet hasznos a megadása, amely esetben azoknak az állománytípusoknak
a vesszővel elválasztott listáját tartalmazza, amelyek elküldhetők a szervernek. Ezzel nemkívánatos típusú állo-
mányok elküldését lehet megakadályozni. Például képek feltöltése esetén a képformátumokra lehet korlátozni a
megengedett formátumokat.
• name: Visszafelé való kompatibilitás miatt létező paraméter, amely helyett célszerűbb az id paramétert hasz-
nálni. Funkciója ugyanaz: egyedi nevet rendel az űrlaphoz, amely nem csupán a stíluslapon elérhető egyedi
formázáshoz, hanem a JavaScript programokból is könnyebbé teszi az űrlap elérését.
• További, már ismert paraméterek:
– lang: az űrlap nyelve
– style: helyi stílusdefiniáláshoz
– title: buborék-információ megjelenítése az űrlaphoz
– target: az érvényesítés során betöltésre kerülő oldal melyik ablakba vagy keretbe kerüljön
• onSubmit: Az űrlap érvényesítésekor végrehajtandó utasítás. Minden esetben egy return utasításnak kell
lennie, amely egy logikai értéket tartalmaz kifejezésként. A kifejezés általában egy logikai értéket eredményül
adó függvény szokott lenni, amellyel ellenőrizzük az űrlap kitöltését. Ha az érték hamis, az űrlap nem kerül
érvényesítésre, míg igaz értéke esetén az űrlap tartalma az előírt módon elküldésre kerül.
• onReset: Az űrlap alaphelyzetbe hozása esetén végrehajtandó utasítás megadására szolgál. Az onSubmit-
hoz hasonlóan a return utasítást kell használni. Amennyiben hamis értéket adunk a kifejezéssel vissza, akkor
nem kerül az alaphelyzetbe hozás végrehajtásra, csak igaz érték visszaadása esetén.
a Galeon esetén ez talán megakadályozza az Unicode kódtábla fölösleges használatát. . .

179
A FORM elem tulajdonképpen egybezárja az adott űrlapot alkotó elemeket („vezérlőket”, ahogy a HTML szabvány
nevezi ezeket az elemeket). Ezzel a következőket adja meg :
• Alap az űrlap számára (vagyis az elem tartalma számára).
• A programot, amellyel az űrlapot fel kell dolgozni. Ezt adja meg általában – hacsak nem kliens oldali feldol-
gozásról van szó – az action paraméter. Éppen ezért ez a paraméter minden esetben kötelező – ismételten
azt az esetet kivéve, ha az egész feldolgozást kliens oldali scriptekkel kell elvégezni. A feldolgozó programnak
képesnek kell lennie fogadni és feldolgozni a név-érték párokat.
• Az adattovábbítás módját (get vagy post). Erre szolgál a method paraméter, amelynek alapértelmezett értéke a
szabvány szerint get, így elvileg elég akkor megadni, ha a post értéket akarjuk használni, de célszerű mindig
megadni, ha az action paraméter szerepel.
• A karakterkódolást, amelyet a szerver megért.

Íme egy példa az elem használatára: a következő HTML kódrészlet egy űrlapot definiál, amelynek adatait POST
módszerrel kell elküldeni az adduser programnak :
<form action="http://some.site.org/prog/adduser" method="post">
az űrlap tartalma...
</form>

A FORM elem elérése JavaScript-ből


A JavaScript – minő meglepő – a FORM elemhez is a document objektumon keresztül enged hozzáférést. A docu-
ment.forms tömb nullától indexelve tartalmazza a dokumentumban található űrlapokat. Azonban ha megadtuk a FORM
elem nyitótagjában a name vagy id paramétert, akkor az abban definiált névvel is hivatkozhatunk közvetlenül az űrlapra :
például a urlap nevű elemre a document.urlap néven hivatkozhatunk. Ez minden esetben egy Form típusú objektum
lesz, amelynek a következő tulajdonságai és metódusai vannak :
acceptCharset Az azonos nevű paraméterhez lehet rajta keresztül hozzáférni.
action Szintén az azonos nevű paraméterhez férhetünk vele hozzá.
elements Tömb, amely az űrlapban levő elemekre mutató referenciákat tartalmaz. Az egyik lehetőség az űrlap elemeihez
való hozzáférésre ennek a tömbnek a használata. A HTML kódbeli sorrendjükben kerülnek nullától indexelésre
benne az elemek.
elements.length Az elements tömb elemszáma, vagyis az űrlapban levő elemk száma.
encoding Az elem enctype paraméteréhez lehet vele hozzáférni.
length Ugyanaz, mint az elements.length.
method Az azonos nevű paraméterhez lehet vele hozzáférni,
name Az azonos nevű paraméter értékét adja.
reset() Alaphelyzetbe állítja az űrlapot, mintha az űrlapban szereplő valamely Reset-gombra kattintott volna a felhaszná-
ló. Kiváltja a onReset eseményt is.
submit() Az űrlap valamely Submit-gombjára kattintást szimulálja : kiváltja az onSubmit eseményt, és elküldi az űrla-
pot az előírt módon.
target Az azonos nevű paraméterhez lehet vele hozzáférni.

180
14.1.2. Beviteli mezők: INPUT
Az INPUT elem egy nagyon speciális űrlap-elem. Attól függően, hogy a type paraméterét milyen értékre állítjuk be,
különböző űrlap-elemeket hozhatunk vele létre. A következőkben szerepel az elem pontos definíciója, de az egyes űrlap-
elemeket, amelyeket létrehoz, majd további szakaszokban ismerhetjük meg.

Az INPUT elem:
Az INPUT elem különböző típusú űrlap-elemeket hoz létre. A típust a type paraméter értéke határozza meg. A típustól
függően további paraméterek használatosak:
• name: Az elem neve, amely nem csupán arra szolgál, hogy a stíluslapon megszólítható legyen az elem. Sokkal
fontosabb feladata, hogy az űrlap elküldésekor az elem értékét azonosítsa. Ez lesz a név-érték pároknál is az elem
neve.
• value: Az elem értéke, amelyet az űrlap elküldésekor a név-érték pár második részeként elküld az űrlap.
• checked: Kapcsológombok és rádiógombok esetén ha ez a paraméter szerepel, azt jelenti, hogy a gomb aktív,
azaz kiválasztott.
• disabled: Ha szerepel, akkor az elem nem elérhető pillanatnyilag (JavaScript-tel ez az érték ki-be kapcsolha-
tó).
• readonly: Az elem értéke nem módosítható, vagyis a cél csupán az érték elküldése. (text és password típusnál)
• size: Text és password típus esetén a beviteli mező szélességét adja meg karakterekben. Hosszabb szöveg is
írható a mezőbe, de csak ennyi látszik belőle egyszerre.
• maxlength: Text és password típus esetén a beviteli mezőbe írható érték maximális karakterszámát adja meg,
amelynél hosszabb szöveget a mezőbe nem lehet beírni.
• src: Amennyiben az elem típusa „image”, a gombon megjelenítendő kép címét tartalmazza ez a paraméter.

• tabindex: Az űrlapon belüli navigálás a tabulátor billentyűvel is lehetséges, ha az elemek sorrendjét ezzel a
paraméterrel definiáljuk.
• accesskey: Ennek megadásával a megadott billentyűvel is kiválasztható az elem.
• onChange: Ez az esemény akkor jön létre, ha az elem értéke megváltozott.a
• onClick: Gombok esetében lehet hasznos ezzel az eseménnyel figyelni, hogy mikor nyomják le a gombot.
• onFocus: Amikor az elem kapja a billentyűzetre való reagálást, akkor következik be. Az ellenkezője, amikor
elveszti a fókuszt az elem, az onBlur.
a Ez bekövetkezhet úgy is, hogy a felhasználó megváltoztatja az értéket, és úgy is, hogy a JavaScript programból változtatjuk meg az értékét

valamilyen más esemény hatására.

181
A type paraméter lehetséges értékei a következők :
text : Szöveges beviteli mező, amelybe begépelt szöveg lesz az elem értéke.

password : Mint a text, de a begépelt szöveg helyett csupán csillagok jelennek meg. Ha a csillagok megjelenése sem
kívánatos, akkor a szövegszínt és a háttérszínt a stíluslapon egyformává téve azok is eltüntethetőek. . . a
checkbox : Kapcsológombot hoz létre, amely ki-be kapcsolható. Csak a bekapcsolt gomb értéke kerül továbbításra.
radiobox : Rádiógombot hoz létre, amelyek közül az egy csoportba tartozóaknál mindig csak egy lehet kiválasztva.
Egy csoportba az azonos nevűek kerülnek.
submit : Érvényesítő gomb. Rákattintása az űrlap onSubmit eseményét váltja ki, majd annak igaz értékkel történt
kezelése esetén a megadott módon és címre továbbítja az űrlap adatait.
reset : Visszavonó gomb. Rákattintása az űrlap onReset eseményét váltja ki. A szabvány szerint visszaállítja min-
den elemre az alapértelmezett értéket. Bizonyos böngészők az alapértékek visszaállítását nem feltétlenül hajtják
végre!
image: Egy grafikus érvényesítő gombot eredményez, amelyen képként a src paraméterben megadott kép látható,
egyébként a submit típussal azonos módon viselkedik. Amennyiben egérrel kattintunk az ilyen gombra, akkor
azonban az egér (x,y) koordinátáit is elküldi az űrlappal a böngésző, amely szerver-oldali képtérkép létrehozására
is alkalmas. A koordinátákat úgy küldi el, mintha egy name.x és egy name.y nevű elem értékei lennének, ahol a
name az elem name paraméterben megadott neve.
button : Egy nyomógombot hoz létre, amelynek lenyomása egy onClick eseményt hoz létre, amelyet fel lehet dol-
gozni a kliens oldali scriptekkel.
hidden : Egy rejtett elemet hoz létre, amelynek neve és értéke van. Ezzel úgy lehet értéket továbbküldeni, hogy a
böngésző az értéket nem jeleníti meg. Hasznos lehet több oldalas űrlapok készítéséhez, vagy bonyolult, sok
kapcsolóból álló űrlapoknál a kapcsolók értéklistájának egy értékké összegyűjtésében.b
file : Egy „állomány megnyitása” ablakot hoz létre, amiben állományt vagy állományokat lehet kiválasztani, és elkül-
deni az űrlappal a szerverre. Állományok feltöltésére használható. Részletesebben majd a PHP használatánál
foglalkozunk vele.
a Mindazonáltal a jelszó-mezők értékét is kódolatlan szövegként küldi el a böngésző, így ilyen mezőt tartalmazó űrlapot soha ne küldjünk el GET

módszerrel, mivel akkor a böngésző maga is megjeleníti az értéket !


b Mindkét esetre a PHP használatánál lesznek majd példák. . .

A következő, a HTML szabványban szereplő példa az INPUT elemek használatát mutatja az űrlapokban :
<FORM action="http://somesite.com/prog/adduser" method="post">
<P>
Vezetéknév: <INPUT type="text" name="firstname"><BR>
Keresztnév: <INPUT type="text" name="lastname"><BR>
email: <INPUT type="text" name="email"><BR>
<INPUT type="radio" name="nem" value="ffi"> Férfi<BR>
<INPUT type="radio" name="nem" value="no"> Nő<BR>
<INPUT type="submit" value="Elküld">
<INPUT type="reset">
</P>
</FORM>
Majdnem minden típus esetén használhatók a következő metódusok :

182
blur() Az elemről elviszi a fókuszt. Szövegmezők, jelszómezők és állományfeltöltő mezők esetében használható.
focus() Az elemre állítja a fókuszt. Szövegmezők, jelszómezők és állományfeltöltő mezők esetében használható.
click() Mintha a gombra rákattintottak volna, olyan hatást kelt.

A továbbiakban sorravesszük a használható űrlap-elemeket, amelyek között szerepelni fognak olyan elemek is, ame-
lyek az INPUT elemmel hozandóak létre, és olyanok is, amelyek létrehozására külön elemek szolgálnak. Ez utóbbi
esetben az elem pontos definícióját is megadjuk majd.

14.1.3. Button: általános célú gomb


Általános célú gomb kétféle módon hozható létre:
1. A fentebb ismertetett INPUT elemmel (lásd.: 14.1.2 szakasz), a type paraméternek a button értéket adva.

2. A következőkben ismertetésre kerülő BUTTON gombbal.


A button olyan gomb, amely a weboldalon benyomható gombként jelenik meg, valamilyen szöveggel. Rákattintva az
egérrel benyomódik, majd az egérgomb elengedésére visszaáll eredeti helyzetébe. Az egérkattintás az onClick eseményt
váltja ki, más tevékenységet a gomb nem végez.
Ebből az is következik, hogy bármilyen célra felhasználható a gomb, csupán a megfelelő műveletet tartalmazó függ-
vényt kell eseménykezelőként hozzárendelni.
Például a következő kódrészlet egy gombot hoz létre és lenyomására a lenyomva függvény aktiválódik :
<form name="urlap">
<input type="button" name="Gomb" value="Kattints ide!" onClick="lenyomva(this);">
</form>
Ezután a gombra JavaScript-ből kétféleképpen is hivatkozhatunk a Form objektum elements tömbjén kívül :
• A document.urlap.Gomb változóval bárhonnan elérhetjük.
• A lenyomva függvényen belül közvetlenül elérhetjük a paraméterként megadott névvel, köszönhetően annak, hogy
a függvény meghívásakor megkapta paraméterként a this változó értékét, amely mindig az aktuális HTML elemre
mutat. Ez utóbbi módszerrel olyan függvényeket is készíthetünk, amelyek bármely gombhoz hozzárendelhetőek.
Az elem value paramétere tartalmazza azt a szöveget, amely a gombon megjelenik.
Az elemhez tartozó objektum – a fenti példában a document.urlap.Gomb a következő tulajdonságokkal rendel-
kezik :
event Értéke vagy egy függvény azonosítója – ekkor a gomb lenyomásakor vagy más eseménykor ez a függvény ke-
rül végrehajtásra –, vagy null. A tulajdonság neve valójában nem event, hanem a megfelelő esemény neve:
onclick, onblur, onfocus, onmouseup illetve onmousedown lehet. Ezekkel tulajdonképpen dinamikusan
változtatható a gomb viselkedése.
value Az elem value paraméterének értéke. Hasznos lehet, ha a gomb viselkedésének megfelelően a feliratát is dina-
mikusan meg akarjuk változtatni.
Mint fentebb már említettük, van egy másik lehetőség is gombok létrehozására. Ez a másik lehetőség sokkal több
beállítási lehetőséget ad a gomb megjelenésére.

183
A BUTTON elem :
A BUTTON elem csak űrlapon belül alkalmazható elem nyomógombok létrehozására. Nyitó- és zárótagját is kötelező
megadni. Tartalma az A, FORM és FIELDSET elemek, valamint űrlap-elemek kivételével gyakorlatilag bármilyen
szövegelem lehet.
Paraméterei:
name : Az elem azonosítója, amivel hivatkozni lehet rá JavaScript-ben és CSS-ben egyaránt.
value: Az elem kezdeti értékének megadására szolgál.

type : Értéke meghatározza a gomb típusát:


button egyszerű nyomógomb,
submit érvényesítő gomb,
reset az űrlapot alaphelyzetbe állító gomb.

Ha nem szerepel, akkor egyszerű nyomógombot hoz létre az elem.


id, class : Az elem azonosítására szolgál a stíluslap számára.
title : Információs buborékot hoz létre az elemhez.
style : Helyi stílusinformációt lehet vele megadni az elemhez.
disabled : A gomb pillanatnyilag nem elérhető. JavaScript-ből az elemhez tartozó objektum azonos nevű tulajdonsága
igaz/hamis értékével ez be/ki kapcsolható.
Az accesskey, tabindex és az eseménykezelők megadására szolgáló paraméterek ugyanúgy használhatóak, mint
az INPUT elemnél.
A BUTTON elemnek megadható tartalma. Bár a value paraméter a gomb értéke az űrlap szempontjából, a megjelenő
szöveg, és a gomb mintázata az elem tartalmában kerülhet megadásra. Így tulajdonképpen bármilyen képből készíthető
nyomógomb. Az elembe tett képhez nem lehet térképet rendelni !

14.1.4. Kapcsolók: checkbox


A checkbox egy kétállapotú kapcsoló:
1. Egyik állapotában ki van kapcsolva. Ekkor a négyzet üres, az elem név-érték párja nem kerül továbbításra az űrlap
elküldésekor.

2. Másik állapotában be van kapcsolva. Ekkor a négyzetben egy pipa vagy egy kereszt látható – böngészőtől és ope-
rációs rendszertől függ –, esetleg benyomottá válik a négyzet. Ilyenkor az elem név-érték párja elküldésre kerül az
űrlappal.
Létrehozása az INPUT elemmel történik, a type paraméternek a checkbox értéket adva. A name paraméter értéke
lesz az elem neve mind a JavaScript felé, mint az űrlap elküldéskor. Értéke a value paraméter értéke lesz.

<form name="urlap">
<input type="checkbox" name="igen" value="yes"> Igen<br>
<input type="checkbox" name="neo" value="yes" checked> Kiválasztott
</form>

184
A fenti példában két kapcsoló szerepel. Az elsőre a JavaScriptben a document.urlap.igen, a másodikra a
document.urlap.neo néven hivatkozhatunk. Mivel az utóbbinál szerepel a checked paraméter is, a weboldalon
ez eleve kiválasztottként jelenik meg. Természetesen rákattintva ki lehet kapcsolni. Több azonos nevű kapcsoló esetén
azok a JavaScript-ben tömböt fognak alkotni. Pl.: document.urlap.kapcsolok[2] a harmadik „kapcsolok” nevű
kapcsolót jelenti (indexelés mindig nullától. . . !).
Az objektumnak a következő tulajdonságait használhatjuk :
checked : Értéke igaz (true), ha be van kapcsolva ; hamis (false), ha ki van kapcsolva éppen.
defaultChecked : Az alapértelmezett állapot csak olvasható logikai értéke.
onblur, onclick, onfocus: A megfelelő eseményhez rendelhető függvény azonosítója vagy null. Az eseménykezelők
dinamikos módosítása érhető el vele.
value : A kapcsolóhoz rendelt érték. Akár módosítani is lehet, azonban ne felejtsük el, hogy csak a bekapcsolt állapotú
kapcsolók értékét küldi el az űrlap!

14.1.5. Állományfeltöltés: FileUpload


Ez egy nagyon különleges kezelést igénylő űrlap-elem. A tényleges használatát majd a PHP ismertetésénél fogjuk megis-
merni (21.3 fejezet). Most inkább csak a HTML leírás teljessége kedvéért ejtünk róla szót. Természetesen a JavaScript az
ilyen típusú elemekhez is enged hozzáférést, történetesen a FileUpload objektumon keresztül.
Létrehozása az INPUT elemmel történik, a type paraméter értékéül a file értéket adva :
<form name="urlap">
<input type="file" name="allomany">
</form>
Megjelenése egy egysoros beviteli mező, mellette egy „Browse” vagy „Böngész” vagy hasonló feliratú gombbal.
A gombra kattintva a böngésző vagy az operációs rendszer állomány-megnyitó párbeszédablaka jelenik meg, ahol egy
állományt választhatunk le. A kiválasztás után a beviteli mezőben megjelenik a böngészőt futtató gépen érvényes elérési
útvonala az állománynak.
A JavaScript FileUpload objektumának tulajdonságai :
onblur, onclick, onfocus: Az elemmel kapcsolatos megfelelő eseménykezelő dinamikus definiálását teszi lehetővé.
value : Nem módosítható – a többi elemtől eltérően – tulajdonság, amely tartalmazza a kiválasztott állomány elérési
útvonalát, vagyis amit a beviteli mező is mutat. Ennél az elemnél biztonsági okokból nem lehet alapértelmezett ér-
téket adni az elemnek a value paraméter illetve tulajdonság beállításával. Ez ugyanis azt eredményezni, hogy egy
megfelelően megírt weboldal bármilyen állományt letölthetne a felhasználó akarata ellenére (például megfelelően
beállított FileUpLoad mezőt és automatikusan önmagát elküldő űrlapot tartalmazó weboldal révén).

14.1.6. Rejtett adatmezők: hidden


Az INPUT elem type paraméterét hidden értékre állítva olyan – a JavaScript-ben egy Hidden objektumként elérhető
– adatmezőt tudunk létrehozni, amely nem jelenik meg a weboldalon, de az űrlap elküldésekor értéke továbbításra kerül.
Főleg olyankor célszerű alkalmazni, ha egy adatbevitel több, egymást követő űrlap alkalmazásával történik, amelyek
egymásnak bizonyos adatokat tovább kell, hogy küldjenek. Másik hasznos alkalmazása lehet olyan speciális adatmező
létrehozása, amely más adatmezők tartalmát egyesítve küldi tovább, amelyet a PHP-script könnyebben fel tud dolgozni.
A PHP tárgyalásánál majd látunk erre is konkrét példát.
A következő kódrészlet egy rejtett adatmezőt definiál :

185
<form name="urlap">
<input type="hidden" name="rejtett" value="spec.adat">
...
Egyetlen hasznos tulajdonsága, amihez JavaScript-ben hozzáférhetünk :
value: Az elem értéke. A HTML kódban beállított értéket bármikor megváltoztathatjuk. Például a fenti rejtett elem
értékét „új adat” ra változtathatjuk az alábbi programkóddal :

document.urlap.rejtett.value = "új adat";

Mivel az egyik űrlappal begyűjtött információt a következő űrlap alapból nem tudja továbbítani, ha bármit tovább kell
küldeni, akkor úgy kell legenerálni – pl. PHP-val – az új űrlapot, hogy az rejtett adatként tartalmazza a továbbküldendő
információt.
Ha egy űrlapnak a továbbküldési ideje is fontos, akkor szintén alkalmas a rejtett adatmező az ilyen kiegészítő infor-
mációk elküldésére.

14.1.7. Legördülő lista készítése: Select


A SELECT elemmel legördülő listaként vagy több elemű választólistaként megjelenő menüt lehet létrehozni. Tartalma az
OPTION és esetleg a OPTGRUP elemek sorozata, amelyekkel a menü elemei megadhatóak.

A SELECT elem:
Mind nyitó- mind zárótagját kötelező alkalmazni. A kettő között található tartalom fogja a megjelenítendő menü tartal-
mát kialakítani. Tartalma kizárólag az OPTGROUP és OPTION elemek sorozata lehet, minden más elemet a böngésző
figyelmen kívül hagy.
Lehetséges paraméterei:
name : A SELECT elemmel létrehozott objektum egyedi azonosítója. A JavaScript megfelelő Select objektuma ezzel
az azonosítóval elérhető lesz, az űrlap elküldésekor pedig az elemhez tartozó név-érték párban ez a név fog
szerepelni. Az értéket a kiválasztott OPTION elem value paramétere fogja meghatározni.

size : Amennyiben az elem egy többszörös választást lehetővé tevő görgethető listaként jelenik meg, akkor a lista
egyszerre látható elemeinek számát lehet itt megadni.
multiple : Ha ez a paraméter (érték nélkül) szerepel, az azt jelenti, hogy több elem is kiválasztható. Ebben az esetben
egy többszörös választást lehetővé tevő görgethető listaként kell megjeleníteni az elemet, aminek látszó elem-
számát az előző paraméterben lehet beállítani. Ha a paraméter nem szerepel, akkor csak egy elem választható ki.
Ekkor általában legördülő listaként jelenik meg az elem.
id,class,style : A stílus definiálásához használható paraméterek.
title : Buboréktipp megadását teszi lehetővé.
disabled : Az elem éppen nem elérhető. JavaScript-en keresztül ez a tulajdonság ki/be kapcsolható.
tabindex : Lásd az INPUT elemnél (181. oldal). A párja, a accesskey az OPTION elemnél található.
A SELECT elem egy menüt hoz létre, amelyben egy vagy több elemet lehet kiválasztani. Ennek megfelelően legalább
egy OPTION elemet tartalmaznia kell. Szükség esetén egy hosszabb lista elemeit logikailag csoportosítani lehet a
OPTGROUP elemek alkalmazásával. Ezek egymásba nem ágyazhatóak a HTML 4-es szabvány szerint.

186
A SELECT elemhez és a tartalmához egyaránt tartoznak a JavaScript-ben objektumok. A SELECT elemhez a Select
objektum.
Az objektum tulajdonságai:
onblur,onchange,onfocus: Az eseményekhez rendelt eseménykezelők megadását teszi lehetővé. Fontos esemény a SE-
LECT elemnél az onChange. Ez akkor kerül kiváltásra, ha az addig kiválasztott helyett másik OPTION elem kerül
kiválasztásra, illetve többszörös kiválasztás lehetősége esetén, ha bármelyik elem kiválasztottsága megváltozik.
length : Az OPTION elemek száma. Tulajdonképpen megegyezik az options tömb elemszámával. Tartalma nem módo-
sítható.
options : Ez a tömb tartalmazza az önálló azonosítóval nem ellátható OPTION elemeket nullától kezdődő indexekkel.
Tartalma módosítható (lásd lentebb). Törölni elemet a listáról úgy lehet, ha a tömb megfelelő elemének értékét
null-ra állítjuk. Ekkor a következő tömbelemek indexe automatikusan csökkenni fog.
selectedIndex : Megadja a kiválasztott elem indexét (sorszámát). Ha több elem is kiválasztható, akkor az értéke nem
használható, ekkor egy ciklussal kell végigmenni az options tömb elemein.
type : Értéke vagy „select-one”, vagy „select-multiple”. Az előbbi, ha egy elem választható ki, az utóbbi többszörös
kiválasztás lehetősége esetén.

Az elemek csoportosítása

Az OPTGROUP elem:
Mind a nyitó-, mind a zárótagját meg kell adni. Tulajdonképpen a tartalmaként szereplő OPTION elemek csoportosí-
tására szolgál.
Lehetséges paraméterei:
label : Megadja azt a címkét, amelynek ehhez a csoporthoz meg kell jelennie.
disabled : A csoport jelenleg éppen nem elérhető.
Jelenleg a csoportosítás nem beágyazható, de a későbbi HTML szabványok várhatóan ezt is lehetővé teszik majd. . .

Az elemek : Option
A SELECT elem által létrehozott menü minden egyes elemét egy-egy OPTION elem hozza létre.
A OPTION elem:
Nyitótagja kötelező, zárótagja elhagyható: elhagyása esetén a következő OPTION nyitótagjáig, vagy az elemet magába
foglaló OPTGROUP ill. SELECT elem zárótagjáig tart.
Egy SELECT elem menüjének egy elemét definiálja. Lehetséges paraméterei :
selected : Megadása esetén a menüelem alaphelyzetben ki van választva. Értéken nem kell adni neki.
value: A SELECT elem name paramétere által meghatározott azonosítóval mint névvel ez az érték kerül továbbításra
az űrlap elküldésekor.
label: Egy rövid címke az elemhez. Amennyiben meg van adva, akkor az elem tartalma helyett ez az érték fog megje-
lenni a listában.
disabled : Az elem nem elérhető.
Amennyiben a value paraméter nem szerepel, úgy az elem tartalma lesz az érték, amit továbbítani kell.

187
Többszörös választás feldolgozása nehéz, így az ilyen esetet célszerűbb inkább kapcsolókkal kezelni (lásd. : 14.1.4 sza-
kasz).
Elemek előre kiválaszthatók, mint alapértelmezett választás. Erre szolgál az OPTION elem selected paramétere.
Amelyik elemnél ezt megadjuk, az alaphelyzetben ki van választva. Egy elemű választás esetén a legördülő listában ez az
elem látszik, többszörös kiválasztásnál az ilyen elem már ki van jelölve. Csak akkor lehet ezt a paramétert több elemnél
szerepeltetni, ha többszörös kiválasztás lehetséges !
Az OPTION elemnek a JavaScriptben egy Option objektum felel meg. Mivel ennek egyedi azonosítója nincs, logiku-
san következik, hogy tömbben fogjuk őket elérni.
Lássuk az alábbi példát:
<form name="urlap">
<select name="valaszto">
<option value="1">Első elem</option>
<option value="2" selected>Második elem</option>
<option value="5">Az Ötödik Elem</option>
</select>
...
</form>
Ebben az esetben az „5” értékkel rendelkező (jelenleg ténylegesen 3.) OPTION elemre a
document.urlap.valaszto.options[2] változóval hivatkozhatunk. Ennek értékét (5) tehát a
document.urlap.valaszto.options[2].value változó tartalmazza.
A listát a JavaScript-ben dinamikusan is változtathatjuk. Egyrészt a tömbből törölhető elem, másrészt az Option()
konstruktorral új elemet is létre lehet hozni:
document.urlap.valaszto.options[3] = new Option("Harmadik elem","3");
A konstruktornak négy paramétere lehet, ebből az első kötelező, a többi elhagyható :
1. Az elem címkéje (ami az OPTION label paraméterének értéke lenne).
2. Az elem értéke (value paraméter).
3. Logikai érték, igaz, ha alaphelyzetben az elem ki van választva.
4. Logikai érték, igaz, ha most éppen ki van választva.
Az Option tulajdonságai:
defaultSelected : Egy csak olvasható logikai érték, igaz, ha alaphelyzetben kiválasztott az elem.
index : Az elem sorszáma. Értéke megegyezik az elemet tartalmazó Select.options tömb indexével.
selected : Az elem kiválasztottságát jelző logikai érték.
text : Az elem tartalma. Módosítható, így az elemnél megjelenő szöveg módosul.
value : Az elem value paraméterének értéke.

188
14.1.8. Szövegbeviteli mező: Text
Az INPUT elem legegyszerűbb felhasználási módja a szöveges beviteli mező létrehozása. Ez egy meghatározható méretű,
egysoros beviteli mező, amelybe – amennyiben övé a fókusz – szöveget lehet gépelni.
Létrehozása az INPUT elem type paraméterének adott text szöveggel lehetséges. Amennyiben a value paramé-
ternek értéket is adunk, akkor az alaphelyzetben megjelenik kezdőértékként a beviteli mezőben (természetesen törölhető
onnan).
Hasznos a következő paraméterek használata:
• size: pontosan megadható, hogy hány karakter megjelenítésére alkalmas szélességgel jelenjen meg a szövegmező.
Természetesen ez nem korlátozza a begépelhető szöveg hosszát.
• maxlength: a begépelhető szöveg karaktereinek maximális számát adja meg. Ennél hosszabb szöveget nem en-
ged a böngésző begépelni. Értéke lehet nagyobb a size értékénél.
• readonly: csak olvasható az elem. Megjelenik, elküldésre kerül az űrlappal, de nem lehet módosítani.
A Text objektum tulajdonságai:
onblur, onchange, onfocus, onselect: Eseménykezelők megadására szolgál. Különösen hasznos az onChange ese-
mény figyelése, mert ez minden olyan alkalommal kiváltódik, amikor a mező értékének megváltozását eredmé-
nyező gépelést követően a mező elveszti a fókuszt (onblur). Tehát ezt az eseményt figyelve, azonnal a bevitel
befejezése után ellenőrizhetjük a mező tartalmát.
value : A mező tartalma. Módosítható, tehát akár programból beállítható az értéke (például egy másik mező értékéhez
igazodva). Alapértelmezett tartalma megegyezik a mezőben kezdetben megjelenő értékkel, amit a HTML kódban
a value paraméter értékével lehet beállítani.

14.1.9. Jelszó beírása: Password


A Password egy speciális szövegbeviteli mező, ahol minden begépelt karakter helyén egy csillag jelenik meg. A mező
értéke azonban a tényleges begépelt szöveg lesz. Létrehozása az INPUT elemmel történik, típusként a type paraméterbe
a password szöveget kell megadni. Tulajdonságai megegyeznek a Text tulajdonságaival.

14.1.10. Választógombok: Radio


Több, egymással szembeni alternatíva megadásának – a SELECT mellett másik – módja a választógombok használata.
A választógombokat mindig csoportosan használjuk. Egy adott csoportba tartozó valamennyi választógombnak ugyanaz
lesz a neve. Közülük mindig legfeljebb egy lehet kiválasztva. Ha egy sincs, akkor semmi nem kerül továbbításra, ha ki
van valamelyik választva, akkor név-érték párként a csoport közös neve, és a kiválasztott elem value paraméterében
szereplő érték kerül továbbításra.
Íme egy példa:
<form name="urlap">
<input type="radio" name="nem" value="ffi">Férfi<br>
<input type="radio" name="nem" value="no">Nő
...
</form>

A fenti példában két választási lehetőség van. Ha az elsőt választjuk, akkor a „nem=ffi”, ha a másodikat, akkor a
„nem=no” lesz továbbítva.
Mivel nincs egyedi választógomb – annak nem lenne értelme –, ezért ezúttal is tömbön keresztül lehet őket elérni. A
fenti példában :

189
document.urlap.nem[0] // férfi
document.urlap.nem[1] // nő
A megfelelő hivatkozások.
Egy választógomb tulajdonságai:
checked : Logikai érték, igaz, ha az adott gomb van kiválasztva. Egy tömbben csak egy elem lehet kiválasztva. Ha a fenti
példában a nő van kiválasztva, akkor document.urlap.nem[0].checked értéke false,
document.urlap.nem[1].checked értéke true.
onblur, onclick, onfocus: A megfelelő eseményekhez rendelt függvény.
defaultChecked : Alaphelyzetben ki van-e választva (a checked paraméter meg volt-e adva).
value : A gomb value paraméterének értéke. Módosítható.

14.1.11. Többsoros szövegablak: Textarea


Van lehetőség több soros szövegbeviteli ablak elhelyezésére is. Ezt általában hosszabb, nem feltétlenül korlátozott mennyi-
ségű szöveg beviteléhez szokás használni. Létrehozása speciális, erre a célra szolgáló elemmel történik.

A TEXTAREA elem:
Űrlapon belül alkalmazható több soros szövegbeviteli ablak létrehozására. Nyitó- és zárótagját is kötelező megadni. Az
elem tartalma egyszerű szöveg lehet, amely alapértelmezésben megjelenik a szövegablakban.
Az elem paraméterei:
name : Az elem azonosítója, amit mind a stíluslapon, mind a JavaScript-ben az elem azonosítására használni lehet ;
ezen felül az elküldésre kerülő név-érték pár első fele is ez lesz, míg a második fele az elem tartalma, illetve a
felhasználó által annak helyére begépelt szöveg.
rows : Ez a paraméter határozza meg – ezért kötelező megadni –, hogy hány soros legyen a megjelenő szövegablak.
Természetesen a felhasználó ennél hosszabb szöveget is begépelhet, ebben az esetben a böngésző gondoskodni
fog görgetési lehetőségről.
cols : Ez a paraméter határozza meg – ezért szintén kötelező megadni –, hogy egy sorban hány karakter férjen el, azaz
hány oszlopos legyen a megjelenő szövegablak. A böngészőtől függ, hogy a hosszabb sorokat eltördeli vagy
görgetéssel teszi láthatóvá. (Természetesen a felhasználó bármikor kezdhet a szövegben új sort : amíg az ablakon
van a fókusz, az Enter erre alkalmas, és nem az űrlap elküldésére.)
id,class,style : A megjelenés stílusdefinícióval történő megadását segítő paraméterek.
title : Buboréküzenet megjelenítését lehet vele megadni.
readonly : A szövegablakban megjelenő szöveg nem módosítható. Erre az esetre külön megjelenést is elő lehet írni a
stíluslappal. . .
disabled : Nem elérhető az elem.
tabindex, accesskey: Lásd az INPUT elemnél (181. oldal).
A TEXTAREA elem egy többsoros, szöveg bevitelére alkalmas mezőt hoz létre. Amennyiben az elemnek van tartalma,
az megjelenik a mezőben.

Az elem a name paraméterben megadott azonosítóval, Textarea típusú objektumként érhető el a JavaScript kódban.
Tulajdonságai a következők lehetnek:

190
onblur, onchange, onfocus, onkeydown, onkeypress, onkeyup, onselect : Eseménykezelők megadása. Különösen hasz-
nos az onChange esemény figyelése, amely ugyanazt a funkciót látja el, mint a Text objektum beviteli mezőinél.
value : Az elem értéke. Kezdetben az alapértelmezett érték, később amit a felhasználó helyette begépel. JavaScript pro-
grammal is módosítható, amely esetben – ha a böngésző jól működik – az új érték meg fog jelenni.

14.1.12. Alaphelyzetbe hozás: Reset


Előfordulhat, hogy valaki hibásan tölt ki egy űrlapot, és egyszerűbb az egészet elölről kezdeni, mint a beírt értékeket
kijavítani. Erre szolgál a reset gomb, amely minden elemnél az alapértelmezett értékeket állítja be újra.1 Alaphelyzetbe
hozó gomb létrehozható az INPUT elemmel, típusként a type paraméterbe a reset értéket adva. Ekkor a value
paraméter értékével fog a gomb megjelenni. Használható helyette a BUTTON elem is, ahogy arról fentebb szó volt.
A gombhoz társítható események az onclick, onblur, onfocus, onmousedown és onmouseup. A gomb
lenyomása kiváltja az űrlap onReset eseményét, amelyhez rendelt függvény segíthet az alapértelmezett értékek beállí-
tásában a böngészőnek.

14.1.13. Az űrlap lezárása, elküldése: Submit


A másik speciális nyomógomb, amelyet az INPUT elemmel a type paraméter submit értékével vagy a BUTTON
elemmel lehet létrehozni, az érvényesítő gomb. Rákattintva a gombra, kivátásra kerül az űrlap onSubmit eseménye – és
persze az adott gomb onClick eseménye is –, azaz az űrlap elküldésre kerül a FORM elem action paramétere által
meghatározott erőforrásnak (pl. PHP-scriptnek).
A JavaScript-ben a gomb name paraméterével definiált azonosítóval elérhető Select objektumként jelenik meg az
elem.
Az objektum a következő tulajdonságokkal rendelkezik :

onblur, onclick, onfocus, onmouseup, onmousedown : Eseménykezelők a megfelelő eseményhez.


value : A gomb értéke, azaz felirata.
Az űrlap elküldésekor annak a submit-gombnak a név-érték párja kerül elküldésre, amelyik az elküldést kiváltotta. Így ha
egy űrlapnak több elküldő gombja is van, akkor az űrlap feldolgozásánál megvizsgálható, hogy melyik gombbal küldték
el. Ez hasznos lehet különböző feltételek alapján történő feldolgozás készítéséhez.

14.1.14. Címkék készítése


Az űrlap-elemek egy része tartalmaz megjelenítendő címkéket (a gombok például), mások nem. Ez utóbbiakhoz címkét
egyszerű szövegként lehet kapcsolni, vagy lehet használni a LABEL elemet.
1 Egyes böngészők nem minden elemet állítanak alaphelyzetbe, ilyenkor lehet hasznos az alaphelyzet JavaScript-tel történő helyreállítása.

191
A LABEL elem :
A LABEL elem az önálló címkével nem rendelkező űrlap-elemek megcímkézésére szolgál. Mind nyitó-, mind zárótagját
meg kell adni. Tartalma bármely szövegelem lehet újabb LABEL elem kivételével. Paraméterei lehetnek :
for: Ez a paraméter egyértelműen beazonosítja azt a másik elemet, amelyhez a címkét szánjuk. Ennek az értéknek meg
kell egyeznie az adott elem id paraméterének értékével. Amennyiben nem adjuk meg, akkor az elem tartalmában
levő űrlap-elemre fog vonatkozni.
id,class,style : Megjelenés formázásához használható paraméterek.

accesskey, tabindex: lásd: INPUT elemnél (181. oldal).


Amennyiben a címke megkapja a fókuszt, azt automatikusan átadja a hozzá rendelt elemnek. Így a címkék arra hasz-
nálhatóak, hogy az űrlap kitöltését a billentyűzetről is elérhetővé tegyük gyorsbillentyűk (accesskey paraméterek)
illetve a tabulátor (tabindex paraméterek) használatával. Ez utóbbi egyébként mindenképpen rendelkezésre szo-
kott állni, mivel ha a tabindex paramétert nem adjuk meg, akkor az űrlapon belüli definiálási sorrendben kapnak
alapértelmezett sorszámot az elemek.

14.1.15. Az űrlapok szervezése


A FIELDSET és LEGEND elemekkel az űrlapok megjelenésébe struktúráltságot lehet vinni. A FIELDSET elem tartalma
egy téglalapban jelenik meg. Ezen belül használatos a LEGEND a téglalap névvel való ellátására szolgál.

A FIELDSET és a LEGEND elemek:


A FIELDSET elem kötelezően megadandó nyitó- és zárótagja közti tartalom – amely akár blokk-elemeket is tartal-
mazhat – az űrlap különböző elemeit fogja össze. A LEGEND elem szintén kötelezően megadandó nyitó- és zárótagja
között a FIELDSET elemhez rendelendő címke adható meg.
A LEGEND elem paraméterei:
align (elavult) : azt határozza meg, hogy a FIELDSET elem melyik részén jelenjen meg a címke : felül : top, alul :
bottom, jobbra: right, balra: left.
id, class : a formázáshoz (pl. a fenti helyett) használható azonosítók megadása.
lang, dir : nyelv és irásirány beállítása.
title : buborékban megjelenő szöveg megadása.
style : helyi stílusdefiniálás.
accesskey : gyorsbillentyű rendelhető a FIELDSET elemhez ezzel a paraméterrel.
A FIELDSET elem tehát lehetővé teszi, hogy az űrlap elemeit tematikus csoportokba rendezze. Ezzel a felhasználó
számára érthetőbbé tehető az űrlap használata.
A LEGEND elemet mindig a FIELDSET elemen belül kell használni, közvetlenül annak nyitótagja után megadva. Ez
egy címkét rendel a csoporthoz, amelyet a FIELDSET elem létrehoz.

14.1.16. Az űrlapok használata JavaScript-ben


A fentiekben már szerepelt néhány utalás arra, hogy az űrlapokat hogyan lehet elérni a JavaScript nyelven keresztül. Most
röviden foglaljuk össze mindezt a JavaScript oldaláról nézve !

192
Ha a weboldalon elhelyezünk egy űrlapot, akkor a document objektumnak létrejön egy Form típusú eleme. Amennyi-
ben az űrlapnak nem adtunk nevet, akkor a document.forms tömb fogja ezt tartalmazni. Ha viszont az űrlapnak nevet
is adunk, akkor a forms tömb mellett a névvel is elérhetjük : a urlap nevű űrlapot (amit a <form name="urlap". . .
HTML kód hoz létre) elérhetjük a JavaScript kódban a document.urlap változóként is. Ennek a változónak az egyes
elemei az űrlap-elemek. A fenti ismertetőben ezek elérési módja is mind szerepelt.
Az űrlap-elemek esetében használható a Form objektum elements tömbje, vagy ismét hivatkozhatunk közvetlenül a
nevével az elemre. Ha több azonos nevű elem van (például rádiógombok vagy kapcsolók esetében fordulhat ez elő), akkor
azok neve egy tömb azonosítója lesz.
Minden egyes elem – főleg a szövegmezők – rendelkezhetnek a fókusszal. A fókusszal rendelkező elem kapja meg
a billentyűzet események kezelését, azaz a fókusszal rendelkező beviteli mezőbe íródik a begépelt karaktersorozat. A
fókuszt a JavaScript program is ráállíthatja egy elemre, annak focus metódusa segítségével. Ennek ellenkezőjeként eltá-
volítható a fókusz egy elemről a blur metódusával. Íme egy példa, ahol a „nev” nevű beviteli mezőre állítjuk a fókuszt :
document.urlap.nev.focus();
Az elemeknek értékük is van, amelyhez az elem value tulajdonságával férhetünk hozzá. Az alábbi példa egy űrlap
ellenőrzését mutatja, ahol ha a „nev” mező értéke üres, akkor ráállítjuk a fókuszt :
if (document.urlap.nev.value == ’’) {
document.urlap.nev.focus();
alert("A név nincs kitöltve!");
}
Tulajdonképpen a legtöbbször az űrlapokkal kapcsolatban éppen ilyesmire szokás használni a JavaScript kódot : az
űrlap tartalmának elküldés előtti ellenőrzésére.
Ezen felül az űrlapnak van még két hasznos metódusa :
submit() ez a metódus szimulálja az űrlap „submit”-gombjára kattintást, vagyis elküldi az űrlapot.
reset() ez pedig a „reset”-gombra kattintást szimulálja, azaz törli – alaphelyzetbe állítja – az űrlapot.

Űrlap tartalmának ellenőrzése


Mint fentebb már említettük, a JavaScript segítségével ellenőrizni lehet egy űrlap kitöltésének helyességét annak elküldése
előtt. Tulajdonképpen ez a JavaScript tudásának talán a leghasznosabb része. Minden egyéb csak az oldal megjelenésének
látványosabbá tételére szolgál – amely persze szintén nem haszontalan dolog. . .
A következőben egy konkrét példán fogjuk megnézni, hogy hogyan is lehet az űrlap tartalmát ellenőrizni, mielőtt
elküldésre kerülne.
Először is készítünk egy űrlapot, amely személyi adatokat kér be, és POST módszerrel elküldi egy PHP-scriptnek, ami
a feldolgoz.php nevet viseli (relatív címmel van megadva, ugyanabban a könyvtárban, ahol a szóban forgó weboldal
is található). Mielőtt a beírt adatok elküldésre kerülnének, az adatokat ellenőrizzük. Ehhez nem kell mást tenni, mint
a „submit”-gombra kattintáskor teljesülő valamelyik eseményhez egy ellenőrző függvényt rendelni. Ha ez a függvény
hamis értéket ad vissza, az űrlap nem kerül elküldésre, míg ha igen értéket, akkor az űrlap elküldése megtörténik.
Az ellenőrzést kétféleképpen oldhatjuk meg:
1. Az egyszerűbb megoldás, ha a FORM elemnél adjuk meg az onSubmit eseménykezelőt. Ekkor akárhogyan is
kezdeményezzük az űrlap elküldését, előbb végrehajtódik a függvény, és annak értéke dönti el, hogy el lesz-e
küldve az űrlap vagy sem.
2. A „submit”-gomb onClick eseménykezelőjét adjuk meg. Ekkor ha nem a gombra kattintva kezdeményezzük az
elküldést, az ellenőrzés elmarad.
A következő példában az első megoldást alkalmazzuk. Legyen a függvényünk neve Validate. Íme az űrlap HTML
kódja :

193
<form name="personal" action="feldolgoz.php"
method="post" onSubmit="return Validate(this);">
Vezetéknév: <input type="text" name="vnev" value=""><br>
Keresztnév: <input type="text" name="knev" value=""><br>
Leánykori név: <input type="text" name="girlname" value=""><br>
Születési hely: <input type="text" name="birthplace" value""><br>
Születési idő: <input type="text" name="birthdate"
value="0000-00-00" size=10 maxlength=10><br>
<input type="submit" value="Mehet!">
</form>

Mint látható, az onSubmit paraméterben egy return utasítás szerepel. Ez elvileg elhagyható, de így szabályos, és
előbb-utóbb minden böngésző meg is fogja követelni a használatát.2
A fenti FORM elem előtt célszerű szerepeltetni – de utána írva is működni fog – a Validate függvény definícióját
tartalmazó SCRIPT elemet. Ebben a függvényben egy-egy feltételes utasítás segítségével megvizsgáljuk az egyes beviteli
mezők értékét (amennyiben a mező üres, értéke az üres karaktersorozat : ""). Ha a mező üres, kiírunk egy figyelmeztetést,
ráállítjuk a fókuszt az üres mezőre, és megakadályozzuk az űrlap elküldését a hamis érték visszaadásával. A függvény
utolsó utasítására csak akkor jut el a végrehajtás, ha minden mező ki van töltve megfelelően. Ekkor az űrlap elküldhető,
amelyet az igaz érték visszaadása lehetővé is tesz:

<script type="text/javascript">
function Validate(mit) {
if (mit.vnev.value == "") {
alert("Nincs megadva a vezetéknév!");
mit.vnev.focus();
return false;
} else if (mit.knev.value == "") {
alert("Nincs megadva a keresztnév!");
mit.knev.focus();
return false;
} else if (mit.birthplace.value == "") {
alert("Nincs megadva a születési hely!");
mit.birthplace.focus();
return false;
} else if (mit.birtdate.value == "0000-00-00") {
alert("Nincs megadva a születési idő!");
mit.birthdate.focus();
return false; // a dátum helyességét is lehetne vizsgálni...
} else { // minden rendben
return true;
}
}
</script>

Megjegyzendő, hogy a leánykori név kitöltését nem vizsgálja a függvény, hiszen az lehet helyes akkor is, ha nincs
kitöltve (férfiaknál, hajadonoknál). Ugyanakkor hiányos a függvény, hiszen a születési időnél nem vizsgálja meg, hogy
nem hibás-e a dátum. Ennek vizsgálata is elvégezhető azonban a JavaScript eszközeivel – az olvasóra bízzuk. . .
2 A fenti kód nem túl szép űrlapot eredményez, de most nem a kinézet, hanem a működés a lényeg. Természetesen megfelelő stíluslappal a fenti űrlap

is szép formát kaphat. . .

194
14.2. Képtérképek
A képtérkép egy kép régióinak felsorolása, amely régiók mindegyikéhez egy-egy URL van hozzárendelve, lehetővé téve
ezzel interaktív képek, térképek, magyarázattal ellátott ábrák készítését.
Felhasználói szempontból egy kép, amelynek egyes részeire kattintva más-más művelet végrehajtását lehet kezdemé-
nyezni. Hogy éppen hova kattintva milyen műveletet, az attól függ, hogy a képnek az a pontja melyik régióhoz tartozik.
Működés szempontjából a képtérképnek két fajtája van :
Kliens oldali, ahol a böngésző dönti el a weboldal forráskódja alapján, hogy az adott képpont melyik régióhoz tartozik,
és ez alapján az ahhoz rendelt műveletet hajtja végre.
Szerver oldali, ahol a böngésző csupán annyit tud, hogy el kell küldeni egy erőforrásnak az űrlapoknál alkalmazotthoz
hasonló módon a képpont koordinátáit, és ezt az adott erőforrás fogja feldolgozni.
A két lehetőség közül az első, a kliens oldali az elterjedtebb. Ennek sok oka van, az egyik az, hogy a képet megjelení-
teni nem tudó böngésző is képes valamilyen módon a régiókhoz rendelt műveleteket elérhetővé tenni, ellenben a szerver
oldalival, amely csak akkor enged hozzáférést azokhoz, ha a kép is megjeleníthető. Másrészt a kliens oldali képtérképek-
kel olyan lehetőséget is kapunk, hogy egy kép adott része fölé vitt egérmutató hatására megjelenik egy buborékban egy
rövid leírás, ami arra a régióra vonatkozik.
A továbbiakban ez a jegyzet csak a kliens oldali képtérképekkel foglalkozik.

14.2.1. A képtérkép létrehozásához szükséges HTML elemek


Képtérkép létrehozásához – a képet megjelenítő IMG vagy OBJECT elemen kívül – két elem szükséges. Az egyik a MAP,
amely egy térképet definiál, a másik az ezen belül alkalmazható AREA, amely a térkép egy régióját írja le.

109. A MAP elem

<!ELEMENT MAP - - ((%block;) | AREA)+ -- client-side image map -->


<!ATTLIST MAP
%attrs; -- %coreattrs, %i18n, %events --
name CDATA #REQUIRED -- for reference by usemap --
>

A MAP elem egy képhez rendelhető térképet definiál. Nyitó- és zárótagja is kötelező, a kettő közti tartalomban akár
blokk elemek is elhelyezhetőek, de elsősorban az AREA elemeket kell benne szerepeltetni, amelyek leírják a térkép
régióit.
Lehetséges paraméterei a szokásos (id, class, lang stb.) paraméterek. Kötelező szerepeltetni a name paramétert,
amellyel egy azonosítót rendelünk a térképhez. Ezt az azonosítót kell az IMG illetve az OBJECT elem usemap para-
méterében egy kettőskereszt után megadni annál a képnél, amelyikre a térképet alkalmazni kell.
Tehát ha például a nyitótag így néz ki:
<map name="terkep">

A képet megadó IMG elem így nézhet ki:


<img src="..." usemap="#terkep">

195
110. Az AREA elem

<!ELEMENT AREA - O EMPTY -- client-side image map area -->


<!ATTLIST AREA
%attrs; -- %coreattrs, %i18n, %events --
shape %Shape; rect -- controls interpretation of coords --
coords %Coords; #IMPLIED -- comma-separated list of lengths --
href %URI; #IMPLIED -- URI for linked resource --
nohref (nohref) #IMPLIED -- this region has no action --
alt %Text; #REQUIRED -- short description --
tabindex NUMBER #IMPLIED -- position in tabbing order --
accesskey %Character; #IMPLIED -- accessibility key character --
onfocus %Script; #IMPLIED -- the element got the focus --
onblur %Script; #IMPLIED -- the element lost the focus --
>

Az AREA elem a képtérkép egy adott régióját definiálja. Csak nyitótagja van, zárótagja és tartalma nincs, tehát minden
tulajdonságát a paraméterein keresztül kell megadni.

Az AREA elem paraméterei a szokásos paramétereken felül :


shape megadja a régió alakját. Lehetséges értékei a következők :
• default: Az egész képet, mint egységes régiót kezeli. Az alapértelmezett, azaz más régióhoz nem tartozó
területekre érvényes viselkedést lehet vele beállítani.
• rect: Egy téglalap alakú területet definiál, amelynek oldala vízszintesen illetve függőlegesen állnak. Ekkor
a téglalap egyik átlójának koordinátáival lehet a régiót megadni.
• circle: Egy kör alakú régiót definiál, amelynek középpontját és sugarát kell megadni.
• poly: Tetszőleges számú csúcsponttal megadható sokszöget definiál.
coords a shape értékétől függő jelentésű koordinátalistát adja meg. A lista elemei vesszővel választandóak el egymás-
tól.
• Téglalap alakú terület esetén (rect) a két szemközti csúcs x,y koordinátáit (összesen négy számérték).
• Kör alakú terület esetén (circle) a középpont x,y koordinátáit, majd a sugár értékét (három számérték).
Százalékos sugár megadás esetén a kép magassága és szélessége alapján kiszámolt sugarak közül a kisebbiket
fogja a böngésző alkalmazni.
• Sokszög esetén (poly) az egyes csúcspontok x,y koordinátáit kell egymás után felsorolni. A biztonság ked-
véért célszerű a sokszöget lezárni, azaz megismételni a végén a kezdőpontot. Azonban ha ezt nem tesszük, a
böngészőknek be kell tudnia zárni a sokszöget.

Az x,y koordináták a kép bal-felső sarkához relatív koordináták, tehát nem a hagyományos derékszögű koordiná-
tarendszert, hanem a számítástechnikában elterjedtebbet használják, ahol az x balról jobbra nő, az y fentről lefelé.
nohref Egy logikai kapcsoló, amelyet megadva azt bekapcsoljuk, elhagyva kikapcsoljuk. Bekapcsolt állapota esetén a
területhez nem tartozik művelet.

196
usemap Amennyiben az AREA elemet nem egy MAP elemen belül használjuk, akkor ezzel a paraméterrel meg kell adni,
hogy melyik térképhez tartozik: annak a MAP elemnek az azonosítóját (name paraméter) kell megadni, amely
MAP által definiált térképhez tartozik az adott AREA elem.
title Egy buborékszöveget jelenít meg a böngésző, ha a régió fölé visszük. A paraméter értéke a megjelenítendő szöveg.

alt Egy alternatív szöveg arra az esetre, ha a kép nem jeleníthető meg. Ekkor a térkép helyett az AREA elemek alt
paramétereinek értéke alkotta hivatkozáslista jelenhet meg, elérhetővé téve a megfelelő műveleteket.
href A művelet hozzárendelése ezen a paraméteren keresztül történik a területhez. Az A elemből ismert módon kell
megadni a letöltendő erőforrást.

target Akár az A elemnél, annak az ablaknak vagy keretnek a nevét lehet megadni, amibe a href paraméterben megadott
erőforrást be kell tölteni.
Amennyiben egy IMG vagy OBJECT elem rendelkezik a usemap paraméterrel, abból az következik, hogy az általa
leírt képobjektumhoz létezik a weboldalon valahol egy térkép. Az OBJECT elem esetén ez a térkép elhelyezhető magának
az OBJECT elemnek a belsejében is. Ekkor ha a kép nem jeleníthető meg valami miatt, akkor hivatkozások formájában
jelennek meg a régiók.
A MAP elemen belül a régiók kétféleképpen írhatóak le :
1. Egy vagy több AREA elemmel. Ezeknek az elemeknek nincs tartalmuk, csupán megadják egy-egy terület geometriai
alakját és elhelyezkedését, valamint egy hivatkozást rendelnek a területhez. Ezeket az elemeket a böngészők nem
jelenítik meg, legfeljebb az alt paraméter értékét használják fel erre, ha a kép nem jeleníthető meg, amihez a
térkép tartozik.
2. Blokk szintű tartalommal. Ekkor az alternatív megjelenítés esetére vonatkozó elemeket tartalmazza a MAP elem.
Ilyenkor az AREA elem funkcióját az A elem látja el. Természetesen ebben az esetben az A elemnél kell a shape
és coords paraméterekkel leírni a terület geometriáját.
Amennyiben egy MAP elem mind a két esethez tartozó tartalommal rendelkezik, akkor a második esetként kezeli a
térképet, és az AREA elemeket figyelmen kívül hagyja.
Ennek ellenére lehet értelme a két változat együttes alkalmazásának, mivel a régi böngészők csak az első változatot
használják. Így azok az AREA elemeket fogják figyelembe venni, és az összes többit figyelmen kívül hagyni, míg a
modernebb böngészők fordítva viselkednek.

Ha két vagy több régió átfedi egymást, akkor az a régió lesz felül, amelyiknek a definiálása előbb szerepel.

Ebből következik, hogy az alapértelmezett viselkedést a shape="default" értékkel megadó AREA elemet mindig
utoljára kell szerepeltetni, mivel ellenkező esetben az összes többi területet eltakarja.

Szerver oldali térképek


Amennyiben túl komplikált lenne a fenti módszerrel előállítani a képtérképet, akkor érdemes a szerver oldali képtérképpel
foglalkozni. Ezt csak az IMG elemmel és az INPUT elemmel lehet létrehozni. Az IMG elemnek az A elemen belül kell
elhelyezni, és szerepeltetni kell az ismap logikai paramétert, amely jelzi a böngésző felé, hogy egy szerver oldali térkép
tartozik a képhez. Az INPUT elem esetében a típusának image értéket kell adni.
Amikor egy ilyen képre kattint a felhasználó, akkor az A elem által megadott linkhez hozzáfűzi a böngésző a letöltési
kéréskor az egérmutatónak a képen belüli koordinátáit, amelyet a megadott erőforrás mögötti feldolgozó program tud
felhasználni.
A href paraméterben szereplő címhez egy „ ?” után a koordináták vesszővel elválasztva kerülnek hozzáfűzésre.
Például ha az x koordináta 10, az y 25, akkor a következő szöveg kerül a címhez hozzáírásra : „?10,25”. A feldolgozás
már a szerveren történik.

197
Azonban a JavaScript segítségével a kliens oldalon is lehet hasonló módon működő feldolgozást készíteni az egér-
események figyelésével. Az onclick eseményt beállítva egy képhez, az eseménykezelő függvényben lekérdezve az
Event objektum megfelelő tulajdonságait használva az egér pillanatnyi koordinátát.
Ezzel a módszerrel akár olyan képtérképet is definiálni lehet, amelynek minden pontja más-más műveletet jelez. A
legextrémebb régiókat sem lehetetlen így definiálni. Azonban amennyiben a böngésző valamilyen okból – például mert
nem grafikus böngésző, a kép nem letölthető – a kép megjelenítésére képtelen, a képtérkép nem használható. Éppen ezért
ritkán használják.

198
Harmadik rész

Adatbáziskezelés

199
15. fejezet

Elméleti alapok

A következő fejezetekben egy nagyon szélekörűen alkalmazott informatikai területről lesz szó : az adatbázisokról. Több
helyen használnak adatbázist, mint hinnénk. Azonban az adatbázis kezelés nem egy könnyen megérthető témakör, és a
hétköznapi életben egy egyszerű felhasználónak nem is igazán van szüksége az ismeretére, ezért nem túl ismert ez a
terület.
Aki azonban jártas az adatbázisok világában, az rengeteg területen veheti hasznát az ismereteinek. Íme néhány alkal-
mazási terület a teljesség igénye nélkül:
• Repülőgép-helyfoglalás: Több utazási irodában is lehet ugyanarra a járatra helyet foglalni. Nyilván kell tartani,
hogy melyik helyre foglaltak már helyet egy adott gépen. Biztosítani kell, hogy még egyidejű helyfoglalás esetén
se következzen be többszörös helyfoglalás (csak egy utasnak adjunk el egy helyet, de egynek tényleg el is adjuk
azt).
• Banki számlavezetés: A bankok az ügyfelek számláját egy adatbázisban tartják nyilván. Minden tranzakció tulaj-
donképpen az adatbázisban tárolt adatok módosítását jelenti. Szükség van itt is arra, hogy egy adott számlához sok
helyről hozzá lehessen férni, akár egyszerre több helyről is (fizetés átutalása, miközben az ügyfél pénzt vesz ki a
számláról). Biztosítani kell, hogy esetleges rendszerhiba (például áramszünet) esetén se váljanak az adatok hibás-
sá, vagyis ha pénzt utalnak a számlára, akkor az minden körülmények között megérkezzen, vagy fordítva : pénz
levételekor nem maradjon a számlán az összeg, amit másik számlán már jóváírtak. Rendkívül fontos biztonsági
előírásoknak kell megfelelnie egy ilyen banki adatbázisnak.
• Orvosi nyilvántartás: A betegek adatait tartalmazó kartonok régen (a legtöbb helyen ma is) egy hatalmas szekrényt
töltöttek meg egy-egy intézetben. Ez gyakorlatilag egy adatbázis, amelyet papír alapú adattárolással hoztak létre.
Használata fárasztó és hosszadalmas. Ugyanezt a nyilvántartást természetesen számítógépen is tárolhatjuk, ami
gyorsabb hozzáférést tesz lehetővé.
• Könytári nyilvántartás: Az orvosihoz hasonlóan nyilvántartják a könyvek adatait, hogy bármelyik könyv több szem-
pont alapján is megkereshető legyen. Újabban ezt is elhelyezhetik számítógépes adatbázisban.

• Egy bolt árukészletét szintén nyilván szokták tartani. Régen ez leltár formájában történt, ami miatt egy nagyobb
bolt akár napokig is zárva tarthatott időnként. Ugyanez a nyilvántartás napra készen, sőt percre készen is elké-
szíthető számítógép segítségével. Megfelelő kezelői felülettel ellátva az adatbázis kezeléshez nem értő eladók is
használhatják számla nyomtatására, amelyen keresztül azonnal a pillanatnyi készlet aktualizálható. Így a szükséges
utánrendelést a rendszer automatikusan elkészítheti.
• Iskolai adminisztráció: Rengeteg adatot kell egy iskolában egy tanév során nyilvántartani. A tanárok adatait nyil-
ván kell tartani több okból is. A diákok adatait szintén naprakészen nyilván kell tartani statisztikai okokból, vagy

200
akár azért is, hogy esetleges probléma esetén a szülő könnyen elérhető legyen stb. Az osztályzatokat, hiányzáso-
kat, a megtartott órákat, ki melyik osztályt tanítja stb. ; mind nyilván kell tartani. Ez rengeteg – sokszor a tanárokat
fölöslegesen terhelő – papírmunkával jár. Egy megfelelő számítógépes adatbázis ezt megoldhatná, ha lenne az isko-
láknak (a fenntartónak) elegendő pénze arra, hogy az iskola minden tantermét felszerelje egy helyi hálózatba kötött
számítógéppel, amelyen keresztül a tanárok hozzáférhetnek óra alatt is a nyilvántartáshoz. Rengeteg papírmunkát
meg lehetne spórolni ezzel, azonban a hardverszükségletek költsége egy iskola több évi költségvetésével azonos
nagyságrendű.
• Internetes vásárlás során is egy adatbázis rejlik a weboldalak mögött, amelyek az éppen megvásárolható termékeket
mutatják. Ugyanez az adatbázis tárolja a rendelések adatait, és gondoskodik a rendelések teljesítéséről.
• Internetes portálok, keresőrendszerek mögött szintén adatbázis rejtőzik. Tulajdonképpen minden olyan internetes
helyen, amely tartalma dinamikusan változik, vagy amelyhez a hozzáférés azonosítóval és jelszóval lehetséges, egy
adatbázist sejthetünk a háttérben.
A fenti felsorolás utolsó négy pontjában említett adatbázisok minden esetben megvalósíthatóak egy weboldalak al-
kotta felülettel, amely mögött egy szerver oldalon futó program található, amely az adatbázis lekérdezésével, esetleges
módosításával dinamikusan generálja a weboldalakat. A dinamikus weboldalakról majd egy későbbi részben fog szólni
a könyvünk. A következőkben az adatbázisok használatát azonban elsősorban olyan irányból közelítjük majd meg, hogy
ilyen webes felülettel dolgozó rendszereket tudjunk készíteni. Az ilyen rendszereket, amelyek egy adatbázishoz könnyen
– adatbázis kezelői ismeretek nélkül is – kezelhető felületet biztosítanak nevezzük egyébként információs rendszernek.

15.1. Alapfogalmak
Az adatbáziskezelés kapcsán jó néhány fontos fogalom van, amit ismerni kell, hogy megérthessük, hogyan is működik az
adatbázis és a hozzáférés a benne tárolt adatokhoz. A következőkben ezek közül a legfontosabbakat ismertetjük.

Az adatbázis információk (adatok) gyűjteménye, amelyek valamilyen értelemben összetartoznak. Tárolásuk módja
lehetővé teszi az adatok nagy mennyiségének sokféle, hatékony feldolgozását.

Az adatbázis használatához minden esetben szükséges egy adatbázis-kezelő rendszer, amely lehetővé teszi az adatok
feldolgozását. Ennek több fajtája létezik, de mindegyikre érvényesnek kell lennie a következő követelményeknek ahhoz,
hogy adatbázis-kezelő rendszernek lehessen nevezni:
1. Tegye lehetővé több adatbázis kezelését úgy, hogy az egyes adatbázisok egymástól függetlenül elérhetőek legyenek.
2. Tegye lehetővé párhuzamosan több felhasználó számára a hozzáférést az adatokhoz.
3. Biztosítson könnyen kezelhető hozzáférést az adatokhoz a felhasználók számára, amelyen keresztül a bonyolultabb
adatlekérdezések is egyszerűen végrehajthatóak.
4. Tegye lehetővé ugyanahhoz az adatbázishoz biztonságosan a párhuzamos hozzáférést, azaz gondoskodjon a pár-
huzamos hozzáférés esetén felmerülő problémák kezeléséről. Például ha egyszerre két adatmódosítás történik, az
adatoknak akkor is következetesnek kell maradniuk.

Az adatbázis-szerver egy olyan szoftver, amely adatbázisok tárolását biztosítja, valamint az adatbázison történő műve-
letek elvégzésére egy megfelelő adatbázis-kezelő rendszert is nyújt. Ennek az adatbázis-kezelő rendszernek egy másik
komponense általában az a kliens-oldali program, amelyen keresztül a felhasználó, vagy az adatbázist használó program
az adatbázis-szerverhez kapcsolódik.

Általában a hétköznapi életben ritkán használunk közvetlenül adatbázis-kezelő rendszert. Ehelyett inkább egy olyan
szoftvert használunk – a bevezetőben felsoroltunk példát ilyenre –, amely működéséhez valamilyen adatbázist használ,

201
azonban az adatbázisban található információk eléréséhez valójában egy felhasználóbarát, kifejezetten az adott szoftverre
jellemző felületet biztosít.

Az adatbázisra épülő olyan szoftvereket, amelyek az adatbázishoz való hozzáférést saját, megfelelő felhasználói felü-
letre épülő programokkal oldják meg, információs rendszereknek nevezzük.

15.1.1. A tranzakció fogalma


Az adatbázis-kezelőknél a tranzakció nagyon fontos fogalom, ezért érdemes vele egy kicsit bővebben is foglalkozni.

A tranzakció adatbázis-műveletek egy sorozata, amelynek egy egységként kell végrehajtódnia, biztosítania kell az adat-
bázis minden esetben konzisztens azaz következetes állapotát, és a párhuzamosan folyó egyéb adatbázis-műveletektől
elkülönülten kell végrehajtódnia. Ugyanakkor a tranzakciók hatással lehetnek egymásra, azonban ez a hatás mindössze
abból állhat, hogy az egyik tranzakció bekövetkezése meghiúsíthatja egy másik tranzakció sikeres végrehajtását. Eb-
ben az esetben a meghiúsult tranzakciónak nem lehet az adatbázisra semmilyen hatása : úgy kell kezelni, mintha el sem
kezdődött volna.

Például a banki rendszereknél nagyon fontosak a fenti feltételek : az egyik számlát módosító művelettől ugyan függ
egy másik, azt a számlát érintő művelet, de bármely művelet meghiúsulása esetén vagy végrehajtása esetén pontosan annyi
pénznek kell lennie minden számlán, amennyi az eredeti összeg és a ténylegesen megvalósult tranzakciók végrehajtása
kell, hogy eredményezzen. Nem fordulhat elő, hogy egy átutalás pénzt tesz a számlára, de az nem jelenik meg, sem az,
hogy egy pénzösszeg levonása után az eredeti összeg marad a számlán.
A négy alapvető elvárásunk a helyesen végrehajtott tranzakciókkal kapcsolatban a következőképpen fogalmazható
meg :
1. Atomosság: Ez azt jelenti, hogy a tranzakciónak minden esetben vagy teljesen végre kell hajtódnia, vagy egyáltalán
nem szabad semminek végrehajtódnia belőle. Ezt jelenti, hogy „egy egységként” kell végrehajtódnia. Bármilyen
okból történő megszakadása esetén az adatbázisnak olyannak kell lennie, mintha a tranzakció soha el sem kezdődött
volna.
2. Következetesség: Az adatbázisnak minden tranzakció végrehajtása után konzisztens (következetes) állapotban kell
lennie. Egy tranzakció közben előfordulhat, hogy az adatbázis nincs teljesen konzisztens állapotban, de mire be-
fejeződik, ismét abba kell kerülnie. A párhuzamosan futó tranzakciók gyakran okozhatnak inkozisztens állapotot,
amikor például ugyanazt az adatot két tranzakció akarja módosítani. Ilyenkor szokott az egyik tranzakció megsza-
kadni, majd a másik befejeződése után újraindulni úgy, mintha eredetileg is akkor kezdte volna a tevékenységét.
Például egy banki tranzakció az egyik számláról a másikra akar pénzt áttenni. Először a tranzakción belül levonja a
pénzt az egyikről, majd rá akarja tenni a másikra. Azonban ezalatt a cél-számlát egy másik tranzakció megváltoz-
tatta. Ilyenkor a tranzakció minden eddigi tevékenységét vissza kell vonni (ezt hívják rollbacknek), majd a másik
pénzmozgást végző tranzakció sikeres befejezése után újra elkezdeni elölről az egészet. Azonban az is előfordulhat,
hogy a másik tranzakciót kell visszavonni, és így esetleg mégis végre lehet hajtani sikeresen a tranzakciót. Egyes
intelligens adatbázis-kezelők akár ezt az esetet is képesek lehetnek kezelni, időt takarítva meg ezzel a felhasználók
számára is.
3. Elkülönítés: Az előző példánál már említett esetben, ha a másik tranzakció mégsem járt sikerrel, az átutalást igenis
végre kell hajtani. Azaz nem történhet meg az az eset, hogy bár végre lehetett volna hajtani a tranzakciót, mégsem
hajtottuk végre, csak mert éppen akkor egy másik tranzakció futott, amelynek később az adatbázisra nem lett volna
hatása. Az elkülönítés éppen azt jelenti, hogy nem lehet hatással az adatbázisra két tranzakció egyidejű futásának
következménye, amely tranzakciók egymástól függetlenül sikeresek lehettek volna.
4. Tartósság: Sikeresen végrehajtott tranzakció eredménye nem veszhet el semmilyen okból sem. Példánkat folytatva,
ha a pénz átutalása során áramszünet miatt leáll az adatbázis-szerver, az a bank problémája, de az ügyfél pénze

202
nem veszhet el emiatt: az áramszolgáltatás helyreállítását követően az adatbázisnak ekkor is konzisztens képet kell
adnia.
A fenti követelmények teljesítésére a tranzakció kezelésére alkalmas adatbázis-szerverek a következő eszközöket
alkalmazzák :
Zárolás Az elkülönítés biztosítható azzal, ha egy tranzakció az általa érintett adatokat zárolja. Így a másik azt módosítani
kívánó tranzakció kénytelen megvárni a zárolás feloldását. Ha minden tranzakció zárolja induláskor az általa hasz-
nálni kívánt valamennyi adatot, akkor a konzisztencia minden esetben garantálható. Azonban előfordulhat olyan
eset, amikor a zárolás fölöslegesen blokkolja egy tranzakció végrehajtását, holott nyugodtan végrehajtható lenne.
Másik veszélyforrás lehet, amikor a tranzakciók egymás elől elzárnak egy-egy adatot, és a többi adat zárolásának
feloldására várva holtpontot (deadlock) idéznek elő.
A megfelelően használt zárolás biztosíthatja, hogy minden tranzakció a többi által módosított adatoknak is mindig
a konzisztens állapotához férhet csak hozzá.
Naplózás A tranzakció által végzett műveleteket naplózva, esetleges rendszerösszeomlás esetén a tranzakció tényleges
végrehajtása a rendszer helyreállítása után elvégezhető.
Érvényesítés Ha a tranzakció sikeresen végrehajtódik, akkor kerülnek az adatmódosítások ténylegesen végrehajtásra, ad-
dig csak a naplózásuk történik meg. Így esetleges sikertelenség esetén a tranzakció könnyen visszavonható. Emel-
lett ez arra is alkalmas, hogy a naplózásból kiderüljön, hogy hol tartott a tranzakció a rendszerösszeomláskor, így a
naplózás és az érvényesítés együtt képes az összeomlás után az adatbázis konzisztens állapotának visszaállítására.

15.2. Adatmodellezés
Amikor adatbázist szeretnénk készíteni valamilyen adatfeldolgozási feladathoz, először minden esetben meg kell ter-
vezni az adatbázist. Ehhez pedig szükséges a tárolandó adatokhoz egy elméleti modellt készítése. A jó modell alapvető
fontosságú ahhoz, hogy könnyen használható, áttekinthető adatbázist tudjunk készíteni.1
Több módszer is ismeretes adatbázis tervezésére. Minden módszerben szerepel azonban egy vagy több adatmodel-
lezési eszköz, amelyben leírható egy egységes jelrendszerrel a valóságnak az a része, amelyet az adatbázisban tárolni
kívánunk.
A három legismertebb adatmodell a következő :
1. Az egyed-kapcsolat modell egy rajzos modellezési lehetőség a valóság modellezni kívánt részének leírására. Ahogy
az a nevéből is sejthető, a valóságot különböző típusú egyedekre, és az egyedek közti kapcsolatra egyszerűsíti le. A
fejezet további részében ezt a modellt bővebben is megismerjük majd. . .
2. Az ODL (Object Definition Language) egy objektum-orientált megközelítését adja a világnak. Aki már használta
a C++ programozási nyelvet, az otthon fogja magát érezni benne, mivel a két nyelv formailag nagyon hasonlít
egymásra.
Ma még nem túl elterjedt, de ahogy az objektum-orientált adatbázis-kezelők elterjednek, úgy fog terjedni. Az
objektum-orientált logikát követve sok minden egyszerűbben megfogalmazható a hagyományos programozási lo-
gikához képest. Akit az ODL mélyebben érdekel, az a [5] adatmodellezésről szóló fejezeteiben találhat róla bőven
információt. Ebben a dokumentumban – egyenlőre legalábbis – nem foglalkozunk ezzel az adatmodellel.
3. A relációs adatmodell a jelenleg legelterjedtebb adatbázis rendszerek legtöbbjében használatos, már nem teljesen
elméleti adatmodell. A legtöbb ma használt adatbázis-kezelő relációs adatbázis-kezelő. Ezekben az adatbázist a
1 A jelenlegi kétszintű érettségi követelményrendszer éppen ezért hibás, mivel az adatmodellezés ismerete nélkül várja el a középszintű érettségin

az adatbázis-kezelői ismeretek alkalmazását. Azonban kérdéses, hogy van-e értelme adatbázis-kezelésnek akkor, ha az ember nem is érti az adatbázis
felépítését. Ez a jegyzet éppen ezért pótolni kívánja azt a hiányt, amit az érettségi követelményrendszer átgondolatlansága okozhat a diákok számára :
először értsük meg, hogy épül fel egy adatbázis, és csak utána kezdjünk vele dolgozni.

203
relációs adatmodell egy gyakorlati megvalósításával lehet megadni. Ismerete éppen ezért alapvető fontosságú azok
számára, akik adatbázisokkal akarnak dolgozni.
Általában az adatbázis megtervezésekor vagy az egyed-kapcsolat modellből, vagy az ODL-ből indulunk ki. Ezután ha
relációs adatbázis-kezelő rendszert akarunk használni, akkor az elkészült elvi modell alapján elkészítjük a relációs mo-
dellt, amelyet felhasználva az adatbázis létrehozható. Amennyiben objektum-orientált adatbázis-kezelő rendszert akarunk
használni, akkor mindenképpen ODL-ben kell az adatbázist megtervezni, amelyet egy konkrét programozási nyelvre –
legtöbbször C++-ra – kell átültetni, amely maga is képes objektumok kezelésére. Az adatbázist kezelő információs rend-
szert ezután ugyanezen a nyelven lehet elkészíteni.
Mivel jelenleg még a hagyományos módszert a relációs adatbázis-kezelő használata jelenti, ezért mi is ezt az utat
mutatjuk be. Először ismertetjük az egyed-kapcsolat modellt, majd a relációs adatmodellt, bemutatva egyben azt is, hogy
az egyed-kapcsolat diagramokat hogyan alakíthatjuk relációkká. Majd a következő fejezetben bemutatjuk a relációs adat-
modellre épülő szabványos lekérdező nyelvet, az SQL-t.
Az adatmodellezés és a későbbi adatbázis-kezelési eszközök bemutatásánál is ugyanazt a példát fogjuk használni. Ez
pedig egy nagyon gyakorlati példa lesz: egy üzlet árukészletének nyilvántartása. Tárolni szeretnénk az egyes árufajták
mennyiségét, egységárát (azt is, hogy mi az egység). Ezenfelül a vásárláskor számlát állítunk ki, és a megvásárolt ter-
mékeket levonjuk a raktárkészletből, de a nap végéig megőrizzük a vásárlás tényét, hogy a nap végén a napi forgalom
rekonstruálható legyen. Minden termékhez megadható továbbá az a minimális mennyiség, ami alatt pótolni kell a készle-
tet utánrendeléssel. Mindez nem tűnik nagy adatbázisnak, arra azonban tökéletesen megfelel, hogy az adatbázis-kezelés
fortélyai elsajátíthatóak legyenek rajta. Előbb azonban ismerkedjünk meg az adatmodellezés eszközeivel. . . !

15.2.1. Mire figyeljünk a tervezés során?


Amikor adatbázist tervezünk, van néhány szempont, amelynek figyelembe vétele elengedhetetlenül fontos ahhoz, hogy az
adatbázis megfelelően használható legyen. Vegyük röviden sorra ezeket az alapelveket, mielőtt a tényleges adatmodellek
ismertetésébe belekezdenénk!

A modell legyen valósághű


A modellünk feleljen meg a valóságnak a nyilvántartani kívánt adatok szempontjából. Ideértendő az is, hogy olyan tulaj-
donságokat tároljunk, amelynek tényleg van értelme, és az is, hogy a modellezni kívánt része a valóságnak ténylegesen
úgy működjön, ahogyan a modell feltételezi. Magyarul fogalmazva : például egy személyeket tároló adatbázisban nincs
értelme a rendszám tulajdonság tárolásának, illetve ha egy autótulajdonosokat nyilvántartó rendszert készítünk, akkor
nem elfogadható olyan megoldás, hogy egy tulajdonosnak csak egy autója lehet, hiszen a valóságban ugyanannak a sze-
mélynek lehet több autója is.

Ne legyen a modellben redundancia


Minden adatot lehetőleg csak egyszer tároljunk. Amennyiben valamely adatot, amely ugyanarra a valóságos objektumra
vonatkozik, több helyen is tárolunk, akkor nem csupán fölöslegesen megduplázzuk az adatokat, hanem megkockáztatjuk,
hogy esetleg az egyik helyen történő adatmódosítás után a rendszerünk ellentmondásokat fog tartalmazni.

Redundanciának nevezzük az adatok fölöslegesen duplán történő tárolását. Ez veszélyezteti a rendszer konzisztenciáját,
mivel az esetleges módosításnál nem feltétlenül történik meg a redundáns adat minden példányának módosítása.
A konzisztencia szó jelentése ellentmondásmentesség. Azt jelenti egy nyilvántartás esetén, hogy a tárolt adatok minden
esetben megfelelnek egymásnak. A konzisztencia sérülése – melyet inkonzisztens állapotnak is szokás nevezni – hibás
adatfeldolgozást eredményezhet.

204
Törekedjünk a modell egyszerűsítésére
Ne vegyünk fel a modellbe több elemet, mint amennyire ténylegesen szükség van. Előfordulhat, hogy egy-egy a való-
ságban létező objektum nem tartalmaz új információt, így a modellből nyugodtan kihagyható. A modell éppen azért a
valóság leegyszerűsítése, hogy az ilyen fölösleges objektumokat kihagyjuk a modellből.

A megfelelő elemeket válasszuk ki az adatok tárolására


Egy modellezendő elem tulajdonságai lehetnek egyszerűen tárolhatóak, de lehetnek elég összetettek ahhoz, hogy önálló
objektumként nyilvántarthatóvá váljanak. Például ha postacímeket is nyilván akarunk tartani, akkor lehetséges, hogy a
településeket és azok irányítószámait érdemes külön nyilvántartani – ezzel a redundancia is elkerülhető –, és a címbe
csak az irányítószámot bevenni. Hasonlóan megfontolandó, hogy érdemes-e a cím további részét utcanévre és házszámra
bontani, vagy egyetlen tulajdonságként kezelni e két adatot.

15.3. Az egyed-kapcsolat modell


Az egyed-kapcsolat modell esetében a valós világ modellezendő részében mindent mint egyedet tekintünk. Egyed lehet
bármi, amiről adatokat kívánunk nyilvántartani: autó (rendszáma, típusa, színe stb. tartható nyilván), személy (neve, élet-
kora, testmagassága stb.), épület, villamosvonal, vagy akár maga a villamosmegálló is. Attól függően, hogy miért akarjuk
nyilvántartani, más és más tulajdonságai lehetnek fontosak. A számunkra fontos, és ezért nyilvántartandó tulajdonsága-
it nevezzük az egyed attribútumainak. Az egyes egyedek persze nem önmagukban fontosak a számunkra, hanem más
egyedekkel való kapcsolatuk miatt: hogyan, milyen célból és okból kapcsolódik az egyed más egyedekhez. Tulajdonkép-
pen ezeknek az információknak a grafikus, egyed-kapcsolat diagramon történő ábrázolása az egyed-kapcsolat modell.

A hasonló jellegű egyedeket, amelyekről ugyanazokat a jellegű tulajdonságokat tartjuk fontosnak, egy halmazba cso-
portosítjuk. Az így kapott halmazt nevezzük egyedhalmaznak.

Egy egyedhalmazt alkotnak például az autók, a személyek vagy az épületek. Ellenben nem alkothat egy egyedhalmazt
például egy autó és egy épület, mivel az épületekről egészen más adatokat szokás nyilvántartani, mint az autókról.

Az egyes egyedhalmazba tartozó egyedek ugyanolyan jellegű tulajdonságait tartjuk nyilván. Ezeket a tulajdonságokat
adják meg az egyedhalmaz attribútumai.

Az egyes egyedhalmazok között a valóságban persze különböző kapcsolatok lehetnek : az autónak van tulajdonosa,
mint ahogyan egy épületnek is lehet. Az ezeket leíró fogalmat úgy is nevezzük, hogy kapcsolatok.

Az egyed-kapcsolat modell grafikusan szemlélteti az egyedeket és a kapcsolataikat. Így a fenti három fogalomnak az
egyed-kapcsolat diagramon jól elkülöníthető megjelenésének kell lennie :
• Egyedhalmazt minden esetben egy téglalap jelöl, amelynek belsejében található az egyedhalmaz megnevezése.
• Attribútumot egy ellipszis jelöl, amelybe az attribútum neve van írva, és az ellipszist azzal az egyedhalmazzal (vagy
kapcsolattal), amelyhez tartozik, egy vonal köti össze.

• A kapcsolatokat rombusszal jelöljük. A rombusz belsejében található a kapcsolat elnevezése. A rombuszt minden
egyes egyedhalmazzal, amelyhez a kapcsolat tartozik, egy vonal (esetleg az egyedhalmaz felé mutató nyíl) kö-
ti össze. Amennyiben a kapcsolat egy egyedhalmazzal többszörösen is kapcsolódik, akkor több vonal is indul a
rombusztól az egyedhalmaz téglalapjához (lásd később).
A 15.1. ábrán látható egy példa az egyed-kapcsolat diagrammra. Az ábrán három egyedhalmaz látható :

205
15.1. ábra. A film adatbázis egyed-kapcsolat diagramja (átvett példa a [5]-ből)

Filmek, melynek attribútumai: cím, év, hossz és szalagfajta.


Színészek, melynek attribútumai: név és lakcím.
Stúdió, melynek attribútumai: név és cím.
Ezeken felül látható még két kapcsolat is. Az egyik a Szereplők, amely a Filmeket és a Színészeket kapcsolja össze,
vagyis megadja, hogy melyik filmben ki szerepelt, és egyben azt is, hogy melyik színész melyik filmben szerepelt. A
másik kapcsolat pedig az egyes filmeket gyártó stúdiókat, és egyben az egyes stúdiók által gyártott filmeket azonosítja
be: a Gyártó kapcsolat a Filmek és a Stúdió egyedhalmazokat köti össze. Ráadásul az ábráról az is leolvasható lesz –
hamarosan kiderül, miért –, hogy egy filmet csak egy stúdió készíthet ebben a modellben (a valóságban ez nem így van),
de egy stúdió készíthet több filmet is.

15.3.1. Kapcsolatok fajtái


A modellben lényeges, hogy megadhassuk, hogy egy kapcsolat az egyes egyedhalmazokból ténylegesen hány egyedet
kapcsolhat a másik egyedhalmaz egyes egyedeihez hozzá. Például a fenti példában nem mindegy, hogy megengedett-e
egy filmhez több stúdiót rendelni. Ennek megfelelően alapvetően három kapcsolattípust különböztetünk meg :
1. A sok-sok, vagy a magyar szakirodalomban használt elnevezéssel : N:M kapcsolat, amely ha az E1 és E2 egyed-
halmazok közötti összefüggést írja le, akkor azt jelenti, hogy minden E1 -beli egyedhez az E2 -beli egyedek egy
halmazát rendeljük hozzá, és fordítva is minden E2 -beli egyedhez az E1 valamely tetszőleges elemszámú részhal-
maza rendelhető. Ez tehát azt jelenti, hogy a kapcsolatban részt vehet mindkét egyedhalmazból egyszerre több elem
is. A fenti példában ilyen eset lehet amikor egy filmnek több szereplője is van, és ugyanaz a színész több filmben is
szerepel.
2. A sok-egy, vagy a magyar szakirodalomban használt elnevezéssel : N :1 kapcsolat esetén minden E1 -beli egyedhez
az E2 egyedhalmaznak legfeljebb egy elemét (más fogalmazásban pontosan egy elemét) lehet hozzárendelni, azon-
ban egy adott E2 -beli egyedhez az E1 egyedhalmaz több eleme is tartozhat. Ebben az esetben a diagramon az E2
felé a kapcsolatból nem csak egy vonal, hanem egy nyílban végződő vonal mutat. Tehát a fenti példában a Gyártó

206
kapcsolat egy sok-egy kapcsolat, ahol több film, de csak egy stúdió vehet részt egyszerre a kapcsolatban, mert egy
stúdió gyárthat több filmet, de minden filmnél pontosan egy stúdió nevezhető gyártó stúdiónak.
3. Az egy-egy, vagy magyar szakirodalombeli jelöléssel : 1 :1 kapcsolat esetén mind az E1 , mind az E2 egyedhalmaz-
nak pontosan (legfeljebb) egy egyede vehet részt a kapcsolatban. Ha például a fenti példát kibővítenénk egy újabb
egyedhalmazzal, amely azokat a személyeket tartalmazná, akik valamely stúdió elnökei, és feltételezzük, hogy
minden stúdiónak más az elnöke, akkor az elnököt a stúdióval összekapcsoló kapcsolat egy-egy kapcsolat lenne.
Ilyenkor a kapcsolatból mindegyik egyedhalmazba nyílban végződő vonal mutat.
Megjegyzés. Két megjegyzést kell tenni a fentiekkel kapcsolatban :
1. A sok-egy és az egy-egy kapcsolatnál szerepelt a „pontosan egy” és a „legalább egy” kifejezés is. Ez a két kifejezés
természetesen nem azonos jelentésű. Azonban a fenti meghatározásokban mindkettő helyénvaló lehet. Elméletileg
nem megengedett, hogy a kapcsolat a semmibe mutasson, azonban a gyakorlati adatbázisokban ez elég sokszor
előfordul, így érdemesebb megengedni a „legalább egy” kifejezést is. Azonban vannak helyzetek, amikor lényeges,
hogy az az egy egyed ténylegesen létezzen, azaz a „pontosan egy” kifejezést kell alkalmazni. Ezeket általában külön
jelölni lehet, egy másfajta nyíl alkalmazásával.
2. A többágú kapcsolatok esetében a sok-egy és az egy-egy kapcsolat megadása nem feltétlenül egyértelmű. Ilyenkor
ha egy egyedhalmazhoz nyíl vezet, az mindössze annyit jelenít meg, hogy a többi egyedhalmazból kiválasztva egy-
egy egyedet, ahhoz ebben az egyedhalmazban legfeljebb egy egyed tartozhat. Többet azonban nem mond arról, hogy
ennek az egyedhalmaznak egy adott eleméhez a többi egyedhalmazból lehet-e több egyedet rendelni vagy sem.

15.3.2. Egyedhalmazok több szerepben


Lehetséges olyan kapcsolat is, amely ugyanahhoz az egyedhalmazhoz kapcsolódik más-más szerepkörben. Például ilyen
lehet a Szülője kapcsolat, amely a Személyek egyedhalmazhoz kapcsolódik. Egyik szerepben mint gyerek, a másikban mint
szülő szerepel ugyanaz az egyedhalmaz. Másik hasonló példa a képen is látható eset, amikor egy filmet és a folytatásait
akarjuk ábrázolni. Ekkor minden filmnek pontosan egy eredetije van, de lehet több folytatása is. Minden ilyen és ehhez
hasonló esetben a kapcsolat nyilait megcímkézzük a szerepüknek megfelelően.

15.2. ábra. Egy kapcsolat és a szerepei

15.3.3. Kapcsolat attribútumai


Az eddig elmondottakból arra lehet következtetni, hogy attribútumai az egyedhalmazoknak lehetnek. Azonban nincs
semmi olyan kitétel, amely kizárná, hogy egy kapcsolat rendelkezzen attribútumokkal.
Vegyük például azt a példát, amikor a filmek, színészek és stúdiók közti szerződést akarjuk egy kapcsolattal nyil-
vántartani. Ez egy háromágú kapcsolat lesz, amelyben egy stúdió több színésszel illetve több filmre köthet szerződést.
Azonban hová tartozik a fizetés, amit a színész egy adott filmbeli szerepére kap ?

207
Ha a stúdióhoz rendeljük ezt a tulajdonságot, az azt jelentené, hogy az adott stúdió minden színésznek a szereptől
függetlenül ugyanannyit fizet. Ha a színészhez, azt jelentené, hogy az adott színész a filmtől függetlenül minden szerepre
ugyanannyi fizetést kap. Ha pedig a filmhez, az azt jelentené, hogy a film minden szerepére, annak méretétől függetlenül,
az összes színész ugyanannyi fizetést kapna. Egyik sem felel meg a valóságnak.
A fizetés mint tulajdonság valójában egyben tartozik a szerephez, amit a színész egy adott filmben eljátszik, amire egy
meghatározott stúdióval kötött szerződést, azaz magának a szerződésnek a tulajdonsága.
A megoldás lehetne az, hogy a Szerződés kapcsolatot alakítsuk át egy önálló egyedhalmazzá – hiszen logikailag az is
lehetne –, és a többi egyedhalmazhoz megfelelő kapcsolatokon keresztül kössük hozzá.2 Egyszerűbben hangzó megoldás,
ha a fizetés attribútumot a Szerződés kapcsolathoz adjuk hozzá. Az eredmény a 15.3. ábrán látható.

15.3. ábra. Kapcsolat attribútummal

15.3.4. Alosztályok
Előfordulhat, hogy egy egyedhalmaznak vannak olyan elemei, amelyek valamilyen speciális többlettulajdonsággal is
rendelkeznek a többi egyedhez képest. Ezek a többlettulajdonságok lehetnek egyszerűen további attribútumot igénylő tu-
lajdonságok, vagy akár olyanok is, amelyek leírása új kapcsolatokat igényel, amelyekre a többi egyednek nincs szüksége.
Azonban az ilyen egyedek többi tulajdonságaik alapján mégis az eredeti egyedhalmazhoz is sorolhatóak. Az ilyen esete-
ket írja le az alosztály, amely a többlettulajdonságok számára egy speciális egyedhalmazt jelent, amely eredményeként az
egyed egyszerre több egyedhalmaznak is eleme lehet.
Az alosztály fogalom az objektum-orientált megközelítéshez áll közelebb, így elsősorban az ODL-ben használatos.
Azonban az E/K diagramokban is lehet ilyet megadni, és mivel az objektum-orientált megközelítést is lehetővé tevő
PostgreSQL is megengedi az alosztály használatát annak minden öröklési előnyével, ezért érdemes megismerni – legalább
érintőlegesen – ezt a fogalmat is.
Tegyük fel, hogy egy E1 egyedhalmaz egy E2 egyedhalmaznak alosztálya. Ez egy speciális kapcsolat segítségével
adható meg. A kapcsolatot jelképező rombusz helyett azonban most egy háromszög szerepel, amelynek csúcsa az E2
egyedhalmazra mutat (vagyis arra az egyedhalmazra, amelynek a másik az alosztálya). A háromszögbe az „az egy” (angol
eredetiben „is a”) szöveget szokás írni.
A 15.4. ábrán látható egy példa – a [5]-ben is szerepel –, amely alosztályok megadását mutatja. Ezen az ábrán egy
Filmek egyedhalmaz látható, két speciális alosztály megadásával. Az egyik a Rajzfilmek alosztály, amelynek van egy – az
2 Bármely többágú kapcsolat átalakítható kétágú kapcsolatokká úgy, hogy az eredeti kapcsolatot, mint új egyedhalmazt hozzuk létre, és minden olyan

egyedhalmazzal létesítünk belőle kapcsolatot, amelyhez eredetileg kapcsolódott.

208
ábrán csak részben megadott – kapcsolata a Színészek egyedhalmaz felé, amelyen keresztül elérhetőek azok a színészek,
akik a rajzfilm szereplőinek a hangjukat kölcsönözték.
A másik alosztály a BűnügyiFilmek egyedhalmaz, amely egy fegyver nevű attribútummal bővíti ki az eredeti tulajdon-
ságok körét.
Mindez a valóságban azt jelenti, hogy ha egy film rajzfilm, akkor az egyszerre eleme a Filmek egyedhalmaznak és
a Rajzfilmek egyedhalmaznak is. Ebből következően rendelkezik mindazokkal a tulajdonságokkal, amelyekkel, mint a
Filmek egyedhalmaz eleme rendelkezhet, és azokkal is, amelyekkel mint a Rajzfilmek egyedhalmaz eleme rendelkezhet –
vagyis a filmhez a hangjukat adó színészekkel. Ugyanez igaz egy bűnügyi filmre is a megfelelő egyedhalmazok esetében.

15.4. ábra. Alosztályok ábrázolása

Azonban mi a helyzet egy olyan filmmel, amely egyszerre rajzfilm is és bűnügyi film is ? – kérdezhetnénk. Nos, itt
látszik a különbség a valódi objektum-orientált megközelítésű – itt nem ismertetett – ODL és az egyed-kapcsolat modell
között. Az ODL-ben ugyanis minden egyed csak egy osztályba tartozhat, amiben persze rendelkezik minden örökölt
tulajdonsággal is. Ott a bűnügyi rajzfilmek számára is kellene egy külön osztályt származtatni a rajzfilmek és a bűnügyi
filmek felhasználásával (a PostgreSQL-ben is ezt kellene tenni). Ezzel szemben az egyed-kapcsolat modellben erre már
nincsen szükség, hiszen – ahogy fentebb már említettük – egy egyed egyszerre több egyedhalmazba is beletartozik az
alosztályok hierarchiájában. Így egy bűnügyi rajzfilm mint film eleme lesz a Filmek egyedhalmaznak, és megkapja az
ott megadott attribútumok megfelelő értékeit; rajzfilmként eleme a Rajzfilmek egyedhalmaznak, és így rendelkezni fog a
Hangok kapcsolattal; bűnügyi filmként pedig eleme lesz a BűnügyiFilmek egyedhalmaznak is, ahol megkapja a fegyver
attribútum megfelelő értékét.
A kétfajta megközelítés közül az E/K-diagrambeli talán az érthetőbb, azonban a gyakorlati adatbázisoknál lehetséges,
hogy az ODL-féle megközelítés, ahol külön osztályra van szükség a bűnügyi rajzfilmek számára, egyszerűbben meg-
valósítható lehet. Így ha valaki annyira bonyolult adatbázisokkal kíván foglalkozni, ahol alosztályokra is szükség lesz,
feltétlenül érdemes az ODL-t is alaposabban megismernie. . .

209
15.3.5. Megszorítások
Mielőtt az egyed-kapcsolat modell utolsó eleméről ejtenénk pár szót, tennünk kell egy kis kitérőt az adatbázis-kezelés
elméletének egy nagyon fontos területére, a megszorítások megadására. A megszorítások tulajdonképpen olyan feltételek,
amelyeket az adatoknak teljesíteniük kell. A legfontosabb megszorítás fajták a következők :

A kulcsok olyan attribútumok vagy attribútumok olyan halmazai, amelyek egyértelműen azonosítanak egy egyedet az
egyedhalmazon belül. Ez azt jelenti, hogy nincs az egyedhalmazban két olyan egyed, amelynek tulajdonságértékei meg-
egyeznének minden olyan attribútumon, amelyek a kulcsot alkotó halmazba beletartoznak. Másik, ezzel egyenértékű
feltétel : ha két egyed a kulcsba tartozó valamennyi attribútumán ugyanazzal az értékkel rendelkezik, akkor valamennyi
attribútumán megegyezik (azaz a két egyed valójában azonos).

Az egyértékűségi megszorítások olyan követelmények, hogy az érték egy bizonyos szerepben egyedi. A kulcs ennek
speciális esete, mert az egyértékűségi megszorítás azt jelenti, hogy az adott attribútumon vagy attribútumok egy adott
halmazán egy egyedhalmazon belül az érték nem ismétlődhet meg, vagyis minden egyednek ezeken az attribútumokon
eltérő értékkel kell rendelkeznie.

A hivatkozási épség megszorítás megköveteli, hogy egy objektum által hivatkozott érték létezzen az adatbázisban. Ez
azt jelenti, hogy ha egy egyed egy kapcsolaton keresztül egy másik egyedhalmaz valamelyik elemével kapcsolatban
áll, akkor az a másik elem létezzen ténylegesen.

Az értelmezési tartomány megszorítás megköveteli, hogy egy attribútum az értékeit a megadott értéktartományból
vagy értékhalmazból vegye. Ilyen lehet például a dátum megadása, vagy osztályzatok nyilvántartásánál az {1; . . . ; 5}
egész számok halmaza.

Ezeken felül léteznek még általános megszorítások, azaz olyan tetszőleges követelmények, amelyeknek a tárolt ada-
toknak meg kell felelniük.
A fentiek közül különösen fontos a kulcs, így foglalkozzunk vele egy kicsivel többet !

Egy egyedhalmaz kulcsa az egyed-kapcsolat modellben egy vagy több attribútum alkotta K halmaz úgy, hogy bármely
két e1 és e2 különböző egyed esetén a két egyed nem egyezhet meg a K-beli attribútumok mindegyikén.

Egyes esetekben nehéz megtalálni azokat az attribútumokat, amelyekből kulcsot lehet létrehozni. Azonban a kulcs
megkeresése lényeges lehet ha már az adatbázisban rengeteg adatot tartunk nyilván. Ekkor a kulcs alapján gyorsabban
megtalálhatjuk a keresett egyedeket. Vannak persze esetek, amikor nem a kulcs alapján keresünk, ilyenkor hasznos lehet
a kulcs kezeléséhez hasonló eszközöket más attribútumokra is elérhetővé tenni.3 Jobb esetben egy egyedhalmaznál több,
egyforma értékű kulcsot is találhatunk. Ez egyáltalán nem baj. Közülük az egyiket kiválaszthatjuk elsődleges kulcsnak.
Gyakran szokás élni azzal a módszerrel, hogy kifejezetten azzal a céllal készítünk egy attribútumot, hogy az legyen
az egyedhalmaz kulcsa. Ilyen módszer a nem elektronikus nyilvántartásoknál is létezett már : személyi szám, autók rend-
száma mind ilyen egyedi azonosítást lehetővé tevő kulcsok. Vannak olyan adatbázisok, ahol egyszerűen egy-egy egyedi
sorszámmal látják el az egyedeket, és ez az egyedi sorszám lesz azután a kulcs.
Egy fontos gyakorlati tanács: szöveges adatot (például nevet) soha ne használjunk kulcsnak, mert elég egy szóköz
elírás, vagy a kis- és nagybetűk másképp megadása, hogy a kulcs megváltozzon. Helyette mindig alkalmazzunk inkább
egy egyedi azonosítót vagy sorszámot!
3 Ezek az eszközök az indexek, amelyekről majd a későbbiekben lesz még szó. A legtöbb adatbázis-kezelő a kulcsokhoz automatikusan készít a

keresést gyorsító indexeket.

210
Például ha egy cégnél minden dolgozónak van a számítógépes hálózathoz egy azonosítója, akkor ez az azonosító
alkalmas a dolgozók nyilvántartásában kulcsnak. Ha egy iskolában a diákokat akarjuk nyilvántartani, ahhoz is használ-
hatjuk kulcsnak az azonosítójukat, ha abból egyértelműen kiderül, hogy kiről van szó (pl. ha abban benne van az osztálya
azonosítója is).
Az egyed-kapcsolat diagramon az elsődleges kulcsot szokás jelölni azzal, hogy az ehhez tartozó attribútumok neveit az
ellipsziseken belül aláhúzzuk. Amennyiben további kulcsok is vannak, azok ilyen módon nem ábrázolhatóak, legfeljebb
megjegyzésben mellékelhetőek az ábrához.

15.3.6. Gyenge egyedhalmazok


Előfordulhat, hogy egy egyedhalmaz egyedeinek egyértelmű azonosítása nem lehetséges saját attribútumaival, csupán egy
vagy több másik egyedhalmaz kulcs-attribútuminak segítségével. Az ilyen egyedhalmazokat nevezzük gyenge egyedhal-
maznak.
Íme egy példa a gyenge egyedhalmazra – amely egyben a gyenge egyedhalmaz megadásának módját is mutatja :
Az egyes filmstúdióknak lehetnek csoportjaik, amelyek a csoporton belül egyedi sorszámmal rendelkeznek. Azonban a
különböző stúdiók rendelkezhetnek azonos sorszámú csoportokkal, így a csoportot önmagában a sorszáma nem azonosít,
csak a stúdió kulcsa és a saját sorszáma együtt. Ekkor – amennyiben a stúdió kulcsa a neve – a Csoportok egyedhalmaz
kulcsa a saját sorszám attribútuma, és a Stúdiók egyedhalmaz név attribútuma együtt lesz (lásd : 15.5. ábra).

15.5. ábra. Példa gyenge egyedhalmazra

Amikor egy többágú kapcsolatot átalakítunk egyedhalmazzá, és új kapcsolatokká, akkor ez az új kapcsoló egyedhal-
maz valójában egy olyan gyenge egyedhalmaz lesz, amely kulcsa előáll az összes olyan egyedhalmaz kulcsából, amelyeket
az eredeti kapcsolat összekötött. Ilyenkor csak akkor lesz ennek a gyenge egyedhalmaznak saját attribútuma, ha az eredeti
kapcsolatnak volt saját attribútuma. Például a szerződéseket megadó korábbi példánk (15.3. ábra) átalakításával kapott
gyenge egyedhalmaz látható a 15.6. ábrán.
Az ábrán csak azokat az attribútumokat tüntettük fel, amelyek a Szerződések gyenge egyedhalmaz kulcsához szüksé-
gesek, illetve magának a Szerződések egyedhalmaznak a fizetés attribútumát.
Mint az ábrákon is látható, a gyenge egyedhalmazt dupla keretes téglalappal jelöljük. Azt a kapcsolatot (azokat a
kapcsolatokat), amely(ek)en keresztül a kulcsát kiegészítő egyedhalmaz(ok)hoz kapcsolódik, szintén dupla keretes rom-
busszal kell megadni.
Persze ahhoz, hogy egy gyenge egyedhalmazt megadhassunk, kicsit több információ szükséges : Ha egy E egyed-
halmaz gyenge egyedhalmaz, akkor minden F egyedhalmaz esetén, amely egy vagy több attribútumával hozzájárul E
kulcsához, E-nek kapcsolódnia kell F -hez egy R kapcsolaton keresztül, és a következő feltételeknek kell teljesülnie :
1. R-nek egy sok-egy kapcsolatnak kell lennie, amelynek az egy oldala az F egyedhalmaz felé mutat.4
4 Értelemszerűen ebbe a sok-egy kapcsolatba belefér egy egy-egy kapcsolat is.

211
15.6. ábra. Kapcsolat átalakítása gyenge egyedhalmazzá

2. F azon attribútumai, amelyek benne vannak E kulcsában, benne vannak F kulcsában is.
3. Ha F maga is gyenge egyedhalmaz, akkor F azon kulcsattribútumai, amelyek benne vannak E kulcsában, lehet,
hogy egy F -hez sok-egy kapcsolattal kapcsolódó másik egyedhalmaz (kulcs-)attribútumai.
4. Ha több sok-egy kapcsolat is vezet E-ből ugyanabba az F -be, akkor minden kapcsolaton keresztül segíthetik F
kulcs-attribútumai E kulcsának kialakítását. Ilyenkor ugyanaz a kulcsattribútum több példányban is szerepel –
esetleg más-más értékkel – E kulcsában. Előfordulhat az is, hogy az egyes kapcsolatokon keresztül F más-más
egyedei vesznek részt E egyes egyedeinek meghatározásában.

15.4. A relációs adatmodell


A ma használatos adatbázis-rendszerek 90%-a úgynevezett relációs adatbázis-kezelő. Ezek az adatok tárolására logikailag
– és részben fizikailag is – a relációs adatmodellt használják. Éppen ezért, bár az adatbázis megtervezésére az egyed-
kapcsolat modell kitűnő eszköz, a gyakorlati megvalósításhoz a relációs adatmodellt is meg kell ismerni, és tudni kell azt
is, hogy hogyan lehet az egyed-kapcsolat modellben készült E/K diagramot relációs modellé átalakítani.
A relációs adatmodell teljeskörű ismerete komoly matematikai hátteret igényel. Ezért ebben a dokumentumban csupán
olyan mélységig foglalkozunk vele, amilyen mélységű ismerete a továbbiakban szükséges. Valójában csak az alapelveket
említjük, valamint azt, hogy az E/K diagramból hogyan lehet az adatbázis tervét relációs adatmodellbe átalakítani. Innen

212
azután a következő lépés már az SQL nyelv segítségével a fizikai adatbázis létrehozása és kezelése lesz a következő feje-
zetben. Előbb azonban majd még a fentebb már említett bolti árukészlet adatbázisát célszerű gyakorlásként megtervezni
E/K modellben, és átalakítani relációs modellé. . .
A relációs modell tényleges ismertetésére kíváncsiaknak érdemes előbb a szükséges matematikai háttérrel tisztába
kerülniük, majd az adatmodell részletes ismertetését a [5]-ben megtalálhatják. . .
A relációs modellben a legfontosabb fogalom maga a reláció, amely valójában nem jelent mást, mint az adatok
kétdimenziós, azaz táblázatszerű ábrázolását.5 A táblázat első sora tartalmazza az attribútumokat, míg az alattuk levő
sorok egy-egy egyed adatai, ahol minden oszlopban az ott megadott attribútum értéke található. A 15.7. ábra a Filmek
egyedhalmazt, mint relációt mutatja, benne három egyeddel.

cím év hossz szalagfajta


Csillagok háborúja IV.: Egy új remény 1977 124 színes
A rút kiskacsa 1991 104 színes
A Gyűrű szövettsége 2001 200 színes

15.7. ábra. A Filmek reláció

A relációval kapcsolatban fontosak a következő fogalmak :


Attribútumok : Mint fentebb már említettük, a reláció táblázatos megadásakor a fejlécben (vagyis az első sorban) talál-
hatók az attribútumok. Ezek gyakorlatilag megegyeznek az egyed-kapcsolat modell attribútum-fogalmával. Gya-
korlatilag a reláció oszlopainak elnevezését adják. Minden attribútum a relációban szereplő egyedek egy-egy tulaj-
donságát írja le.

Sémák : A reláció nevét és a reláció-attribútumok halmazát együtt relációsémának nevezzük. Megadása tulajdonképpen
a reláció nevének, majd azt követően zárójelben az attribútumainak a felsorolásából áll :

Film(cím, év, hossz, szalagfajta)

Mint látható, ezúttal maguk az egyedek nem szerepelnek. Megjegyzendő, hogy ebben a megadási módban ugyan
szerepel az attribútumoknak egy sorrendje, de az elvi megadásnál az attribútumoknak mindössze a halmazát adjuk
meg, amely nem definiál sorrendet. Amikor majd a gyakorlatban definiáljuk az adatbázis relációit, akkor az attribú-
tumok megadási sorrendje egy tényleges tárolási sorrendet is meghatároz, amelyhez a későbbiekben az adatbázis-
kezelő ragaszkodni fog.
Amikor egy adatbázist tervezünk relációs modellben, az egyes relációsémákat soroljuk fel. Az adatbázis relációinak
ilyen felsorolását szokás relációs adatbázissémának vagy röviden adatbázissémának nevezni.
Sorok : A reláció minden egyes sora (a fejlécet kivéve) egy-egy egyed adatait tartalmazza. Megadhatóak a sorok a táblá-
zaton kívül is. Ilyenkor zárójelek között, vesszővel elválasztva szerepelnek az attribútum értékei. Viszont ilyenkor
nincs semmi, ami alapján el lehetne dönteni, hogy melyik érték melyik attribútumnak felel meg, hiszen a reláció-
séma az attribútumoknak csak a halmazát adja meg. Ilyenkor azonban mégis úgy tekintjük, hogy a relációsémánál
megadott sorrendben szerepelnek az értékek.
Azonban már a relációs adatbázis-kezelők sem igen foglalkoznak a sorok megadási sorrendjével : a sorok gyakorla-
tilag egy halmazt alkotnak. Van olyan adatbázis-kezelő, ahol egy reláció tartalmát lekérdezve ez azonnal láthatóvá
is válik : egyszerűen abban a sorrendben jeleníti meg a reláció sorait, amilyen sorrendben éppen fizikailag tárolva
vannak. Ha azonban egy sort módosítunk, a fizikai tárolási sorrenddel együtt a kiíráskori sorrend is megváltozhat.
5 Ez az oka annak, hogy bizonyos adatbázis-kezelési feladatok gyakorlatilag egy táblázatkezelővel is megoldhatóak.

213
Maga a reláció egy elméleti fogalom. Hogy pillanatnyilag milyen sorai vannak, az nem befolyásolja magát a relációt,
csupán a reláció aktuális előfordulását. Amikor már nem elméleti adatbázisról, hanem gyakorlati adatbázisról fogunk
majd beszélni, akkor ott már az elméleti reláció szó helyett a gyakorlati adattábla vagy tábla néven fogjuk említeni,
amely utal a reláció megjelenési formájára, a táblázatra, ugyanakkor a később ismertetendő SQL nyelv is a TABLE néven
említi a relációk fizikai megvalósítását.

15.4.1. Az egyed-kapcsolat modell átalakítása relációsémákká


Mivel az egyed-kapcsolat modell elméleti modell, ezért csak az adatbázis struktúráját adja meg. Ebből következően a
relációknak is csak a sémáját kapjuk meg. Azonban az egyes egyedekből az őket tartalmazó egyedhalmazból kapott reláció
egy-egy sora lesz, és minden attribútumuk is értelemszerűen válik a megfelelő reláció megfelelő sorának az értékévé. . .

Egyedhalmazok átírása relációkká


Első lépésként magukat az egyedhalmazokat írjuk át relációkká. (A kapcsolatok átírása külön történik, így azokkal egyen-
lőre nem foglalkozunk.) Először azokkal az egyedhalmazokkal foglalkozunk, amelyek nem gyenge egyedhalmazok. A
gyenge egyedhalmazokra majd később térünk vissza.
Minden nem gyenge egyedhalmazhoz készítsünk egy relációt ugyanazzal a névvel. Az egyedhalmaz attribútumait
vegyük fel a reláció attribútumaiként. A relációban azok az attribútumok alkotják a kulcsot, amelyek az egyedhalmaz
kulcs attribútumai voltak. Végül az egyedhalmaz minden egyes egyede a reláció egy-egy soraként fog megjelenni.
A 15.1. ábrán (206. oldal) szereplő E/K diagramot fogjuk példaként tekinteni. Ezen három egyedhalmaz szerepel,
amelyekből rendre a következő relációsémák lesznek :

• Filmek(cím, év, hossz, szalagfajta)


• Színészek(név, lakcím)
• Stúdiók(név, cím)
A fenti relációsémákban a megszokott módon, aláhúzással jelöltük a kulcsot alkotó attribútumokat.6

Kapcsolatok átírása relációkká


A fenti példában szerepelt még két kapcsolat is – egy sok-sok és egy sok-egy kapcsolat –, amelyeket még valahogy át kell
írni relációs modellbe.
A kapcsolatokból szintén relációk lesznek. Egy adott kapcsolatból szintén a kapcsolat nevével megegyező R reláció
készül, amely a következő attribútumokat tartalmazza:

1. Az R kapcsolatban résztvevő minden egyedhalmazra belevesszük az R sémájába az egyedhalmazok kulcs attribú-


tumait.
2. Amennyiben az R kapcsolatnak voltak saját attribútumai, akkor azokat is felvesszük a relációsémába.
Természetesen ha egy egyedhalmaz többszörösen részt vett az adott kapcsolatban, akkor az érintett kulcs attribútumo-
kat a szerep szerint át kell nevezni, hogy a relációséma minden attribútuma egyedi nevet kapjon.
Az így kapott reláció sorai természetesen azokból a kulcspárosításokból állnak majd, amelyek az egyes egyedhalma-
zoknak a kapcsolatban résztvevő egyedeinél szerepelnek.
A fenti példában szereplő két kapcsolatból tehát a következő relációsémák keletkeznek :
• Szereplők(filmcím, filmév, színésznév)
6A kulcsok helyességén lehetne vitatkozni, azonban most csupán a példa átírását kívánja a felsorolás bemutatni, még akkor is, ha korábban említet-
tük: szöveges adatot kulcsnak választani nem célszerű. . .

214
• Gyártó(filmcím, filmév, stúdiónév)
Mint látható, az egyedhalmazokból kulcs attribútumként kapott attribútumok a kapcsolatból létrejövő reláció kulcs
attribútumai lesznek.
Azonban a Gyártó kapcsolatból nem feltétlenül szükséges külön relációt létrehozni, hiszen az sok-egy kapcsolat lévén,
minden filmhez egyetlen sort fog tartalmazni. Ilyen esetben – vagyis a sok-egy kapcsolatoknál – megtehető, és a gyakorlati
alkalmazásoknál célszerű is megtenni, hogy a sok-egy kapcsolatot beleolvasztjuk a sok-oldali egyedhalmazból alkotott
relációba : felvesszük az egy-oldali egyedhalmaz kulcs attribútumait ebbe a relációba.
A példánkban ez azt jelenti, hogy a Filmek reláció így módosul :
Filmek(cím, év, hossz, szalagfajta, stúdiónév)
Itt a stúdiónév a Stúdiók reláció név attribútumára utal, amely a Stúdiók reláció kulcsa. Azonban, mint látható, a Filmek
relációnak ez az attribútum nem lesz kulcsa.
Egy-egy kapcsolatoknál még könnyebb a dolog, hiszen bármelyik egyedhalmaz relációjába beilleszthető a másik
egyedhalmaz kulcsa. Azonban minden esetben meg kell gondolni, hogy mit nyerünk és mit veszítünk a beolvasztással.
Nyerünk : tárolási helyet, amelyből kevesebbet igényel az adatbázisunk, ha kevesebb a reláció. Vesztünk : sebességet,
ha a másik irányból akarjuk a kapcsolatban résztvevő egyedeket megkeresni. Ha sok olyan információ keresésére kell
számítani az adatbázisban, amelyhez jó, ha van külön reláció, akkor érdemesebb a külön relációt megtartani.

Gyenge egyedhalmazok átírása


A gyenge egyedhalmaz egyedeinek beazonosításához nem elegendőek saját attribútumai, hanem néhány sok-egy kap-
csolaton keresztül további egyedhalmazok attribútumait használja fel. Emiatt ezek relációkká alakítása kicsit másképpen
történik, mint a nem gyenge egyedhalmazoké.
Éppen ezért
1. a W gyenge egyedhalmazból alkotott relációnak tartalmaznia kell W valamennyi attribútumát, valamint minden
olyan, egyedhalmaz kulcs attribútumait, amelyek dupla keretes (sok-egy) kapcsolaton keresztül segítik a W kul-
csának kialakítását.
2. Azoknál a kapcsolatoknál, amelyekben W részt vesz, a W -től kapott kulcs attribútumnak számít minden olyan
attribútum is, amely az előző pontban leírtak alapján a W -ből származó relációba más egyedhalmazokból került
be. Tehát azokat is fel kell venni a kapcsolat kulcs attribútumai közé.
3. A dupla keretes kapcsolatok valójában csak azt jelölik, hogy a W kulcsát mely egyedhalmazok segítik meghatároz-
ni, önálló jelentésük nincs. Ennek a kapcsolatnak az attribútumai valójában mind benne vannak a W attribútum-
halmazában, annak részhalmazát képezve. Így az ebből a kapcsolatból származó reláció nem adna új információt,
redundás reláció lenne. Ezért a dupla keretes kapcsolatokból nem készítünk relációt.
A 15.5. ábrán (211. oldal) látható gyenge egyedhalmazból ezek szerint a következő relációk készülnek :
• Stúdiók(név, cím)

• Csoportok(stúdiónév, csoportszám)

Mivel az Egysége kapcsolatból létrejövő relációnak pontosan ugyanazok az attribútumai lennének, mint a Csoportok
relációnak, így felvétele fölösleges, sőt kifejezetten hibás lenne a kialakuló redundancia miatt.
A 15.6. ábrán látható példán a Szerződések kapcsolatból alkotott gyenge egyedhalmaz látható, a saját fizetés attribútu-
mával. Ha nem alakítjuk át egyedhalmazzá, akkor a kapcsolatból a következő relációt hozhattuk volna létre (értelemszerű
kulcsokat feltételezve):
• Szerződések(színésznév, stúdiónév, filmcím, filmév, fizetés)
Ha viszont a 15.6. ábrán látható gyenge egyedhalmazt alakítjuk át relációvá, akkor (a dupla keretes kapcsolatok
eltűnnek) a következő relációt kapjuk:

215
• Szerződések(színésznév, stúdiónév, filmcím, filmév, fizetés)
Mint látható, a két reláció között semmi különbség. Ez is azt mutatja, hogy a többágú kapcsolatok kétágú kapcsola-
tokká alakítása vagy meghagyása a végső adatmodellt érdemben nem befolyásolja.

Alosztályok átírása
Kényes kérdéshez érkeztünk. A relációs modell nem biztosít eszközt az alosztály-hierarchia megadására. A PostgreSQL
megvalósít egy megoldást, amely az ODL öröklődési módszerét követi, azonban a PostgreSQL egy részben objektum-
orientált relációs adatbázis-szerver, amely tehát részben követi az ODL modellt is.
Van azonban lehetőség az alosztályok kezelésére több is :
1. Készítsünk minden alosztály számára egy önálló relációt. Az eredeti osztályhoz készített reláció tartalmazza mind-
azokat az attribútumokat, amelyek minden egyedre érvényesek, míg a többi az eredeti osztály kulcs attribútumait,
és az új, csak arra az alosztályra jellemző attribútumokat.
Ez a megközelítés megfelel az E/K modell alosztályainak, hiszen így egy egyedet több reláció együtt ír le. Minden
egyed azokban a relációkban szerepel egy-egy sorként, amelyben van rá vonatkozó információ.
Előnye a módszernek, hogy nyomon lehet követni, hogy melyik egyed hova tartozik. Hátránya viszont, hogy egy
egyed tulajdonságainak összegyűjtéséhez végig kell nézni több relációt is.
2. Készítsünk minden egyes alosztálynak egy olyan relációt, amely tartalmazza az ő összes attribútumát, beleértve az
örökölt attribútumokat is. Tulajdonképpen ezt a módszert alkalmazza az ODL és a PostgreSQL is.
Előnye, hogy minden egyed pontosan egy relációban található, és ott fel van sorolva minden tulajdonsága. Hátránya,
hogy nehéz megtalálni az egyedet a sok reláció között, és esetleg elég lenne csak az alap relációban keresni az előző
módszer esetén, ha csupán olyan információ érdekel bennünket, amely onnan örökölt attribútumban van tárolva.
3. Egyetlen relációba gyűjtsük össze az összes alosztály valamennyi attribútumát. A nem minden alosztályban szerep-
lő attribútumokra engedjük meg, hogy üres legyen.7 Amennyiben az adott egyednek nincs ilyen attribútuma, akkor
azt üresen hagyjuk.
Persze ha az alosztályok sok új tulajdonságot adnak meg, ugyanakkor az egyedek többsége nem az alosztály-
ba, hanem az eredetibe tartozik, akkor ennek sok olyan sor lesz az értéke, amely tele lesz üres attribútumokkal.
Amennyiben az adatbázis-kezelő a sorok tárolására a tartalmuktól függetlenül fix adatterületet használ, akkor ez fe-
lesleges helypocsékolást is eredményezhet, azonban összehasonlítva a sok relációval és az azokon keresztüli többlet
keresési idővel, talán mégis így járunk jobban.
Megjegyzendő, hogy elképzelhető, hogy a PostgreSQL is az öröklésekkel kialakított relációkat valójában egy re-
lációban így tárolja, csak feljegyzi, hogy logikailag melyik relációba tartozik az adott sor. Így a keresést olyan
gyorsan meg tudja oldani, mintha egyetlen relációt használna, azonban logikailag megőrzi az osztály-hiererchiát.
Azonban azt tudni kell, hogy a PostgreSQL van olyan profi adatbázis-szoftver, hogy az egyes sorok tárolását ne
azonos hosszúságon végezze, tehát itt az üres attribútumok fizikailag kisebb helyen lesznek tárolva, mint az értékkel
rendelkezők. . .
Mint a fentiekből is látható, az adatbázis megtervezése nem egy könnyű feladat. Éppen ezért komolyabb adatbázisok
tervezéséhez nem érdemes a megfelelő előképzettség nélkül hozzáfogni. Ráadásul a fentiek csupán ízelítőül szolgáltak
az adatbázis megtervezéséhez. Az így készült adatmodellekben még lehetnek olyan hibák, amelyek miatt az adatbázis
nem megfelelő relációkból fog állni. Ezért még egy lépést el kellene végezni, a normalizálást. Erről azonban nem ejtünk
szót, mert ez az a pont, ahonnan már a megértéshez olyan háttérismeretekre is szükség lehet, amelyek túlmutatnak a
középiskolában tanított ismereteken.
Ehelyett az eddigieket egy konkrét – a már említett bolti nyilvántartás – adatbázis bemutatása következik. Majd e
dokumentum további részében az SQL, majd a későbbi fejezetekben a PHP adatbázisra épülő részének bemutatására
használt példákban ezt az adatbázist fogjuk használni.
7 Majd később látni fogjuk, hogy az adatbázis-kezelő szoftverek megengedik egy speciális érték, az üres érték használatát ilyen esetekre.

216
15.5. Példa az adatbázis tervezésre
Vegyünk példának egy egyszerű élelmiszerboltot, ahol különféle élelmiszereket árusítanak. Vannak köztük előre cso-
magolt – bonthatatlan –, és szabadon kimérhető árucikkek is. Ha a készlet egy bizonyos mennyiség alá csökken, akkor
szeretnénk, ha a rendszer, amit készítünk az adatbázis fölé, automatikusan – vagy félig automatikusan – gondoskodna az
áru utánrendeléséről is. Ehhez nyilván kell tartani minden árura azt a mennyiséget, amelynél a pótlásról gondoskodni kell,
valamint annak a szállítónak az adatait is, akitől az adott terméket rendeljük.
Szeretnénk nyilvántartani a napi forgalmat is, és azt is hogy mi mennyibe kerül. Mivel több pénztárunk is van, szeret-
nénk a napi forgalmat pénztárankénti bontásban is megnézni.
Továbbá nem szabad megfeledkeznünk arról sem, hogy a termékek között különböző ÁFA-tartalmúak is lehetnek.
Mivel azonban az ÁFA értéke akármekkora nem lehet, célszerű a lehetséges értékeket külön nyilvántartani. Ez egyrészt
lehetővé teszi, hogy az esetleges változás esetén gyorsan át lehessen árazni mindent, másrészt a fölösleges redundanciából
eredő problémák is elkerülhetőek vele.
A fentiek alapján tehát a következő egyedhalmazokra lesz szükségünk :
• Termék : egyede egy adott termék, amelynek különböző tulajdonságait nyilván kell tartanunk.
• Mennyiség : az egyes termékekből éppen raktáron levő mennyiség. Lehetne az előzővel azonos egyedhalmaz, de a
különválasztása lehetővé teszi, hogy a termékek állandó adatait ne kelljen minden vásárláskor vagy árubeszerzéskor
bántani.
• Szállító : az egyes szállítók adatai az utánrendelésekhez.
• ÁFA-kategóriák: Az egyes lehetséges ÁFA-kategóriák tárolására szolgál.
• Számla : Az egyes napokon készült számlák adatai.
• Eladás : az egyes eladott tételek, amelyekből egy számlához több is tartozhat.

217
16. fejezet

Az SQL nyelv

Ebben a fejezetben konkrét példákat is használva a jelenleg legelterjedtebb, sőt már az adatbázis-lekérdezés szabványának
számító lekérdező nyelvvel, az SQL-el ismerkedünk meg. Az SQL a Structured Query Language, vagy más szakirodalom
szerint a Standard Query Language rövidítése. Akármelyik kifejezést vesszük is, az egyértelműen kiderül, hogy egy
egységes nyelvet biztosít az adatbázisban található információkhoz való hozzáférésre.
Az SQL tulajdonképpen a relációs adatmodellre épül. A fő utasítása, a később részletesen ismertetendő SELECT
tulajdonképpen az ebben a dokumentumban – komoly matematikai háttérigénye miatt – nem ismertetett relációs algebra
műveleteit valósítja meg, de még azoknál is valamivel többet tud. Számunkra a lényeg ebben mindössze annyi, hogy
néhány – angolul könnyen olvasható – utasításon keresztül biztosít jól átlátható hozzáférést az adatbázishoz.
Mielőtt az SQL részletes megismerésébe belekezdenénk lássunk néhány egyszerű példát, hogyan is lehet a segítségé-
vel az adatbázisban tárolt információkhoz hozzáférni. A [5]-beli filmes adatbázis példáját követve szeretnénk megtudni,
hogy a Disney stúdiónak milyen 1990-ben készült filmjei vannak az adatbázisunkban nyilvántartva. Ehhez használható a
következő SQL utasítás:

SELECT *
FROM Film
WHERE stúdiónév = ’Disney’ AND év=1990;

Aki tud angolul, annak számára talán nem is túl nehéz megfejteni, hogy mit is jelent a fenti utasítás. Aki nem tud
angolul, az a fejezet későbbi részein megismerheti. Először azonban – a legtöbb adatbázis-kezelésről szóló könyvvel
ellentétben – érdemes megismerni az SQL-nek azt a részét, amellyel létre lehet hozni az adatbázist, hiszen enélkül nehéz
kipróbálni a lekérdező példákat is.
Mindenekelőtt azonban ejtsünk pár szót a legelterjedtebb adatbázis-kezelő szoftverekről, amelyek az SQL segítségével
használhatóak :
Oracle Az Oracle egy nagyon profi, kereskedelmi adatbázis-szerver, amelyhez a megfelelő jogosultsággal rendelkező
felhasználók egy egyszerű UNIX-terminálon keresztül is csatlakozhatnak. Szöveges képernyőn SQL utasításokat
kiadva lehet dolgozni. De biztosít más hozzáférési felületeket is, amelyeken keresztül szintén SQL utasításokon
keresztül férhetünk hozzá az adatbázisokhoz.
PostgreSQL A PostgreSQL a kaliforniai Berkeley egyetem által kifejlesztett POSTGRES nevű objektum-orientált adat-
bázis-kezelő nyílt kódú változatából fejlődött ki. A POSTGRES eredetileg nem az SQL nyelvet használta, de a
PostgreSQL-ben az eredetileg használt nyelvet lecserélték az SQL-re, megtartva az akkor már nagyon sokat tudó
POSTGRES eredeti tudását.
A PostgreSQL az SQL szabványt maradéktalanul ismeri. A legtöbb Linux rendszernek része, de a forráskódja az
internetről letölthető, és bármely Linux vagy egyéb UNIX-rendszerre feltelepíthető. Használati módja hasonlít az

218
Oracle-éhez, de nyilván valamivel kevesebb támogatást nyújt a felhasználóknak. A nyílt kódú adatbázis-kezelők
közül ez számít a legprofibbnak.
MySQL Egy mostanában fejlődő nyílt kódú adatbázis-szerver, amely a legtöbb Linux rendszernek szintén része. Még
nem valósítja meg a teljes SQL szabványt. Az egyik legnagyobb hiányossága az alkérdések hiánya. Gyorsasága és
könnyű kezelhetősége – és talán a nagyon kényelmesen használható webes felülete, a PHPMyAdmin – miatt mégis
elég népszerű, legalább annyi helyen alkalmazzák, mint a PostgreSQL-t.
DBase, FoxBase, FoxPro Bár ezek a DOS-os időkből megmaradt programok nem valódi adatbázis-kezelők, hiszen egy
adatbázishoz csak egy felhasználó férhet egyszerre hozzá, mégis érdemes megemlíteni a rá épülő információs rend-
szerek nagy száma miatt. Teljes SQL megvalósítással soha nem rendelkeztek, azonban az alapvető utasításokat
ismerték. Saját nyelvük mellett egy rendkívül korlátozott SQL megvalósítást is lehetett bennük használni.
MS Access Ez a program valójában a DBase-családhoz hasonlóan nem nevezhető adatbázis-kezelőnek. Két okból kell
mégis megemlíteni:
1. A jelenleg érvényes érettségi követelményrendszert éppen ez miatt a szoftver miatt alakították ki olyanra,
amilyen, hogy lehetőleg semmilyen más programmal ne lehessen olyan jó eséllyel megoldani az adatbázis-
kezelési feladatot, mint az MS Accessel.1
2. Az MS Accessben is van lehetőség SQL-szerű lekérdezésekre. Azért csak SQL-szerűek ezek, mert a Microsoft
szokása szerint semmibe vette az Access megalkotásakor is a kialakult szabványokat, és az Access SQL
változata sok ponton eltér a szabványtól. Azonban tény, hogy van SQL benne, amelyet az érettségin ki lehet
használni, hogy ne kelljen az Access átláthatatlan menürendszerében elveszni, amikor valamilyen lekérdezést
kell létrehozni. Sajnos csak a lekérdezésnél van erre lehetőség. . .
Valójában azonban az MS Access nem adatbázis-kezelő, hanem egy „játékprogram”, amellyel „adatbázis-kezelést
lehet játszani”. De az egyik legfontosabb követelménynek nem felel meg : ha egy adatbázist megnyitnak egy gépen,
akkor más felhasználó számára már nem elérhető. . .
Ennyi bevezető után ideje belevágni az SQL megismerésébe. Mint a fentiekből talán már kiderült, az egyes adatbázis-
kezelő szoftverek több-kevesebb eltéréssel valósítják meg az SQL szabványt. Hogy ez a „tankönyv” gyakorlatiasabb
legyen, nem az SQL szabványt, hanem a PostgreSQL-beli megvalósítását fogjuk ismertetni. Azért pont ezt, mert ez
egy ingyenes adatbázis-szerver, amelynek elég bőséges dokumentációja van – amely történetesen ugyanazzal a LATEX
szövegszerkesztő rendszerrel készül, mint ez a dokumentum. Aki az internetről, a ftp ://ftp.postgresql.org/pub/ címről tölti
le, az megtalálhatja angol nyelven. Az admin-*.pdf-ben (a csillag helyén a verziószám található) a telepítés módja
is megtalálható. A további példákat a legegyszerűbben a parancsorból kiadott psql paranccsal elérhető kliensből lehet
majd kipróbálni. Feltételezzük a továbbiakban, hogy rendelkezésre áll hozzá egy adatbázis a szükséges jogosultságokkal.2
A fentiek alapján tehát a fejezet további részében leírtak elsősorban a [6] valamely „kötetében” leírt információkra,
valamint saját tapasztalatra épülnek.

16.1. Az SQL alapvető szintaxisa


Mielőtt belekezdenénk az utasítások megismerésébe, ejtsünk még néhány szót azok nyelvtani szabályairól is !
Az SQL nyelv bemenete minden esetben utasítások egy vagy több elemű sorozatából áll. Egy utasítás szavak és egyéb
szimbólumok egy pontosvesszővel lezárt sorozata.3
1 Igazából éppen ezért nincs semmi értelme az érettségin az adatbázis-kezelésnek, hiszen a használandó program nem is felel meg az adatbázis-

kezelőkkel szemben támasztott követelményeknek, így eleve a feladatok sem felelnek meg a valódi adatbázis-kezelés igényeinek.
2 Ezen a ponton megjegyzendő, hogy bár fentebb az szerepelt, hogy a legtöbb Linux rendszer mind ezt, mind a MySQL-t tartalmazza, úgy tűnik, a

Mandrake 10-ből mindkettőt kihagyták, bár a 9.2-es verzióban még szerepeltek. Ha olyan Linux disztribúciót használunk, amelyből hiányzik, a fenti
címről letölthető és telepíthető minden további nélkül. Persze a telepítés igényelhet néhány további csomagot, amelyeket szükség esetén szintén le kell
tölteni az internetről. . .
3 Magyarra fordítva ez azt jelenti, hogy minden SQL utasítást pontosvesszővel kell lezárni, és egyszerre több ilyen utasítást is begépelhetünk.

219
A „szavak és egyéb szimbólumok” lehetnek:
• az SQL nyelv kulcsszavai, amelyeket írhatunk akár kis- akár nagybetűkkel. A továbbiakban ebben a dokumentum-
ban az egyéb szakirodalomban is alkalmazott módon csupa nagybetűs írással jelezzük, hogy mik a kulcsszavak, de
ezek ténylegesen írhatóak kisbetűvel is.
• azonosítók, vagy idézőjeles azonosítók. Akkor kell idézőjelbe tenni, ha egyébként nem lenne egyértelmű, hogy hol
a vége. Ha egyértelmű, hol a vége, akkor is idézőjelbe lehet tenni, de ilyenkor nem kötelező.
• konstansok, melyek valamilyen típusú értéket jelölnek (ezekre később még visszatérünk).
• speciális szimbólumok.

A fent felsorolt szimbólumokat egymástól általában egy vagy több szóköz vagy más szóköznek minősülő karakter (hiva-
talosan ezeket nevezük „whitespace”-nek) választja el. Ilyen elválasztó lehet a megjegyzés is, amely két kötőjelből áll,
amely után a következő újsor-jelig minden megjegyzésnek minősül.

220
17. fejezet

Adatdefiníciós utasítások

Azokat az SQL utastásokat, amelyekkel az adattáblák szerkezetét lehet meghatározni/módosítani, adatdefiníciós utasítá-
soknak nevezzük. Ezek az utasítások általában a CREATE vagy az ALTER kulcsszóval kezdődnek. Azok az utasítások,
amelyekkel valamit törölni lehet, a DROP kulcsszóval kezdődnek.
Ezután általában annak az objektumnak a megnevezése következik, amelyre az utasítás vonatkozik.
Ilyen módon tehát egy új adatbázist létrehozni1 a következő utasítással lehet :
CREATE DATABASE név;
A fenti utasítás a név nevű adatbázist hozza létre. Törölni ezt az adatbázist a következő paranccsal lehet :
DROP DATABASE név;
Ha már van egy adatbázisunk, akkor azon belül létrehozhatunk adattáblákat (relációk), vagy egyéb objektumokat.
Ilyen objektum lehet például egy függvény, amely több SQL utasítást hajt végre, majd valamilyen adatot ad eredményül
(ezekkel egyenlőre nem foglalkozunk).
A PostgreSQL-ben egyszerre csak egy adatbázist használhatunk. Ha valahogy mégis szeretnénk rendszerezni az adat-
tábláinkat ezen belül, arra a – csak a PostgreSQL-ben definiált – sémákat használhatjuk.
A séma valójában egy különálló halmaza az adatbázis objektumainak. Minden név a sémán belül érvényes, így egy
adatbázisban előfordulhat ugyanolyan nevű objektum minden egyes különböző sémában legfeljebb egy-egy alkalommal.
A sémán belül viszont már minden névnek egyedinek kell lennie, éppúgy mint a sémák nevének egy adott adatbázison
belül.
Ha létre akarunk hozni egy sémát például dvdtár néven, akkor adjuk ki a következő parancsot :
CREATE SCHEMA dvdtár;
Ha a fenti sémát törölni akarjuk, adjuk ki az alábbi parancsot :
DROP SCHEMA dvdtár;
Azonban a fenti parancsot jól gondoljuk meg: minden megerősítés nélkül történik meg a törlés, amely végleg megszünteti
a séma összes objektumát is!
A létrehozott dvdtár sémába úgy tudunk adattáblákat felvenni majd azokra később hivatkozni, ha az adattábla neve
előtt megadjuk a séma nevét. Így a dvdtár sémában levő kiadók adattáblára hivatkozni például a dvdtár.kiadók
névvel lehet, azaz a séma nevét meg kell adni, majd ezt egy pont után követi az objektum neve.
Amennyiben nem hozunk létre sémát, akkor is van egy séma, amelynek neve public. Ez az alapértelmezett séma, ha
nem adunk meg sémanevet, akkor ezt használja a rendszer.
1 Egy sokfelhasználós rendszerben új adatbázist nem hozhat létre akárki, csak a rendszeradminisztrátor (superuser). A saját gépünkre telepített

rendszerben általában mi magunk vagyunk a superuser is.

221
17.1. Adattáblák létrehozása
17.1.1. Pár szó az adattáblákról általában
Mint minden relációs adatbázis-kezelőben, így a PostgreSQL-ben is a legfontosabb adattárolási egység az adattábla.2
Minden egyes adattábla megfelel a relációs adatmodell egy-egy relációjának. Tulajdonképpen logikailag úgy épül fel,
mint bármelyik másik táblázat: vannak sorai és oszlopai. Oszlopai száma a létrehozásakor meghatározott – hiszen minden
oszlop a reláció egy attribútumát adja –, míg sorainak száma akárhányszor megváltozhat – minden sor, amelyet a relációs
adatbázis-kezelőkben rekordként emlegetnek, egy-egy egyed adatait tartalmazza.
Az egyes sorok tényleges sorrendje nem tartalmaz különösebb információt : A táblázat sorait tekintsük úgy, mint egy
halmaz elemeit, amelyek semmilyen szempont szerint nincsenek rendezve. Erről a PostgreSQL használata során könnyen
meggyőződhetünk, ha egy adattáblába sok rekordot felveszünk, majd egy részüket módosítjuk, töröljük, újakat hozunk
létre. Hamar tapasztalhatjuk, hogy kilistázáskor, ha nem adunk meg rendezési feltételt, a sorok teljesen összekeveredve
jelennek meg. Ez annak következménye, ahogyan az adatmódosítások történnek.
A másik probléma, hogy nincsen rá semmi garancia, hogy az adattáblának nincs két teljesen megegyező rekordja. Ez
halmaznál nem fordulhatna elő, de valójában nem is halmazként, hanem multihalmazként kell tekinteni az adattáblákat,
amely azt jelenti, hogy ugyanaz az elem többször is előfordulhat benne. A probléma ezzel az, hogy ha a két azonos rekord
egyikét akarjuk törölni vagy módosítani, az lehetetlen. Ezt a problémát a PostgreSQL egyedi objektum-azonosító alkal-
mazásával oldja meg, amely egy alaphelyzetben nem látható, de minden adattáblában jelenlevő oid nevű attribútumban
található, amely minden rekordot különböző értékűvé tesz.
Az egyes rekordok mezőkből állnak. A mezők minden rekordban azonos sorrendet követnek, és a reláció megfelelő
attribútumának felelnek meg. Tehát az adattábla egy adott oszlopát mező névvel illethetjük.
Minden mezőnek van valamilyen típusa, amellyel egy értelmezési tartomány megszorítást adunk az adott mező érté-
keire, hiszen a mező típusa meghatározza a mezőnek adható értékek lehetséges halmazát. Van rá módszer, hogy még ezt a
lehetséges halmazt is tovább szűkítsük, amire majd később visszatérünk. Az egyes lehetséges típusokat a 17.1.3 fejezetben
részletezzük. Röviden az alapvetőbb típusok:
• Egész számok (integer)
• Általában számok (numeric) meghatározott pontossággal
• Szöveges adatok (text, char)
• Dátum (date) egy meghatározott intervallumon belül
• Egyéb időadatok (time, timestamp)

• Igaz/hamis érték (boolean)


Ahhoz, hogy egy adattáblát használni tudjunk, létre kell azt hozni. Ehhez meg kell adni legalább a nevét, és a leendő
oszlopainak nevét és típusát. Mindez a CREATE TABLE utasítással lehetséges. Példaként egy példatábla nevű adattábla
létrehozása, amely tartalmaz egy szöveges egy nevű, és egy egész számokat tároló kettő nevű mezőt, a következőképpen
lehetséges :
CREATE TABLE példatábla (
egy text,
kettő integer
);
2 Bár a PostgreSQL nem egyszerűen relációs adatbázis-kezelő, hanem objektum-orientált adatbázis-kezelő is egyben, de relációs adatbázis-
kezelőként is nagyon jónak számít, és a számunkra most ez a fontos.

222
Mint látható, a CREATE TABLE kulcsszavak után a tábla nevét adjuk meg, majd zárójelek között, vesszővel elvá-
lasztva felsoroljuk a tábla mezőit (és egyéb adatait). A mezők megadása a leendő azonosítójuk, majd a leendő típusuk
megadásával történik.
Az egy táblában megadható oszlopok (mezők) számára a PostgreSQL egy elég nagy maximális számot ad meg, amely
a mezők típusától függően 250 és 1600 között változik. Normális adatbázisban ritkán szerepel olyan adattábla, amely
ennyi mezőt igényel, így ez a határ nagyon kényelmesnek mondható.
Amennyiben a táblára többé nincs szükségünk, akkor azt eldobhatjuk a DROP TABLE táblanév parancs segítségével,
azonban ez minden megerősítés nélkül örökre törli a táblát minden tartalmával együtt, így jól gondoljuk meg, mikor adjuk
ki !
Amennyiben kiderül, hogy hibásan hoztuk létre az adattáblát, akkor még van lehetőség az ALTER TABLE parancs
használatával a módosítására, de nem lehet akármit módosítani. Mező típusát például nem engedi a PostgreSQL mó-
dosítani (a MySQL például igen), így legfeljebb törölhetjük azt, majd egy új mezőt vehetünk fel ugyanazzal a névvel.
Azonban a már felvitt rekordok esetében ennek a mezőnek a tartalma ilyenkor elveszik, hacsak nem mentjük el valahova
addig. Ilyen esetben egyszerűbb megoldás lehet, ha létrehozunk egy új adattáblát a módosításnak megfelelő szerkezettel,
ebbe átmásoljuk az adatokat, töröljük az eredeti táblát, majd az új táblát lemásoljuk az eredeti névvel. Ennek módjára is
látunk még később eszközöket.

17.1.2. A CREATE TABLE utasítás


A CREATE TABLE utasítás szintaxisa – a jelentőségéből fakadóan – elég bonyolult. Ha elsőre nem minden világos, nem
kell tőle megijedni – másodszorra sem lesz minden az. . . Nem is minden részével kell tisztában lenni a használatához,
így egyenlőre mi is csak a legfontosabb részeire fogunk koncentrálni. Azonban előbb következzék a teljes szintaxis :3

CREATE [ [ LOCAL ] { TEMPORARY | TEMP} ] TABLE táblanév (


{ oszlopnév adattípus [ DEFAULT alapértelmezett_kifejezés ]
[ oszlop_feltétel [,...] ]
| tábla_feltétel } [,...]
)
[ INHERITS ( szülő_tábla [,...] ) ]
[ WITH OIDS | WITHOUT OIDS ]

ahol az oszlop_feltétel lehet:


[ CONSTRAIN feltételnév ]
{ NOT NULL | NULL | UNIQUE | PRIMARY KEY |
CHECK (logikai kifejezés) |
REFERENCES reftábla [ (refoszlop) ] [ MATCH FULL | MATCH PARTIAL ]
[ ON DELETE teendő ] [ ON UPDATE teendő ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
a tábla_feltétel pedig lehet:
[ CONSTRAIN feltételnév ]
{ UNIQUE (oszlopnév [,...] ) |
PRIMARY KEY (oszlopnév [,...] ) |
CHECK (logikai kifejezés) |
FOREIGN KEY (oszlopnév [,...] ) REFERENCES reftábla [ (refoszlop [,...] ) ]
[ MATCH FULL | MATCH PARTIAL ] [ ON DELETE teendő ] [ ON UPDATE teendő ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
3 A szintaxismegadás egyik szokásos módját használjuk itt a [6] alapján. Ebben a szögletes zárójelek az elhagyható részeket, a kapcsos zárójelek kö-

zött függőleges vonallal elválasztott részek pedig választható alternatívákat jeleznek. A nagybetűs szöveg a pontosan megadott módon írandó szöveget,
a kisbetűs a később kifejtendő részeket jelzi.

223
A fenti szintaxisú utasítással tehát adattáblát lehet létrehozni. Ez az adattábla a tablanév nevet fogja viselni. A záró-
jelben felsorolt oszlopok – a megadott típussal – a felsorolásuk sorrendjében lesznek a tábla oszlopai, a későbbiekben is
ilyen sorrendben kerülnek felhasználásra minden olyan esetben, amikor nem adjuk meg az egyes utasításokban a használni
kívánt oszlopokat.
Mint látható, minden oszlophoz rendelhető a DEFAULT kulcsszó segítségével egy alapértelmezett érték, valamint egy
feltétel. Ez utóbbi, és az oszlopok megadása után használható, az egész táblára érvényes feltételek valósítják meg a meg-
szorításokat (lásd 15.3.5 fejezet, 210. oldal), köztük a kulcsok definiálását is. Ezeknek a feltételeknek nem mindegyikét
fogjuk megismerni, bár egy igazán profi adatbázisban nagyon hasznos ezek ismerete is.
A feltételekkel azt lehet vizsgálni, hogy új rekord felvitelekor illetve egy rekord módosításakor az újonnan létrejövő
rekord megfelel-e a megadott feltételeknek. A vizsgálat ebben a két esetben automatikusan megtörténik, és ha valamely
feltétel nem teljesül, akkor hibaüzenet keletkezik, és az adatfelvitel illetve -módosítás nem történik meg.
Az oszlopdefinícióhoz tartozó feltétel csak arra az oszlopra vonatkozhat, amelyik definíciójában szerepel. Éppen azért
van lehetőség oszlopdefiníción kívül is feltételek megadására, amelyek az egész táblára vonatkozhatnak, mert sokszor
olyan feltételek teljesülését várjuk el, amelyek több oszlop értékétől is függenek. Ilyen például, amikor a tábla kulcsát
több mező együttesen alkotja. Ezt csak tábla feltételként lehet megadni.
Van néhány specialitása még a CREATE TABLE utasításnak, amelyek nélkül ugyan meg lehet lenni, de egy komo-
lyabb információs rendszer készítésekor hasznosak lehetnek. Ilyen például az ideiglenes tábla létrehozása, amelyben egy
tranzakció alatt lehet bizonyos adatokat összegyűjteni úgy, hogy más tranzakció azokhoz ne férhessen hozzá. A másik
ilyen specialitás a PostgreSQL tábla-öröklődése, amelyet az INHERIT (oszlopnév) résszel lehet megadni. Ezekkel most
nem foglalkozunk.

17.1.3. Az oszlopok lehetséges típusai


A PostgreSQL jóval többféle adattípussal rendelkezik, mint amit az SQL szabvány előír. Azonkívül a CREATE TYPE
utasítással bármikor létre lehet hozni új adattípust – amit megfelelő eszközökkel definiálni kell. Azonban ezek a típusok
a bennük tárolható információ alapján kategorizálhatóak. E szerint a csoportosítás szerint nézzük végig a legfontosabb
típusokat a következőkben.

Számok
Számok tárolása a numerikus típusokban lehetséges. Ezek lehetnek 2, 4, 8 byte méretű egészek, 4 vagy 8 byte méretű
lebegőpontos számok, és fix pontosságú decimálisan tárolt számok. A következő táblázat mutatja a szám-típusokat :
Típusnév tárolási méret leírás pontosság
smallint 2 byte kis méretű egész számok tárolására −215 . . . 215 − 1
integer 4 byte az általában használt egész típus −231 . . . 231 − 1
bigint 8 byte nagy méretű egész számok tárolására −263 . . . 263 − 1
decimal változó pontosan a felhasználó által megadott pon- nincs korlát
tosságot használja
numeric változó pontosan a felhasználó által megadott pon- nincs korlát
tosságot használja
real 4 byte lebegőpontos számok tárolására 6 tizedes szám-
jegy pontosságú
double precision 8 byte lebegőpontos szám 15 tizedes szám-
jegy pontosságú
serial 4 byte automatikus növekmény 1 . . . 231 − 1
bigserial 8 byte automatikus növekmény 1 . . . 263 − 1

Egész típusok A smallint, integer, bigint típusok egész számokat tárolnak, kettes komplemens alakot hasz-
nálva a negatív számok ábrázolására. Ebből adódik ábrázolási intervallumuk. Amennyiben az intervallumon kívüli számot

224
akarunk értékül adni az ilyen típusú mezőnek, az hibaüzenetet eredményez. A bigint típus a PostgreSQL bővítése az
SQL-hez képest, a másik kettő az SQL által is definiált típus.

Decimális típusok A numeric – és a vele azonos decimal – típus egészen 1 000 decimális számjegyig képes szám-
értékek tárolására megadott pontossággal, és azokkal pontos számításokat végezni. Pénzügyi adatok tárolására ez a típus
ajánlott, mivel itt nem léphet fel kerekítési pontatlanság. Azonban a lebegőpontos számokhoz képest jóval lassabban
történik a számítás ezzel a típussal.
Mind a teljes méretet (a számjegyek számát), mind a törtrészre jutó tizedesjegyek számát meg lehet adni. Ehhez a
következő formát kell használni a típus megadásakor :
NUMERIC(teljes, törtrész)
A teljesnek pozitívnak kell lennie, míg a törtrész lehet nulla (egész pontosság), amely esetben a vesszővel együtt elhagy-
ható :
NUMERIC(teljes)

Ha csak a NUMERIC kulcsszót adjuk meg, akkor tetszőleges pontosságú és hosszúságú számot megadhatunk az adott
rendszer korlátain belül. Ezt azonban jobb kerülni. . .
Ha túllépjük a beállított intervallumot, a rendszer megpróbálja kerekíteni az értéket. Ha ez nem sikerül, az eredmény
egy hibaüzenet lesz.

Lebegőpontos típusok A valós számoknak a hagyományos programozási nyelvekben használatos ábrázolási módja
a lebegőpontos szám. Ez a matematikában normál alak néven ismert fogalomhoz hasonlít : van egy mantissza és egy
karakterisztika, amely általában azt adja meg, hogy a mantisszát a 2 hanyadik hatványával kell megszorozni. Azért is
hívják lebegőpontos ábrázolásnak, mert a tizedes pont helye nincs rögzítve.
A mantissza ábrázolására rendelkezésre álló bitek száma meghatározza, hogy hány jegyű pontosság lehetséges, míg a
karakterisztika ábrázolására használható bitek száma az intervallum nagyságát befolyásolja.
Az ilyen típusú értékekkel történő számolásnál mindig számolni kell a kerekítésből adódó számítási hibákkal, amelyek
folyamatosan halmozódhatnak is. Például ha egy nagyon kicsi számot és egy nagyon nagy számot összeadunk, annál
nagyobb a valószínűsége, hogy eredményül magát a nagyobb számot kapjuk, minél nagyobb a két szám nagyságrendje
közötti különbség. Ha ez a különbség több, mint ahány értékes jegye van a mantisszának, akkor a kisebbik szám teljesen
elveszik a számításokban a kerekítés eredményeként.4
Az adott gép processzorának képességeitől függ minden esetben az ábrázolási pontosság és a lehetséges intervallum
egyaránt. A PostgreSQL – ahogyan az SQL szabvány is – két különböző lebegőpontos típust ismer : a kisebb pontosságú
real és a nagyobb pontosságú double precision típust.

Automatikusan növekvő érték Szinte minden adatbázis-kezelő ismer olyan eszközt, amellyel valamely mező értékét
folyamatosan növekvő értékkel automatikusan fel lehet tölteni. A MySQL erre az egész típusú mezőhöz rendelhető „auto-
increment” tulajdonságot alkalmazza. Ezzel szemben a PostgreSQL egy külön típust alkalmaz, amelynek neve serial.
Ez valójában persze ugyanúgy egy egész típust jelent, amelyhez azonban a rendszer egy egyedi sorozatot generál, amely-
nek minden újabb adatfelvitelnél a következő értékét rendeli.
Ilyen sorozatot későbbi használatra mi magunk is létrehozhatunk a CREATE SEQUENCE utasítással. Ilyen módon
az alábbi adattábla definíció

CREATE TABLE példa (


oszlop SERIAL
);
4A kerekítésből eredő pontatlanság nem csupán a törtjegyeket érintheti : ha például nyolc jegy pontossággal lehet a számokat ábrázolni, akkor egy
109 nagyságrendű számnál már elveszítjük az egyes helyiértéken álló számjegyet is !

225
csupán rövidítése a következőnek:
CREATE SEQUENCE példa_oszlop_sorozat;
CREATE TABLE példa (
oszlop integer DEFAULT nextval(’példa_oszlop_sorozat’) NOT NULL
);
Az oszlopdefinícióhoz rendelt DEFAULT rész egy alapértelmezett értéket rendel az oszlophoz. Amennyiben az adat-
felvitelnél ennek a mezőnek nem adjuk meg az értékét vagy a DEFAULT kulcsszót adjuk neki értékül, akkor az itt meg-
adott érték lesz az értéke a mezőnek. A nextval függvény pedig a sorozat következő (egész) értékét veszi. Ilyen módon
egyedi sorszámmal lehet könnyedén ellátni egy adattábla rekordjait kulcs gyanánt.
A serial kulcsszó egy integer típusú automatikus növekményű oszlop definiálását teszi lehetővé, míg a
bigserial egy bigint típusú oszloppal teszi ugyanezt.

Pénzügyi típus
A money típus gyakorlatilag a numeric típusnak egy olyan felülettel ellátott (elavultnak számító) változata, amelyben
lehetőség van a beállított nyelvtől függő tulajdonságok alkalmazására. Célszerű ennek ellenére helyette a numeric típust
alkalmazni (lásd 225. oldal).

Szöveges típusok
Az SQL két szöveges típust definiál, a változó és a fix hosszúságú karakterláncot. A PostgreSQL ezt kiegészíti még egy
olyan karakterlánccal, amelynek a hossza nincsen korlátozva. Az alábbi táblázat mutatja a használható típusokat :
Típusnév Leírás
character varying(n), varchar(n) Változó (de maximummal rendelkező) hosszúságú karakterlánc
character(n), char(n) Rögzített hosszúságú, szóközzel kiegészített karakterlánc
text Korlátlan hosszúságú karakterlánc
A táblázat első két sorában szerepelnek a szabványos típusok, amelyeknél zárójelben az n helyén minden esetben a
karakterlánc maximális hosszát kell megadni pozitív egész számként. Amennyiben a char(n) típusnak n-nél rövidebb
karaktersorozatot adunk értékül, akkor a karaktersorozathoz a szükséges számú szóközt fűzi a rendszer. A varchar(n)
esetén erre nem kerül sor. Mindkét típusnál ha n-nél hosszabb karaktersorozatot akarunk értékül adni a mezőnek, az
hibaüzenetet eredményez, kivéve, ha típuskonverzióra kényszerítjük a rendszert, amely esetben az első n karakter kerül
tárolásra.
Amennyiben a character típust hosszmegadás nélkül adunk meg (PostgreSQL-ben), az megegyezik a
character(1) megadásával. Szintén csak PostgreSQL-ben a character varying hosszmegadás nélkül a text
típushoz hasonlóan hosszkorlátozás nélküli karaktersorozatot jelent.
Egy text típusú mező értéke – a PostgreSQL által szükség esetén alkalmazott tárolási technikáknak köszönhetően –
akár az 1 GByte méretet is elérheti, így nem kell aggódnunk, hogy nem fér el a tárolandó szövegünk. Mint ahogy azon sem
kell aggódnunk, hogy egy-egy hosszú szöveg tárolása lelassítja a többi, rövidebb érték elérését, mivel erről is megfelelő
módszerekkel gondoskodik a rendszer.
A karakterláncok megadása egyszeres idézőjelek (aposztrófok) között történik. Ha a karaktersorozatban magában
szerepeltetni akarjuk az egyszeres idézőjelet, akkor meg kell duplázni azt. Például így :
tulajdonos = ’O’’Neil’
Ekkor a O’Neil szöveg kerül tárolásra.
A PostgreSQL használ még egy speciális típust, amely egyetlen byte karakterként való tárolását teszi lehetővé. Meg-
adása a következő: "char" (az idézőjel is lényeges !).

226
Bináris sorozatok
A bináris sorozat egy olyan karaktersorozat, amelyben bármilyen byte előfordulhat. Az azonosítója : bytea. Hossza nem
korlátozható. Tárolása úgy történik, hogy egy 4 byte méretű számláló a hosszát megadja, majd jönnek a byte-ok egymás
után.

Dátum és idő tárolása


A PostgreSQL és az SQL szabvány egyaránt a következő dátum/idő tárolására alkalmas típusokat ismeri :
timestamp : dátum és idő együttes tárolására időzónával vagy anélkül, 8 byte méreten mikroszekundum pontossággal.
interval : időintervallum (időtartam) tárolására, 12 byte méreten mikroszekundum pontossággal.
date : dátum tárolására, 4 byte méreten nap pontossággal.
time : napon belüli időpont tárolására időzónával vagy anélkül, 8 byte méreten (időzónával 12 byte méreten) mikrosze-
kundum ponossággal.
A timestamp, time és interval típusoknak zárójelben meg lehet adni egy pontosságot is, amely meghatározza a
másodperc törtrészének tizedes pontosságát is.
A PostgreSQL az időbélyeget 2000. január elsejétől számolja másodpercekben. A tároláshoz használt hely – és a
negatív számok használata – megengedi az időszámításunk előtti 4713. évtől egészen 1 465 001-ig terjedő időpontok
tárolását (a dokumentáció szerint). Ugyanakkor a date típus csupán 32 767-ig terjedő dátumokat enged meg (a kezdő
dátum ugyanaz). Ha van olyan, aki talál alkalmazást, amelyre ez nem elég, akkor annak külön érdemes gratulálni. . .
A dátum és idő bevitele gyakorlatilag speciális formátumú szövegként lehetséges. A PostgreSQL több formátumot
ismer, mint az SQL, így könnyebb dolgunk van ezt használva, azonban mégis érdemes megszokni az SQL-t, hogy más
rendszerben se legyünk gondban.
A dátum megadására az SQL a következő formát használja : ’2005-01-24’, azaz négy számjegyen az év, utána két
számjegyen a hónap, végül két számjegyen a nap, mindhárom adat között egy-egy kötőjellel. Ezen felül persze a Postg-
reSQL más formát is ismer, ezek megtalálhatóak a [6]-ban. . .
A time típus megadható időzónával vagy anélkül. Ha időzónával akarjuk használni, akkor a típus valódi neve
time (p) with time zone, ahol a (p) a pontosságot jelenti, amely elhagyható, vagy a p helyén a pontosság
értéke megadható 0 . . . 6 közötti egész számmal.
A megadásra íme néhány példa:
• ’04:05:06.789’: ezredmásodperces pontosság
• ’04:05:06’: másodperces pontosság
• ’04:05’: perces pontosság
• ’040506’: másodperces pontosság (szintén szabványos)
• ’04:05 AM’: ugyanaz, mint a ’04:05’, mivel az AM nem lényeges
• ’04:05 PM’: valójában délután 4 óra 5 perc lesz, mivel a PM 12 órát hozzáad az időhöz.
• ’allballs’: az éjfél egy speciális megadása (00 :00)
Amennyiben ehhez még az időzónát is meg akarjuk adni, akkor azt egy + vagy - jel után kell megtenni vagy csak
az órát megadva, vagy az órát és a percet kettősponttal elválasztva megadva. Másik módszer az időzóna megadására a
használt időzóna hárombetűs azonosítójának megadása.
Az időbélyegek (timestamp) megadása szintén lehet időzónával (with time zone) vagy anélkül. Megadható a
dátum és az idő fenti megadási módját kombinálva (köztük szóközt hagyva) :

227
’2005-01-24 07:30’
esetleg az időzóna megadásával kiegészítve. A típus megadásakor itt is megadható a pontosság 0 . . . 6 közötti értékkel.
Az időtartam (interval) megadása egy kicsit eltér az eddigiektől. Formája a következő :
mennyiség mértékegység [ mennyiség mértékegység ... ] [ irány ]
@ mennyiség mértékegység [ mennyiség mértékegység ... ] [ irány ]
Ahol a mennyiség egy előjeles szám, a mértékegység lehet second, minute, hour, day, month, year, decade,
century, millenium, vagy ezek egyértelmű rövidítése. Az irány lehet üres, vagy lehet ago. A @ elhagyható, jelentése
nincs. A különböző mértékegységekben megadott értékek összeadódnak a tárolás során.
Amennyiben nem adunk meg mértékegységet, akkor a megadott mennyiségek rendre nap, óra, perc, másodperc jelen-
tésűek lesznek. Például: ’1 12:59:10’ ugyanaz, mintha azt írtuk volna :
’1 day 12 hours 59 minutes 10 seconds’
Használhatunk a dátum és az idő megadására néhány speciális értéket is. A CURRENT_DATE, CURRENT_TIME és
CURRENT_TIMESTAMP változók például az éppen aktuális dátumot, időt illetve időbélyeget jelentik.
Az infinity és a -infinity minden ábrázolható időpontnál későbbi illetve korábbi időt jelent.
Az epoch érték megadása egyenlő a UNIX időbélyeg kezdőpontjának (1970. január 1. 0 óra) megadásával.
A now azt az időpillanatot tartalmazza, amikor az éppen folyamatban levő tranzakció elkezdődött. Ez tehát nem
feltétlenül azonos a tényleges rendszeridővel, lehet annál korábbi is egy több lépéses tranzakció esetén !
A today az adott napon nulla órakor érvényes időpontot jelenti. A tomorrow ugyanez a következő napra, míg a
yesterday az előző napra. Éjfelet (nulla órát) jelent a GMT (greenwich-i világidő) szerint a zulu, allballs és a z.
Megjegyzés. Még egy szót az ábrázolható dátumok intervallumáról. A PostgreSQL a dátum és idő adatokat Julián dátum-
ban számolja. Így bármely dátum egyértelműen ábrázolható i.e. 4713-tól kezdve, amely a Julián dátumok kezdőnapja.5
A végső dátum pedig a lehetséges ábrázolható értékek mérete miatt akkora, amekkora. Ez az ábrázolási mód azért is
hasznos, mert így nem fordulnak benne elő az Y2K néven ismerthez hasonló ábrázolási problémák.

Logikai típus
Az SQL definiál egy logikai típust is, amelyet azonban furcsa módon nagyon sok megvalósítás vagy mellőz, vagy na-
gyon különös módon valósít meg. A MySQL-ben például nincs logikai típus, hanem az SQL által egyébként nem ismert
felsorolással lehet ilyet gyártani.
A PostgreSQL az SQL-nek megfelelően definiálja a logikai típust, a szabványos boolean névvel. Két lehetséges
értéke a logikai hamis értékre a false, a logikai igaz értékre pedig a true konstans. Ezeken felül a definiálatlan logikai
értéket a null konstanssal lehet használni.
A null érték ezúttal több, mint csupán annyi, mint érték nélküli mező, mivel a logikai műveletek igazságtáblájában
definiálva van, hogy null érték esetén hogyan kell viselkednie a műveletnek.
Az igaz érték megadható a true kulcsszó mellett még a ’t’ és a ’true’ karaktersorozattal is, vagy a ’y’, ’yes’
és ’1’ karaktersorozatok valamelyikével is. A hamis érték hasonlóan megadható a false kulcsszó mellett a következő
karaktersorozatok valamelyikével: ’f’, ’false’, ’n’, ’no’, ’0’. Kiíráskor a t vagy az f betű jelenik meg logikai
típusú értéknél. A logikai típus tárolására a PostgreSQL 1 byte méretű helyet használ.
Mint említettük, a logikai műveleteknél figyelembe veszi a null értéket is az eredmény meghatározásakor a rendszer.
A három lehetséges művelet a logikai ÉS (and), a logikai VAGY (or) és a logikai tagadás not.
A logikai ÉS művelet eredménye abban az esetben, ha mindkét operandus igaz, igaz lesz. Ha a két operandus egyike
sem meghatározatlan és legalább az egyik hamis, akkor hamis lesz az eredmény. Ha pedig legalább az egyik operandus
értéke meghatározatlan, akkor az eredmény is meghatározatlan lesz.
5 Csillagászok éppen ezért szeretik a Julián dátumokat.

228
A logikai VAGY műveletnél már kicsit bonyolultabb a helyzet. Ha legalább az egyik operandus igaz, akkor az ered-
mény a másik operandus értékétől függetlenül igaz.6 Ha mindkét operandus hamis, akkor az eredmény is hamis, míg
meghatározatlan lesz az érték abban az esetben, ha mindkét operandus meghatározatlan, vagy ha az egyik meghatározat-
lan, a másik pedig hamis.
A logikai tagadás már jóval egyszerűbb: az igaz tagadása hamis, a hamis tagadása igaz, a meghatározatlan tagadása
pedig meghatározatlan marad.

Geometriai típusok
A PostgreSQL ismer néhány geometriai típust, amely kifejezetten térinformatikai alkalmazásokhoz használható. Segít-
ségükkel, valamint PHP-val történő képgenerálással akár egy interaktív térképet is lehet adatbázisra épülve készíteni
(tulajdonképpen ezt nevezzük térinformatikának, ha nagyon le akarjuk egyszerűsíteni a dolgot).
Mivel ez a PostgreSQL egy speciális kiegészítése az SQL-hez képest, ezért nem részletezzük, a [6]-ban a típusok
részletes ismertetésénél megtalálhatóak.

Hálózati adatok
Szintén rendelkezik a PostgreSQL olyan speciális típusokkal, amelyekben a hálózati címeket lehet tárolni. Ilyen a spe-
ciálisan IP-cím, IP-címtartomány, a hálókártya egyedi azonosítókódja (a MAC-address) tárolására szolgáló típus. Ezek
leginkább egy hálózat monitorozásának adatbázisban történő tárolására használható típusok. Szintén itt nem részletezendő
típusok.

Bitvektorok
Hasznos lehet azonban a bitvektorok tárolása. A logikai típus ugyebár egyetlen, legfeljebb három értékű logikai adat táro-
lására elpazarol egy egész byte-ot. Ha több logikai értéket szeretnénk tárolni, akkor azokat esetleg érdemesebb összefogni
egy bitsorozatba, és akár nyolc logikai értéket is tárolni egyetlen byte méreten. Erre alkalmas a bitvektor többek között.7
A bitvektor egyesek és nullák sorozataként adható meg. Két változata a fix és a változó hosszúságú bitsorozat. Előbbi
megadása a bit kulcsszó után zárójelben a bitek számának megadásával történik, utóbbi a bit varying kulcsszó után
várja a lehetséges maximális hosszúságot.
A fix hosszú bitsorozatnak mindig pontosan annyi bitből álló értéket kell eredményül adni, amennyi bittel definiálták.
A változó hosszúságú bitsorozatnak legfeljebb a megadott hosszúságú bitsorozatot lehet értékül adni.
Az érték konstansként történő megadása a karaktersorozatokhoz hasonlóan történik.8 A különbség az, hogy egy B
betűvel a nyitó aposztróf előtt meg szokás jelölni, hogy ez bitsorozat lesz. Például : B’010’. Szükség esetén megadható
a konstans típusa is az általános típuskonverziós eljárással : két kettőspont után a céltípus meghatározása. Például a 3 bites
bitvektort így lehet megadni: B’011’::bit(3).

Tömbök használata mezőtípusként


Általában az adatbázis-kezelők nem teszik lehetővé mezőtípusként összetett adatok használatát. A PostgreSQL azonban
ismeri a tömb típust, amely bizonyos esetekben nagyon előnyös lehet.
A tömb alaptípusa bármely egyszerű mezőtípus lehet, vagy akár lehet maga is tömb, többdimenziós tömbök létreho-
zását lehetővé téve ezzel. Íme néhány példa tömb típusú mezők definiálására :

CREATE TABLE tömbpélda (


egydimenziós integer[],
6 Tehát akkor is igaz az eredmény, ha a másik operandus meghatározatlan értékű, azaz null az értéke.
7 Másik hasznos alkalmazása a bitsorozatnak, a halmaz ábrázolása karakterisztikus vektor formájában. Ez valójában éppen azt jelenti, hogy a halmaz
minden lehetséges elemének megfelel egy bit, amely igaz értéke esetén az adott elem benne van a halmazban, hamis értéke esetén nincs benne. Ehhez
persze az összes lehetséges elemhez kell egy bit, ami bizonyos halmazfajták esetén nem tárolható.
8 Tulajdonképpen a karaktersorozatokat feldolgozó műveletekkel ezeket is fel lehet dolgozni.

229
kétdimenziós text[][]
);

Mint a példán is látható, a tömb megadása az alaptípus után írt szögletes zárójelpárral történik. Az adatok felvitele
ilyen adattípusba speciális formájú karaktersorozatokként történik. A tömb elemeit egy kapcsos zárójelpár fogja közre,
amelyen belül az adott tömbelemet a szomszédjától vessző választja el. Ilyen módon egy többdimenziós tömb esetében a
teljes tömb belső tömbjeit újabb kapcsos zárójel jelöli.
Például vegyük a következő értéket:

’{{első}, {második, harmadik}, {negyedik, ötödik, hatodik}}’

Ez a következő kétdimenziós tömböt jelenti:


1. első

2. (a) második
(b) harmadik
3. (a) negyedik
(b) ötödik
(c) hatodik
A tömb egyes elemeire lehet egyben is hivatkozni, de lehet a mezőnév után szögletes zárójelek között megadott
index-szel is, amely egytől indul. Többdimenziós tömbnél újabb kapcsos zárójelek is szerepelhetnek szükség esetén.
Amennyiben a fenti példában szereplő értéket egy tömb nevű mező tartalmazza a példa nevű adatbázisban, akkor például
a következő lekérdezéseket végezhetjük:

sir=# SELECT * FROM példa ;


tömb
----------------------------------------------------------------
{{első,"",""},{második,harmadik,""},{negyedik,ötödik,hatodik}}
(1 sor)

Mint látható, minden esetben a belső tömbök ugyanolyan elemszámúvá lesznek kiegészítve a szükséges elemszámokat
üres karaktersorozattal kitöltve. A második elemet elérhetjük a következőképpen :

sir=# SELECT tömb[2:2][1:3] FROM példa;


tömb
-------------------------
{{második,harmadik,""}}
(1 sor)

Az első index azt adja meg, hogy a másodiktól a másodikig keressük az elemet, míg a második index adja meg ennek
teljes tartalmát. Ha az első indexben csak egy kettes szerepel, akkor az azt fogja jelenteni, hogy a második elemig kell
kiírni :
sir=# SELECT tömb[2][1:3] FROM példa;
tömb
--------------------------------------
{{első,"",""},{második,harmadik,""}}
(1 sor)

230
Ebből következően a második paraméterben már elég a hármas megadása is.
Tehát amennyiben egy intervallumot akarunk megadni, akkor annak kezdő értéke után kettősponttal elválasztva kell
a záróértéket megadni. Ha többdimenziós tömbnél csak egy értéket adunk meg, akkor azt a kettőspont után írt értéknek
tekinti a rendszer, míg a kezdő értéknek egyet vesz. Ez azonban nem érvényes akkor, ha egyetlen egy intervallumot sem
adunk meg, mert ebben az esetben mindenképpen egyetlen elemet határoz meg az index.
Az egyes elemek első elemeit elérhetjük a következőképpen :
sir=# SELECT tömb[1][1] FROM példa;
tömb
------
első
(1 sor)

sir=# SELECT tömb[2][1] FROM példa;


tömb
---------
második
(1 sor)

sir=# SELECT tömb[3][1] FROM példa;


tömb
----------
negyedik
(1 sor)
Természetesen arra is van lehetőség, hogy már a definiáláskor megadjuk, hogy hány eleme lehet a tömbnek. Ekkor a
CREATE TABLE utasításban nem üres zárójelek szerepelnek, hanem a zárójelekben meg kell adni a lehetséges elemszá-
mot.
Egy már létező tömb elemszáma új elemek felvételével az UPDATE utasításban lehetséges, ha egy még nem használt
indexű tömbelemnek adunk értéket.
Mire használható a tömb típus? Elsősorban többértékű adatok tárolására. Például ha szeretnénk nyilvántartani az
ügyfelek telefonszámait, de nem tudjuk előre, hogy mennyi lesz. Ahelyett, hogy egy külön adattáblát hoznánk létre az
egyes telefonszámok felsorolására, vagy korlátozva a nyilvántartható számokat egy adott mennyiségre, több telefonszám
mezőt hozunk létre, létrehozhatunk egy telefonszám tömböt, amelyben az összes telefonszám felsorolható a tényleges
számuktól függetlenül.
A tömb pillanatnyi elemszáma lekérdezhető az array_dims függvénnyel :

sir=# SELECT array_dims(tömb) FROM példa;


array_dims
------------
[1:3][1:3]
(1 sor)

Ebből persze kicsit körülményes a szükséges adatokat például egy PHP-scriptben kihámozni, de azért nem lehetetlen.

17.1.4. Alapértelmezett mezőértékek


Miután megismertük a lehetséges adattípusok egy részét, térjünk vissza a tábla definiálására, a CREATE TABLE utasí-
táshoz. Az egyes mezőknek nem csupán a nevét és a típusát adhatjuk meg, hanem adhatunk egy alapértelmezett értéket is
arra az esetre, ha az adatfelvitelkor a mező nem kap értéket. Ezt a DEFAULT kulcsszó használatával tehetjük meg.

231
Az itt megadott értéket kapja minden esetben a mező egy új rekord felvitelekor, amennyiben az adatfelvitelnél a
mező értéke nincsen megadva, vagy az érték helyén a default kulcsszó szerepel. Amennyiben nem adjuk meg a mező
alapértelmezett értékét a tábla definiálásakor, akkor az alapértelmezett értéke a NULL lesz, amely azt jelenti, hogy a mező
üres.
Az alapértelmezett érték megadása a tábla definiálásakor a mező megadása után történik a DEFAULT kulcsszó és az
alapértelmezésként használandó érték megadásával. Természetesen az értéket a mező típusának megfelelő konstansként
kell megadni. Ezenfelül értékként megadható egy megfelelő típusú értéket adó kifejezés is, amelynek nem a tábla defi-
niálásakor kell kiszámolhatónak lennie, hanem akkor, amikor új rekord felvitelére kerül sor. Ez azt jelenti, hogy akár a
felvitel időpontja is rögzíthető egy ilyen mező segítségével.
Például a következő adattáblába való adatfelvitel tartalmazni fogja a felvitel időpontját :
CREATE TABLE példa (
név text,
felvitel timestamp DEFAULT now()
);
Ha adatfelvitelkor csak a név mező kap értéket, akkor a felvitel mező a now() kifejezésnek az adatfelvitel pillanatában
érvényes értékét kapja, azaz az éppen aktuális dátumot és időpontot.

17.1.5. Feltételek megadása


A tábla mezőihez és az egész táblához egyaránt megadhatóak feltételek, amelyeknek teljesülniük kell minden egyes
rekordra, amit felviszünk a táblába, vagy amely adatmódosítás eredményeként létrejön.
Ilyen feltétel lehet például az a megkötés, hogy az osztályzatot tároló mező értéke csak az [1; 5] intervallumba eső
egész szám lehet, vagy hogy a fizetés mező értéke nem lehet negatív stb. Azonban lehetnek ennél bonyolultabb, több
mező értékét összekapcsoló feltételek is.
Az ilyen feltételek, amennyiben egy oszlopra vonatkoznak, akkor megadhatók az oszlop megadásakor a CHECK
kulcsszó után egy logikai feltételként, amely más mezőre nem hivatkozhat. Amennyiben több oszlopra is vonatkozik a
feltétel, akkor az utolsó oszlop megadása után külön táblafeltételként, szintén a CHECK kulcsszó után adható meg.
Amennyiben van rá esély, hogy később az ALTER TABLE utasítás segítségével meg szeretnénk változtatni egy felté-
telt, akkor szükség van rá, hogy pontosan meghatározható legyen, melyik feltételről van szó. Ilyenkor a feltételnek nevet
kell adni. Egy feltételt el lehet nevezni a CONSTRAINT név záradékkal, mielőtt a feltételt ténylegesen megadnánk :

CREATE TABLE példa (


név text,
fizetés decimal(10) CONSTRAINT fizetés_feltétel CHECK (fizetés > 0)
);

A fenti eljárással létrehozott feltétel akkor teljesül, ha a zárójelben szereplő logikai feltétel igaz, vagy NULL értéket
eredményez. Ebből tehát az következik, hogy ilyen módon nem lehet megakadályozni, hogy a mező értéke NULL legyen.
Márpedig vannak olyan attribútumok, amelynek mindenképpen léteznie kell az értékének. Erre ad megoldást a NOT
NULL feltétel.
Ez is az oszlopdefinícióban szerepel a típus megadása után.9 Csak oszlopfeltételként adható meg, hiszen az adott
oszlopra tiltja meg a NULL érték használatát. A fordítottja, a NULL feltétel is megadható, de fölösleges, mivel ha a NOT
NULL nem szerepel, az eleve azt jelenti, hogy az oszlopban szerepelhet a NULL érték.
A korábbiakban ismertetett megszorítások is gyakorlatilag oszlop- vagy táblafeltételekkel valósíthatóak meg. Ilyen
megszorítást megvalósító feltételek a következők:
UNIQUE egyedi értékkel kell rendelkeznie. Oszlopfeltétel esetén nem kell mást tenni, mint a típus megadása utáni rész-
ben a UNIQUE kulcsszót szerepeltetni, és ettől kezdve az adatfelvitel csak olyan értékkel lehetséges, amely a már
9 Az alapértelmezett érték, illetve a feltételek megadásának sorrendje tetszőleges.

232
felvitt rekordoknál ebben a mezőben még nem szerepel. Táblafeltételként megadható olyan eset is, amikor több
attribútum együtt alkot egyedi kulcsot. Ekkor a UNIQUE kulcsszó után zárójelben, vesszővel elválasztva fel kell
sorolni azokat a mezőket, amelyeknek az értéke nem egyezhet meg teljesen két különböző rekordnál. Ez gyakor-
latilag egy általálános kulcs megszorítást valósít meg. Amennyiben a szóban forgó oszlop(ok)ban előfordulhat a
NULL érték, két NULL érték nem számít azonos értéknek.
PRIMARY KEY elsődleges kulcs megszorítást valósít meg. Technikailag megegyezik a NOT NULL és a UNIQUE
feltétel egyidejű szerepeltetésével, azonban elsődleges kulcs egy táblánál csak egy adható meg. Megadási módja
oszlopfeltételként a PRIMARY KEY kulcsszóval történik, táblafeltételként több mezőből álló kulcs is megadható.
Ebben az esetben a PRIMARY KEY kulcsszót egy zárójel követi, benne vesszővel elválasztva a kulcsot alkotó
mezők nevei. Sokkal áttekinthetőbb – és könnyebben módosítható – ha az elsődleges kulcsot táblafeltételként adjuk
meg még akkor is, ha egyetlen mezőből áll.
A PostgreSQL-ben ha megadunk elsődleges kulcsot (általában így szokott lenni), akkor automatikusan létrejön egy
index a kulcsba tartozó oszlopokon történő gyorsabb keresés érdekében.
hivatkozási épség megszorítás: Amennyiben valamely mező olyan célt szolgál, hogy egy másik adattáblában levő ér-
tékekre hivatkozzunk vele (például a városra az irányítószámmal), akkor elvárjuk, hogy a hivatkozó mezőben levő
érték a hivatkozott adattábla kulcsában létezzen értékként. Tulajdonképpen ezt jelenti a hivatkozási épség megszo-
rítás. Ezt megvalósító feltétel is létezik.
Például létezik egy tábla, megfelelő adatokkal feltöltve, amely így néz ki :

CREATE TABLE products (


product_no integer PRIMARY KEY,
name text,
price numeric
);

Szeretnénk egy adattáblában tárolni a termékekre vonatkozó megrendeléseket. Ekkor ebben a táblában hivatkozni
kell a products tábla megfelelő sorára. Ehhez a következő megoldást alkalmazhatjuk :

CREATE TABLE orders (


order_id integer PRIMARY KEY,
product_no integer REFERENCES products(product_no),
quantity integer
);

Ezek után a rendszer nem enged olyan rekordot felvinni, amelynek termékszáma nem szerepel a products táblában.
Az utóbbi tábladefinícióban a zárójelben szereplő mezőnév elhagyható, mivel megegyezik a helyi mezőnévvel,
azonban így olvashatóbb és egyértelműbb. Amennyiben a két táblában más a hivatkozott és a hivatkozó mező neve,
akkor mindenképpen meg kell adni a hivatkozott mező nevét is.
Előfordulhat az az eset is, hogy több mező együtt hivatkozik egy másik tábla azonos számú mezőjének értéke által
meghatározott rekordra. Ekkor mindenképpen táblafeltételként kell megadni, amely esetben hosszabb a feltétel,
mivel először meg kell adni a hivatkozó mezőket is :

CREATE TABLE t1 (
a integer PRIMARY KEY,
b integer,

233
c integer,
FOREIGN KEY (b,c) REFERENCES other_table (c1,c2)
);

A hivatkozási épség megszorítást előíró feltételben egyébként a hivatkozó mezőket együtt külső kulcsnak hívjuk,
mivel egy másik tábla elsődleges kulcsára hivatkoznak. Természetesen a mezőknek egymással számban és típusban
meg kell egyezniük. Egy tábla több külső kulcsot is tartalmazhat. Tulajdonképpen amikor az E/K diagram kap-
csolataiból készítünk relációt, akkor annak a relációnak az egyedhalmazok kulcsaiból származó attribútumai ilyen
külső kulcsok lesznek.
A táblák ilyen összekapcsolása azonban felvet egy kérdést : mi történjék, ha a hivatkozott rekordot törlik, vagy a
kulcsát megváltoztatják? Ilyenkor mit kell tenni az ekkor már létező, rá hivatkozó rekordokkal ?
Az egyik megoldás, hogy nem engedjük a törlést ill. megváltoztatást. A másik lehetőség, hogy a hivatkozó rekordot
is töröljük. Harmadik lehetőség, hogy nem teszünk semmit ebben az esetben. Mindig a konkrét adatbázistól függ,
hogy melyik a helyes cselekedet.
Éppen ezért a külső kulcs feltétele kiegészíthető az ON DELETE és az ON UPDATE kulcsszavak után azzal a
teendővel, amelyet ilyenkor el kell végezni. Ez lehet RESTRICT vagy másként írva NO ACTION (semmit nem
kell tenni), SET NULL (legyen üres), SET DEFAULT (legyen értéke az alapértelmezett), CASCADE (a hivatkozó
rekordot is törölni kell).

17.1.6. Az ALTER TABLE utasítás


Előfordulhat, hogy a tábla létrehozása után kiderül, hogy valamit nem megfelelően hoztunk létre. Az ALTER TABLE
utasítás segítségével lehet a szükséges változtatásokat végrehajtani. Azonban azt nem árt megjegyezni, hogy az ALTER
TABLE sem old meg minden gondot, néha nincs más megoldás, mint az adattáblát teljesen törölni és újra létrehozni.
Ez azonban abban az esetben nem célszerű, ha az adattábla már tartalmaz rekordokat. Persze ilyenkor is megoldható a
dolog egy ideiglenes adattáblába történő átmásolással. A legnagyobb probléma akkor lép fel, ha a táblában levő adatokra
egy másik tábla külső kulcsai is hivatkoznak. Ekkor már az átmásolás sem megoldás. Éppen ezért lényeges, hogy az
adatmodellezés minél pontosabb és részletesebb legyen.
Ha mégis módosítani kell az adattáblát, akkor használhatjuk az ALTER TABLE utasítást, amely segítségével a követ-
kező módosítások végezhetőek el a táblán:
• Új oszloppal bővíthető a már meglévők után.
• Törölhető valamely oszlop (a már felvitt rekordokban a megfelelő adatok is eltűnnek).
• Új feltétel adható meg akár oszlopra, akár az egész táblára.
• Törölhető egy névvel ellátott feltétel.
• Megváltoztatható egy oszlop alapértelmezett értéke.
• Átnevezhető egy oszlop.
• Átnevezhető a tábla.

Új oszlop felvétele
Amennyiben egy új oszloppal akarjuk bővíteni a táblát, akkor az utasítást a következő formában kell használnunk :
ALTER TABLE táblanév ADD [ COLUMN ] oszlopnév típus [ oszlopfeltétel ] ;
Az új oszlop minden már felvitt rekord esetén NULL értékkel fog rendelkezni. Éppen ezért az oszlopfeltétel nem tilthatja
meg a NULL értéket ebben az oszlopban. Azonban később az oszlop módosításával felvehető a NOT NULL feltétel.
Hasonlóképpen utólag lehet csak alapértelmezett értéket adni az oszlopnak.

234
Oszlop törlése
A már létező oszlopot törölni – a létező adatokkal együtt – az utasítás következő formájával lehet :
ALTER TABLE táblanév DROP [ COLUMN ] oszlopnév [ RESTRICT | CASCADE ] ;
Amennyiben a CASCADE kulcsszót is megadjuk, akkor minden olyan objektum is törlésre kerül, amely a törlendő osz-
loppal kapcsolatban áll. Tehát ebben az esetben azok a más táblában levő oszlopok is törlésre kerülnek, amelyek külső
kulcsként erre az oszlopra hivatkoznak. Ugyanakkor a RESTRICT kulcsszó megadása esetén megóvhatjuk magunkat a
hivatkozási épség megsértésétől ilyen esetben: nem lesz törölve az oszlop, ha van tőle függő objektum az adatbázisban.

Feltétel megadása
Új feltétel, mint tábla feltétel adható meg a következő utasítással :
ALTER TABLE táblanév ADD táblafeltétel ;
Természetesen táblafeltételként a tábla definiálásakor ismertetett bármely feltétel megadható, amely egész táblára megad-
ható (tehát null tiltása nem). Ez utóbbihoz az oszlop módosítását kell alkalmazni :
ALTER TABLE táblanév ALTER COLUMN oszlopnév SET NOT NULL ;
A feltétel beállításakor a tábla sorai azonnal ellenőrzésre kerülnek, így csak olyan feltételt lehet beállítani, amelynek
a beállításkor is megfelel minden már felvitt adat.

Feltétel törlése
A már beállított feltételt utólag csak akkor lehet törölni, ha el volt nevezve. A PostgreSQL persze akkor is ad egy nevet a
feltételnek, ha mi nem tesszük meg. Ezt azonban ki kell deríteni, ha hivatkozni akarunk rá.
Az utasítás, amellyel törölni tudjuk a feltételt, a következő :
ALTER TABLE táblanév DROP CONSTRAINT feltételnév [ RESTRICT | CASCADE ] ;
Null értéket tiltó feltétel törlése ismét kicsit másképpen történik :
ALTER TABLE táblanév ALTER COLUMN oszlopnév DROP NOT NULL ;

Alapértelmezett érték megváltoztatása


Mint említettük, új oszlop felvételekor nem lehet alapértelmezett értéket beállítani, csak utólag, az oszlop tulajdonságai-
nak megváltoztatásával, a következő parancs segítségével :
ALTER TABLE táblanév ALTER COLUMN oszlopnév SET DEFAULT érték ;
Az alapértelmezett érték új beállítása nélkül törölhető is :
ALTER TABLE táblanév ALTER COLUMN oszlopnév DROP DEFAULT ;
Ez utóbbi egyenértékű a null érték alapértelmezett értékké tételével, ami persze hibát okoz, ha egyidejűleg a null érték
használata le van tiltva.

Oszlop/tábla átnevezése
Az oszlop neve is megváltoztatható a következő paranccsal :
ALTER TABLE táblanév RENAME COLUMN oszlopnév TO újnév ;
Az egész tábla is átnevezhető a következő paranccsal :
ALTER TABLE táblanév RENAME TO újnév ;

235
17.2. Egyéb adatbázis objektumok
Bár a legfontosabb objektuma egy adatbázisnak maga az adattábla, lehetnek még további objektumok is. Ezeket nem
részletezzük, csupán felsoroljuk őket. Ezek még akkor sem férnek bele ennek a jegyzetnek a kereteibe, ha maga a jegyzet
többet is kíván tartalmazni az előírt minimális követelményeknél – az SQL-ről szóló fejezet már eleve ezért került bele :
fontos ismerni, bár nem része a kötelező tananyagnak sajnos.
A további objektumfajták a következők:
Nézettáblák olyan táblák, amelyek valójában egy másik adattábla vagy nézettábla lekérdezésével jönnek létre. A né-
zettábla tehát valójában egy olyan lekérdezés, amelyet tárolva bármely más táblához hasonlóan fel lehet használni
újabb lekérdezésekhez. A CREATE VIEW paranccsal lehet ilyeneket létrehozni.
Függvények, operátorok, adattípusok A függvények vagy egy értéket, vagy egész táblarészeket (mint lekérdezés ered-
ményét) adhatják eredményül. A függvényeket általában több utasításból álló adatbázis-műveletek definiálására
szokás használni, amelyek így többször végrehajthatóak. Ráadásul a függvénynek adott paraméterekkel a végrehaj-
tandó műveletek is paraméterezhetőek.
Eseményfigyelők (triggerek) meghatározott események (adatfelvitel, adattörlés, adatmódosítás) bekövetkezésekor vég-
rehajtódó műveletsorok, amelyekkel bizonyos tevékenységek ellenőrizhetővé válnak.

236
18. fejezet

Adatmanipulációs utasítások

Azokat az utasításokat, amelyek egy adott adatstruktrúrában tárolt adatokat módosítják, adatmanipulációs utasításokként
szokás emlegetni. Ilyen adatmanipulációs tevékenyégnek számít
• új adatok felvitele az adattáblákba;
• a meglévő adatok módosítása;
• a meglévő adatok törlése az adattáblából.
A következő szakaszokban az ezeket megvalósító utasításokat fogjuk megismerni.

18.1. Adatfelvitel
A frissen létrehozott adattábla üres, adatokat nem tartalmaz. Ahhoz, hogy adatok is legyenek benne, fel kell azokat vinni.
Erre szolgál az INSERT utasítás.
Az adatokat az adattáblába soronként lehet felvinni. Természetesen lehet egyszerre több sort is felvinni, de egy sornál
kisebb részt nem. Tehát még akkor is, ha nem ismert minden mező értéke, az egész sort egyszerre kell felvinni – legfeljebb
a nem ismert értékű mezők az alapértelmezett értéket kapják.
Az INSERT utasítás általános szintaxisa a következő :

INSERT INTO táblanév [ (oszlop [,...] ) ]


{ DEFAULT VALUES
| VALUES ( { kifejezés | DEFAULT } [,...] )
| SELECT lekérdezés
}

Az egyes elemek jelentése a következő:


• A táblanév – esetleges sémamegadással ellátva – annak a táblának neve, amelybe adatokat akarunk felvinni.1
• Az oszlop a tábla azon oszlopát jelenti, amelynek az értékét fel akarjuk vinni.
• A kifejezés az oszlopba felviendő értéket határozza meg.
• A lekérdezés egy normál adatlekérdezés, amit a később ismertetendő SELECT utasításnál (lásd 241. oldal) meg-
szokott formában lehet megadni.
1 Egy INSERT utasítás egy adattáblába tud adatokat felvinni.

237
Tegyük fel hogy van egy táblánk a következő oszlopokkal :
termékazonosító integer;
név text ;

ár decimal(8,2) ;
és a tábla neve termékek. Ekkor ebbe a táblába egy rekordot a legegyszerűbben a következő utasítással vihetünk fel :

INSERT INTO termékek VALUES ( 1, ’Sajt’, 9.99);

Ebben az egyszerű formában az értékeket a VALUES szó utáni zárójelben (vesszővel elválasztva) abban a sorrendben
kell felsorolni, amilyen sorrendben a tábla definiálásakor az oszlopokat megadtuk, és minden oszlophoz szerepeltetni kell
az értéket.
Elképzelhető, hogy az ember elfelejti, hogy milyen sorrendben voltak definiálva az oszlopok. Az ekkor fellépő problé-
ma elkerülhető, ha az oszlopok sorrendjét a felvitelkor megadjuk. Ez a módszer arra is alkalmas, hogy ne minden oszlopot
kelljen megadni. A következő két utasítás a fentivel azonos eredményt ad :

INSERT INTO termékek ( termékazonosító, név, ár)


VALUES (1, ’Sajt’, 9.99);
INSERT INTO termékek (ár, név, termékazonosító)
VALUES (9.99, ’Sajt’, 1);

Amennyiben valamelyik mezőnek nem akarunk értéket adni (az alapértelmezett értéket kapja a mező), akkor azt az
oszlopot kihagyjuk:

INSERT INTO termékek (termékazonosító, név)


VALUES (2, ’Paprika’);

Az SQL-ben hibás, azonban a PostgreSQL elfogadja a következő utasítást is :

INSERT INTO termékek (2, ’Paprika’);

Ez a fentivel azonos eredményt ad, mivel a PostgreSQL ilyenkor az első annyi oszlopnak adja az értéket, ahány érték
szerepel, a többit az alapértelmezett értékkel tölti fel. A szabványos SQL ezt az utasítást hibásnak tekinti !
Az alapértelmezett értékek használatára másképpen is rá lehet venni az adatbáziskezelőt. Az értékek között szerepelhet
a DEFAULT kulcsszó, amely azt jelenti, hogy az ott következő mezőbe az oszlopra előírt alapértelmezett érték kerüljön.
Másik lehetőség az érték lista helyett a DEFAULT VALUES megadása, aminek hatására egy olyan rekord kerül a táblába,
amelynek minden mezője az oszlopra előírt alapértelmezett értéket kapja :

INSERT INTO termékek DEFAULT VALUES;

A másik lehetőség egy tábla adatokkal való feltöltésére az INSERT utasításban az értéklista helyett egy SELECT
utasítás alkalmazása. Ezzel a módszerrel egy vagy több táblából másolhatunk adatokat egy másik táblába. A SELECT
utasítás eredményeként kapott sorok kerülnek beillesztésre a táblába úgy, hogy minden sor első mezője a tábla első
oszlopába kerül, a második a másodikba stb.

238
18.2. Adatok módosítása
A táblában már jelenlévő adatok módosítását az UPDATE utasítással végezhetjük el. Akár egy sor, akár az egész tábla
módosítható egyetlen utasítással, azonban a módosítás mindig oszlopokra vonatkozik úgy, hogy közben a többi oszlop
nem változik meg.2 A módosításhoz a következő három információt kell megadni :
1. A módosítandó tábla és oszlop neve;
2. Az oszlop új értéke;
3. Melyik sor(oka)t kell módosítani.
Megjegyzés. Az SQL az adattáblát multihalmazként definiálja, azaz nem írja elő egyértelműen, hogy minden rekordnak
egyedi azonosítóval kell rendelkeznie. Azonban az UPDATE utasítás – éppúgy, mint az utána ismertetendő DELETE
utasítás – a rekordok azonosítását csak a tartalmuk alapján tudja elvégezni. Így ha van két teljesen azonos értékeket
tartalmazó rekord, akkor azok vagy egyszerre módosíthatóak vagy egyszerre törölhetőek. Ezt a problémát a PostgreSQL-
ben az oid mező használatával lehet megkerülni, amely egy táblán belül minden rekordra egyedi objektum-azonosítót
ad.
Ennek elkerülése érdekében célszerű minden táblában definiálni kulcsot, biztosítva ezzel, hogy a táblában levő rekor-
dok ne multihalmazt, hanem mindenképpen egyedi azonosítást lehetővé tevő halmazt alkossanak.
A következőkben az UPDATE utasítás teljes szintaxisa látható :

UPDATE táblanév
SET oszlop = újérték [,...]
[ FROM mástáblák ]
[ WHERE feltétel ]

A fenti szintaxisban a FROM záradék a PostgreSQL kiterjesztése az SQL szabványhoz képest, amely lehetővé teszi
olyan táblák megadását, amelyek oszlopaira a WHERE záradékban hivatkozni szeretnénk.
A SET után vesszővel elválasztva sorolhatóak fel azok az értékadások, amelyek a módosítandó oszlop(ok) (balol-
dal) új értékét (jobboldal) határozzák meg. Az új érték egy kifejezés, amelyben akár a módosítandó rekord oszlopai is
szerepelhetnek.
Azok a rekordok fognak módosulni, amelyek esetén a WHERE utáni feltétel igaznak adódik. Ha a WHERE záradék
nem szerepel, akkor a tábla valamennyi rekordja módosul.
Például a következő utasítás a termékek tábla minden olyan sorát módosítani fogja, amelyben az ár mező értéke 5, és
ezekben a mező új értéke 10 lesz:

UPDATE termékek SET ár = 10 WHERE ár = 5;

Amennyiben valamennyi termék árát növelni szeretnénk például tíz százalékkal, akkor azt a következő utasítással
tehetjük meg (figyeljük meg a WHERE záradék hiányát) :
UPDATE termékek SET ár = ár * 1.1;

Ez az utasítás sorra veszi a tábla rekordjait, és mindegyiknél veszi az ár mező pillanatnyi értékét, megszorozza 1,1-el,
és ezt az értéket írja az ár mezőbe új értékként.
Elképzelhető az is, hogy több mezőt módosítunk úgy, hogy azokat az új értékhez is felhasználjuk. Vegyük például a
következő példát :

UPDATE table SET a = b + 3, b = a + 3, c = a + b;


2 Tapasztalat szerint az UPDATE utasítást a PostgreSQL valójában a módosított rekord új rekordként való felvitelével és egyben a régi értéket

tartalmazó rekord törlésével oldja meg, mindezt egyetlen atomi lépésként végrehajtva.

239
Itt ránézésre nem egyértelmű, hogy például mi lesz a c mező értéke, mivel ugyanaz az utasítás egyben azt a két mezőt
is módosítja, amelynek az összege kell legyen. Ha kipróbáljuk az utasítást, akkor például a kezdeti a = 1, b = 2, c = 3
értékekből a = 5, b = 4, c = 3 értékek lesznek, ami egyértelműen mutatja, hogy az értékadások párhuzamosan hajtódnak
végre : először a régi értékek felhasználásával mindegyik kifejezés értéke meghatározásra kerül, majd ezután kapják ezeket
meg a mezők.
Az érték lehet akár egy teljes allekérdezés is akár ugyanerre a táblára, akár más táblára is. Ebben az esetben is igaz,
hogy először az értéket kell meghatározni, tehát először lefut az allekérdezés az eredeti táblán, és ezután kerül sor az
értékadásokra. Amennyiben több rekordot érint a módosítás, akkor minden rekordhoz a tábla eredeti változatán fut le a
lekérdezés, és nem a korábban már ugyanebben az utasításban módosult rekordokat tartalmazó táblán. Mindez elég bo-
nyolulttá teszi az utasítás megvalósítását, ami bonyolultabb allekérdezések esetén nagyon megnövelheti a végrehajtáshoz
szükséges időt, és memóriaméretet. Ha azonban belegondolunk a tranzakciók működésébe, akkor ez az elvárható helyes
működése az utasításnak.

18.3. Törlés
Időnként szükség lehet arra is, hogy a táblában levő valamely rekordot töröljünk. Erre szolgál a DELETE utasítás, amellyel
nagyon vigyázni kell, mert egyetlen utasítással akár az adattábla teljes tartalmát is törölhetjük !
Az utasítás szintaxisa:
DELETE FROM táblanév [ WHERE feltétel ]
Amennyiben nem adunk meg feltételt, akkor a tábla valamennyi sorát törli az utasítás, és csak az üres tábla marad
meg.3 Ha megadunk feltételt, akkor minden olyan sort töröl a táblából az utasítás, amelyre igaz a feltétel.
Az utasítás nem kérdez vissza, hanem azonnal végrehajtásra kerül a törlés ! Ezért nagyon gondosan ügyeljünk a
parancs kiadásánál a feltételre!

3 Ez sokszor gyorsabb, mint a tábla bizonyos sorait törölni.

240
19. fejezet

Lekérdezések

Most, hogy már létre tudjuk hozni az adattáblát, fel tudunk vinni adatokat, módosítani vagy törölni is tudjuk azokat, már
csak a leggyakrabban használt utasítás van hátra, amellyel az adatbázisban levő adatokat lekérdezhetjük. Ez az utasítás a
SELECT, amely bonyolultsága és sokoldalúsága miatt egyaránt megérdemli, hogy külön fejezetet szenteljünk neki.
Már maga az utasítás szintaxisa is túl bonyolult ahhoz, hogy elsőre átlátható legyen. Ennek ellenére következzék itt a
teljes szintaxis – egyenlőre minden magyarázat nélkül :

SELECT [ ALL | DISTINCT [ ON ( kifejezés [,...] ) ] ]


* | kifejezés [ AS név ] [,...]
[ FROM táblaspecifikáció [,...] ]
[ WHERE feltétel ]
[ GROUP BY kifejezés [,...] ]
[ HAVING feltétel [,...] ]
[ { UNION | INTERSECT | EXCEPT } [ ALL] select ]
[ ORDER BY kifejezés [ ASC | DESC | USING operátor ] [,...] ]
[ LIMIT { rekordszám | ALL } ]
[ OFFSET kezdőrekord ]
[ FOR UPDATE [ OF táblanév [,...] ] ]

ahol a táblaspecifikáció:

táblanév [ [ AS ] alias [ (oszlop_alias_lista) ] ]


|
( select )
[ AS ] alias [ (oszlop_alias_lista) ]
|
tábla_függvénynév ( [ paraméterlista ] )
[ AS ] alias [ (oszlop_alias_lista | oszlop_def_lista) ]
|
tábla_függvénynév ( [ paraméterlista ] )
AS ( oszlop_def_lista )
|
táblaspecifikáció [ NATURAL ] join_típus táblaspecifikáció
[ ON join_feltétel | USING (join_oszlop_lista) ]

241
19.1. A SELECT utasításról általában
Mielőtt a fenti szintaxis részleteit elemeznénk, nézzünk néhány példát az utasítás használatára. Az adatbázisban tárolt
adatok lekérdezésére szolgál tehát a SELECT utasítás. Angolul a lekérdezést query-nek nevezik. A probléma – mint a
PHP használatánál majd látni fogjuk –, hogy a többi utasítás kiadását adatbázis-kérésnek nevezzük, amit angolul szintén
query-ként emlegetnek. Valószínűleg ez az oka, hogy egyes programok magyarításában – mint az MS Access is – az
INSERT, UPDATE és DELETE utasításoknak megfelelő műveletet is beszúró-, módosító- illetve törlő-lekérdezésként
emlegetik, ami rendkívül zavaró.
A lekérdezés az adatbázisban tárolt információ valamely célból és valamilyen formában történő előhívását jelenti. A
tárolt információ módosítására irányuló kéréseket nem nevezzük lekérdezésnek.

Mint a fenti szintaxisból is látható, a SELECT utasítás általános alakja a következő :


SELECT oszloplista FROM táblaspecifikáció [ egyéb feltételek ]
A legegyszerűbb formája az utasításnak:
SELECT * FROM tábla ;
A fenti utasítás a tábla nevű adattábla minden sorát kilistázza. A soron belül minden mező értéke egymás után látható
lesz abban a sorrendben, ahogy a tábla definiálásakor az oszlopok szerepeltek. A * az utasításban azt jelenti : „minden osz-
lop tartalmát meg kell jeleníteni”. Amennyiben valamely oszlop nevét szerepeltetjük itt, vagy több oszlop nevét vesszővel
elválasztva, akkor a megadott nevű oszlopok tartalma jelenik csupán meg. Másrészt az oszlop neve helyett szerepelhet
egy kifejezés is, amelyben akár az oszlopnevek is szerepelhetnek. Ilyenkor minden egyes sorra a megadott kifejezések
kiszámítása (szakszóval kiértékelése) megtörténik, és a kapott eredmények kerülnek kilistázásra. Tehát ha például a tábla
adattáblának van a, b és c mezője, akkor a következő utasítás kiírja egy oszlopban az a, egy másikban a másik két mező
összegének értékét:
SELECT a, b + c FROM tábla ;
A FROM záradék1 állítja elő a táblázatot, amelynek a soraival kell dolgozni. Az eddigi példáinkban ez mindig egy
adattábla (reláció) volt, azonban az adatbázisokban a lényeg éppen a több táblára vonatkozó lekérdezésekben rejlik. Ez
azt jelenti, hogy akár több táblából, sőt akár egy fizikailag nem is létező, csak a lekérdezés idejére – esetleg egy másik
lekérdezéssel – előállított táblát is használhatunk. Nagyon ritka az olyan lekérdezés, amelyben a FROM záradék nem sze-
repel, hiszen a lekérdezéseknél mindig valamilyen táblából akarunk adatokat kinyerni. Igazából csak azért nem kötelező,
mert vannak esetek, amikor tényleg nincs rá szükség.
Egyik példa a FROM záradék hiányára, amikor csak valaminek a kiszámolására használjuk a SELECT utasítást :
SELECT 3 * 4 ;
?column?
----------
12
(1 sor)
Ennél sokkal gyakoribb eset, hogy a lekérdezés ugyan használ táblát, de az el van rejtve egy függvényhívás mögötti
lekérdezésbe :
SELECT jelszó(’babar’);
Itt ha a jelszó függvény például a paraméterében szereplő azonosítójú felhasználó jelszavát keresi ki egy adattáblából,
akkor a fenti utasítás eredménye a babar azonosítójú felhasználó jelszava lesz.
A következő szakaszokban a [5] 5. fejezete alapján (és persze a PostgreSQL sajátosságait is megemlítve) bemutatjuk
a SELECT utasítás használatát. Látható lesz, hogy ez az utasítás nagyon sokféle információ lekérdezésére alkalmas.
1 Már többször szerepelt a „záradék” kifejezés az SQL utasítások ismertetésénél – és még sokszor fog is szerepelni. Az SQL-ről szóló szakkönyvek

sűrűn használják a „záradék” szót egy-egy utasításnak a valamilyen kulcsszóval kezdődő részére, amely önálló jelentéssel is rendelkezik az utasításon
belül.

242
19.2. Egyszerű lekérdezések
A SELECT utasítás alapvetően a következőt csinálja:
1. Veszi a FROM záradékban megadott táblákat ;

2. Ezekből kiválasztja a WHERE záradékban megadott feltételnek elegett tevő sorokat ;


3. Az így megmaradt sorokból a SELECT záradékban megadott oszlopokat kilistázza az esetleg szereplő többi záradék
által előírt sorrendben.
A legegyszerűbb lekérdezések nem is használnak ennél többet.
Vegyük például a [5] filmes példáját:
SELECT *
FROM Film
WHERE stúdióNév = ’Disney’ AND év = 1990 ;
Ez a ránézésre is jól olvasható utasítás az angolul tudóknak máris sugallja, hogy a Film tábla sorai közül szeretnénk látni
azon sorok minden oszlopának értékét, amelyeket a Disney néven nyilvántartott2 stúdió 1990-ben készített. Valóban ez
az utasítás jelentése:

• A FROM záradék megadja azt a táblát, amelynek a soraira vonatkozik a lekérdezés.


• Ezután a WHERE záradék ebből kiválogatja a feltételnek megfelelő sorokat, és a többit eldobja.
• A megmaradt sorok mindegyikére kilistázódik a SELECT záradékban megadott kifejezéslista, illetve ha a csillag
szerepel, akkor minden oszlop értéke.3

19.2.1. A SELECT záradék elemei


Általában nem arra van szükségünk, hogy az előállt tábla minden egyes oszlopát lássuk, hanem inkább arra, hogy azok
valamelyikét új információ előállításához felhasználjuk.
Lehetőség van arra, hogy kiválasszuk azokat az oszlopokat, amelyeket látni szeretnénk. Ezt a műveletet – az általunk
bonyolult matematikai háttere miatt nem tárgyalt – relációs algebrában vetítésnek nevezzük.
Amennyiben a SELECT szó után vesszővel elválasztva felsorolunk kifejezéseket, akkor azok értékét fogja az utasítás
a tábla minden egyes sorára kiszámolni, és megjeleníteni eredményként. Ezek a kifejezések tetszőleges tartalmú kife-
jezések lehetnek, azonban értelme azoknak van, amelyek hivatkoznak a tábla valamely oszlopára annak azonosítójával.
Amennyiben egy kifejezés tartalmazza valamely oszlop azonosítóját, akkor a kifejezésben a soron következő rekordban
a szóban forgó oszlopban levő érték kerül behelyettesítésre a kifejezésbe. A legegyszerűbb ilyen kifejezés amikor magát
az oszlop nevét adjuk meg:

SELECT cím, hossz


FROM Film
WHERE stúdiónév = ’Disney’ AND év = 1990;

Eredményül egy két oszlopos táblázatot kapunk, amelyben a két megadott oszlop szerepel csak.
Előfordulhat, hogy valamiért más néven szeretnénk látni az eredmény oszlopait, mint amit eredetileg adna. Például a
fentebb szerepelt egyszerű számítás ereménye egy névtelen oszlop lett. Hasonló fordulhat elő, ha a kifejezés nem csupán
egy oszlop nevét adja meg. Ilyenkor az AS szó után megadhatjuk azt a nevet, amin látni akarjuk az eredményt :
2 Ha van olyan stúdiónév tárolva, hogy „Disney studio” vagy hasonló, arra nem igaz a feltétel. . .
3 Lehetséges a kifejezéslistában egy elemként szerepeltetni a csillagot. Ezt például akkor használhatjuk, ha a sorok mellett további információt is meg

akarunk jeleníteni. Például a PostgreSQL a tábla rendszer-mezőit nem listázza ki a csillagra, de az oid,* megadására az oid mező értéke is megjelenik.

243
SELECT a, b, a + b AS összeg
FROM tábla;

Itt az eredmény egy olyan három oszlopos táblázat lesz, ahol az első és a második oszlop fejlécében a mező neve jelenik
meg, míg a harmadik oszlopnál – amely az első két oszlop összegét tartalmazza – az „összeg” felirat lesz a fejlécben.
Arra is van lehetőség, hogy minden egyes érték után megjelenítsük a neki megfelelő mértékegységet is :
SELECT cím, hossz * 0.16667 AS hossz, ’óra’ AS órákban
FROM Film;
Ekkor egy külön oszlopban a hossz után mértékegység gyanánt megjelenik az „óra” szöveg is. Erre azonban van egy
sokkal szebb megoldás is: egy kifejezésben fűzzük hozzá a mennyiséghez a mértékegységet :
SELECT cím, hossz || ’ perc’ AS hossz
FROM Film;
A fenti utasításban a || operátor a karakterfüzérek összekapcsolását jelenti. Igaz ugyan, hogy a hossz értéke szám, de a
szükséges típuskonverzót az utasítás el tudja végezni.

19.2.2. A WHERE záradék használata


A WHERE szó után szereplő feltétel tehát kiválasztja azokat a sorait a FROM záradék által meghatározott táblázatnak,
amelyekkel a SELECT kifejezéslistája dolgozni fog. A WHERE után tehát egy olyan kifejezésnek kell állnia, amely igaz
vagy nem igaz értéket ad eredményül (emlékezzünk : az SQL három értékű logikát használ). Az SQL hat összehasonlító
operátort használ : = (egyenlő), <> (nem egyenlő, a PostgreSQL még ismeri ugyanerre a C-ből ismert != formát is),
<, >, <=, >=. Az összehasonlításban (és általában a logikai kifejezésben) lehetnek konstansok és a FROM záradékban
létrehozott táblázat oszlopai.
Alkalmazhatók az összehasonlítandó értékekre a szokásos matematikai műveletek : *, /, +, -, valamint a szokásos
műveleti sorrend megváltoztatására a kerek zárójelek. A fentebb már említett karakterlánc összekapcsoló || is használha-
tó. A kifejezésekben használható valamennyi műveleti jelet itt nincs értelme felsorolni, azok megtalálhatóak a használni
kívánt adatbáziskezelő leírásában, a PostgreSQL esetén például a user.pdf 6. fejezete foglalkozik ezekkel.
Az összehasonlítás eredményéül már egy logikai értéket kapunk, amely vagy igaz, vagy hamis, ha az összehasonlított
kifejezésekben nem szerepelt a NULL érték. Ha azonban valamely felhasznált oszlop értéke NULL volt, akkor az egész
összehasonlítás értéke NULL (meghatározatlan) lesz.
Az így kapott logikai értéket azután a logikai típusnál már említett AND, OR és NOT logikai műveletek segítségével
összekapcsolhatjuk. A végeredményként vagy igaz, vagy hamis, vagy NULL értéket kapunk, minden egyes sorra külön-
külön. Csak azok a sorok maradnak meg az utasítás további részében, ahol a végeredményül kapott érték igaz volt.
Amennyiben a SELECT utasítás nem tartalmaz WHERE záradékot, akkor minden sorra igaz értéket feltételez, és
ezért minden sor bele kerül a végrehajtásba.
A WHERE záradék teljesen azonos módon szerepel a DELETE és az UPDATE utasításban is. Így ott éppen az előző
bekezdésből következik, hogy elhagyása a táblázat összes sorának törlését illetve módosítását eredményezi. . .

Karakterláncok összehasonlítása
A karakterláncok kezelése egy kicsit problémás, hiszen egyetlen fölösleges szóköz máris gondoskodik róla, hogy két
karakterlánc ne egyezzen meg. Két karakterlánc ugyanis pontosan akkor egyenlő, ha a karaktereknek ugyanabból az
egymást követő sorozatából áll. Nem egyenlő a két karakterlánc ha legalább egy karakteren eltérnek egymástól.
A kérdés azonban az, hogy vajon sorrendet lehet-e közöttük definiálni. Egy adatbáziskezelőtől elvárható, hogy képes
legyen valamilyen sorrendet megállapítani a karakterláncok között, hiszen másképpen nem lehet például az adatokat
névsorba rendezni, ami pedig egy elég gyakori igény.
Ebből már következik az is, hogy olyan rendezettséget várunk el, amely az ábécé szerinti rendezést lehetővé teszi. Az
ilyen rendezést lexikografikus rendezettségnek nevezzük.

244
Lexikografikus sorrend: Ha a1 a2 . . . an és b1 b2 . . . bm két karakterlánc, akkor abban az esetben mondjuk, hogy az
első kisebb, mint a második, ha
1. a1 < b1 , vagy
2. minden 1 . . . i közti l indexre al = bl , és ai+1 < bi+1 , vagy
3. a1 = b1 , a2 = b2 , . . . , an = bn , és az első karaktersorozatnak nincs több karaktere, de a másodiknak még van,
azaz minden karaktersorozatnál kisebb a baloldali részsorozata.
Ezek után a „kisebb” relációból a másik három összehasonlító reláció (>, <=, >=) már értelemszerűen levezethető, az
„egyenlő” relációval szükség esetén kombinálva.

További lehetőség karakterláncok összehasonlítására a mintaillesztés. Erre szolgál a LIKE operátor. Ennek használata
a következőképpen történik:
s LIKE p [ ESCAPE x ]

ahol s az a karakterlánc, amelyben a mintát keressük, p a minta, az x-re pedig később visszatérünk. . .
A p minta egy olyan karakterlánc, amelyet az s-re ráhúzva, ha összeillenek, akkor a művelet eredménye igaz, kü-
lönben hamis (ha p értéke ismeretlen [NULL], akkor az eredmény is NULL lesz). A mintában szerepelhet két speciális
karakter, a % és a _. Ezek rendre a UNIX parancsokban használható * illetve ? helyettesítő karakterek funkcióját töltik
be.4 A százalék azt jelenti, hogy azon a helyen akárhány, tetszőleges karakter szerepelhet. Az aláhúzás helyén egyetlen
tetszőleges karakter állhat.
Előfordulhat, hogy a mintában szeretnénk magát a százalékjelet vagy az aláhúzásjelet is szerepeltetni. Ilyenkor van
szükség az ESCAPE szóra és utána egy egy elemű karakterláncra, amely megadja azt a karaktert, amelyet a mintában a
nem helyettesítendő százalék illetve aláhúzás elé kell írni. Így a következő példában szereplő feltétel akkor teljesül, ha az
s százalékjellel kezdődik és végződik, köztük akárhány (akár nulla is lehet) karakter szerepel :
s LIKE ’x%%x%’ ESCAPE ’x’
Itt tehát az x% jelentése: a mintában ténylegesen % szerepel.
Tegyük fel, hogy olyan filmcímeket keresünk, amelyek első szava „Halálos” és a második szó 7 betűs. A következő
utasítás ezeket listázza ki (csak ebből a két szóból állhat a cím a példában) :
SELECT cím
FROM Filme
WHERE cím LIKE ’Halálos _______’;
Keressük most azokat a filmeket, amelyek címében a ’s karaktersorozat szerepel ! A probléma az egyszeres idézőjellel
van, amely nem szerepelhetne karaktersorozatban. A problémát úgy oldották meg, hogy az egyszeres idézőjelet ilyenkor
minden helyzetben duplázva kell megadni. A helyes utasítás tehát a következő :
SELECT cím
FROM Filmek
WHERE cím LIKE ’%’’s%’;
A LIKE tagadása a NOT LIKE kulcsszó használatával lehetséges.
4 A MS Access-ben egy újabb példa a MS szabványt semmibe vevő magatartására, hogy a százalék és aláhúzás helyett a csillagot és a kérdőjelet kell

használni.

245
Intervallumok
Amennyiben egy értéknek egy intervallumba tartozását vagy ennek fordítottját akarjuk vizsgálni, akkor használható a
a < b < c helyett a b BETWEEN a AND c kifejezés. Ennek tagadása pedig b NOT BETWEEN a AND c formában
lehetséges.
Ez a kifejezés számokra értelemszerű. Talán a szöveges adatokra történő használata sem értelmezhető nehezen. Azon-
ban a dátumokra éppen olyan jól használható. Tegyük fel, hogy a 2005. januárjában keltezett számlákat szeretnénk meg-
kapni. Ekkor egyszerűen lekérdezhetjük ezeket a következő utasítással :

SELECT *
FROM számlák
WHERE dátum BETWEEN ’2005-01-01’ AND ’2005-01-31’;

Figyeljünk azonban arra, hogy a PostgreSQL hibás dátumot nem fogad el, tehát a ’2005-02-31’ dátumot nem
szerepeltethetjük még ilyen intevallumban sem, ugyanakkor például a MySQL intervallum megadásakor probléma nélkül
elfogadja a február lezárásaként értelmezve azt!

19.2.3. Az eredmény rendezése


Már említettük a kapott sorok esetleges sorba rendezését. Lássuk hát, hogyan is lehet ezt megtenni !
Egyszerűen írjuk az utasítás végére az ORDER BY záradékban vesszővel elválasztva a rendezés szempontjait, esetleg
a rendezés irányát is megadva: DESC csökkenő, ASC növekvő sorrend esetén. Például ha a filmeket hosszuk, azon belül
pedig címük alapján akarjuk rendezve látni, akkor azt a következő utasítással tehetjük meg :

SELECT *
FROM Film
ORDER BY hossz, cím;

Megjegyzés. Ne feledjük: a relációs adatmodell halmazoknak tekinti a relációkat, tehát alapesetben semmilyen rende-
zettséget nem lehet definiálni a sorok között. Ez azt jelenti, hogy az ORDER BY záradék nélkül a sorok megjelenési sor-
rendjére nézve nincs semmi támpont. Még abban sem bízhatunk, hogy a rekordok felvitelük sorrendjében jelennek meg.
Ezért ha ki akarunk használni az eredményben bármilyen rendezést, akkor adjuk meg a rendezést a SELECT utasításban.

19.3. Lekérdezések több táblával


A valós életben gyakorlatilag lehetetlen elképzelni olyan adatbázist, amely mindössze egyetlen adattáblával dolgozik –
az ilyen feladatok megoldására fölösleges adatbázist használni, elég egy táblázatkezelő is. Általában több adattáblában
elosztva tároljuk az adatokat, legalább a redundancia elkerülése érdekében.
A legegyszerűbb példa az irányítószámok és a helységnevek kapcsolata. Általában elmondható, hogy az irányító-
szám ismeretében egyértelműen meghatározható annak a városnak a neve, amelyhez tartozik. Fordítva már nem ilyen
egyértelmű : egy nagyobb városnak több irányítószáma lehet.
Amennyiben bármilyen címet akarunk nyilvántartani, abban a pillanatban a fentiek figyelembe vétele esetén két táb-
lára van szükségünk: az egyikben az irányítószámokhoz tartozó városneveket tároljuk, a másikban a címet, benne csak az
irányítószámmal, hivatkozva a másik, a város nevét tartalmazó táblára.
A fenti módon tárolt címeket viszont szeretnénk egy lekérdezéssel, mint teljes címet megkapni. Ehhez olyan lekérde-
zésre van szükség, amely egyszerre több táblát is érint, mégpedig lehetővé téve, hogy a több táblából csak az egymással
kapcsolatban álló sorok kerüljenek össze. Hogy megértsük ennek mikéntjét, szükség van egy matematikai fogalom pontos
ismeretére is.

246
19.3.1. A Descartes-szorzat

Két halmaz Descartes-szorzatán azt a halmazt értjük, melynek elemei a következőképpen keletkeznek az eredeti hal-
mazok elemeit felhasználva:
1. Vegyük az első halmaz minden egyes elemét, és párosítsuk össze a második halmaz minden egyes elemével.
2. Az így kapott (a; b) elempárok lesznek a szorzathalmaz elemei, ahol a az első, b a második halmaz eleme volt.

n halmaz Descartes-szorzata hasonlóan az a halmaz, amely tartalmaz minden olyan elem n-est, amelynek első eleme
az első halmaz eleme, második eleme a második halmaz eleme stb.

Vegyük a következő halmazokat: A = {a1 ; a2 ; a3 }, B = {b1 ; b2 ; b3 ; b4 } és C = {c1 ; c2 }. Ebben az esetben A × B


Descartes-szorzat elemei a következő elemek lesznek :
{(a1 ; b1 ), (a1 ; b2 ), (a1 ; b3 ), (a1 ; b4 ), (a2 ; b1 ), (a2 ; b2 ), (a2 ; b3 ), (a2 ; b4 ), (a3 ; b1 ), (a3 ; b2 ), (a3 ; b3 ), (a3 ; b4 )}.
Hasonlóan : A × C = {(a1 ; c1 ), (a1 ; c2 ), (a2 ; c1 ), (a2 ; c2 ), (a3 ; c1 ), (a3 ; c2 )}.
Ugyanakkor az A × B × C Descartes-szorzat elemeit a következő táblázat mutatja :
a1 b1 c1
a1 b1 c2
a1 b2 c1
a1 b2 c2
a1 b3 c1
a1 b3 c2
a1 b4 c1
a1 b4 c2
a2 b1 c1
a2 b1 c2
..
.
a3 b4 c2
Gondoljuk végig, mi lesz az eredménye a következő szorzatoknak : A × (B × C) illetve (A × B) × C ! Ha az ered-
ményben a belső zárójeleket elhagyjuk, akkor a két szorzat eredménye gyakorlatilag megegyezik.
Ezek alapján látható, hogy ha van két olyan halmazunk, amely elemei több érték meghatározott sorrendben vett
sorozataiból áll, akkor azt is tekinthetjük az értékeket szolgáltató halmazok Descartes-szorzatának egy részhalmaza-
ként. Tulajdonképpen a relációs adatmodell relációi nem mások, mint az egyes attribútumok értékhalmazaiból képzett
Descartes-szorzatnak egy valódi részhalmaza.5
Ha van két relációnk (vagy annak fizikai megvalósításaként két adattáblánk), amelyet a fenti modell szerint egy
Descartes-szorzat részhalmazának tekintünk, akkor ezeknek is vehetjük a Descartes-szorzatát. Az így kapott halmaz,
az eredeti két halmaz elemeinek minden lehetséges módon vett kombinációja lesz, azaz a relációkra lefordítva : az új
reláció sorai az eredeti két reláció minden egyes soraiból az összes lehetséges kombinációval állnak elő.
Megjegyzés. Felmerül a kérdés: mi van abban az esetben, ha az üres halmazt szorozzuk egy másik halmazzal ? A válasz
egyszerű : mivel a Descartes-szorzat definíciójából is következik, hogy egy n és egy m elemszámú halmaz Descartes-
szorzatának eredménye egy n·m elemű halmaz lesz, ha az üres halmazt (amelynek elemszáma 0) bármely más halmazzal
összeszorzunk, az eredmény a 0 elemszámú üres halmaz lesz. Ebből következik, hogy ha két olyan relációt szorzunk össze,
amelyek közül az egyik nem tartalmaz sorokat, akkor az eredményül kapott reláció sem fog tartalmazni sorokat.
5 A relációs adatmodellben azonban a relációkban az elemek ismétlődése lehetséges, és az attribútumok is elvileg bármilyen sorrendben megjelen-

hetnek, ha egyértelműen azonosítható, hogy melyik melyik attribútum. Ez azonban nem változtat azon a tényen, hogy a reláció matematikai modellje
az attribútumok értékhalmazaival képzett Descartes-szorzat részhalmaza.

247
19.3.2. A Descartes-szorzat megvalósítása a lekérdezésekben
A SELECT utasításban két vagy több tábla Descartes-szorzatát nagyon egyszerű megvalósítani. Egyszerűen írjuk a FROM
záradékban egymás után a táblák neveit vesszővel elválasztva. Amennyiben létezik egy lakcímek és egy irányítószámok
nevű adattábla, akkor a kettő Descartes-szorzatát a következő utasítással tudjuk megjeleníteni :
SELECT *
FROM lakcímek, irányítószámok ;
Az eredmény egy olyan tábla lesz, amely tartalmaz minden olyan sort, amelynek első valahány attribútuma (annyi,
amennyi a lakcímek táblában volt) a lakcímek tábla soraiból van, a további oszlopok pedig az irányítószámok táblából
származik. Mivel feltehetően mindkettőben van irányítószám, ezért ennél látható, hogy az azonos nevű oszlopokat hogyan
lehet ilyenkor megkülönböztetni egymástól: a mező neve előtt egy pontot megelőzően szerepel a tábla neve.
A tábla soraiban szerepel minden párosítás, amely a két tábla egyes soraiból előállhat. Általában azonban ez nem
felel meg annak, amire szükségünk van, nekünk a fenti példában csak azok a sorok kellenek, ahol az irányítószám a két
táblából származó sorban megegyezik.
Az összetartozó sorokból a szorzatban keletkezett sorokat pontosan ugyanúgy kaphatjuk meg, mint bármely más,
valamely feltételnek megfelelő sort: a WHERE-záradékban megadjuk a feltételek között azt, amely gondoskodik róla,
hogy csak a nekünk megfelelő sorok maradjanak meg.6
A szükséges sorok kiválasztása általában nagyon egyszerűen történik : a két összekapcsolt táblában a hivatkozott és a
rá hivatkozó mező értéke az összetartozó sorokban azonos. Így nem kell mást tenni, mint megkeresni azokat a sorokat, ahol
a hivatkozott tábla kulcsmezői és a hivatkozó tábla rá hivatkozó külső kulcsának mezői páronként megegyeznek. Ezeket
az egyenlőségvizsgálatokat az esetleges további feltételekkel együtt teljesítendő feltételekkel kell megadni – vagyis ÉS
művelettel kell a többi feltételhez kapcsolni.
A fenti példa módosításaként íme az utasítás, amely csak a helyes adatokat tartalmazó sorokat mutatja meg :
SELECT *
FROM lakcímek, irányítószámok
WHERE lakcímek.irányítószám = irányítószámok.irányítószám ;
Mint a példában is látható, az egyes adattáblákban szereplő mezőket egyértelművé lehet tenni, ha a mező neve előtt
megadjuk a tábla nevét egy ponttal elválasztva a mezőnévtől. Ez minden esetben használható, de azonos nevű mezők
esetén elkerülhetetlen.
Amennyiben egy konkrét személy adataira vagyunk kíváncsiak, akkor a feltételben megadható az is, ami a keresett
személy adataira szűkíti az eredményt. Mint említettük, akkor az összetartozó sorokat kiválasztó feltétel(ek) és a többi
feltétel egyszerre kell, hogy teljesüljön:
SELECT *
FROM lakcímek, irányítószámok
WHERE lakcímek.irányítószám = irányítószámok.irányítószám
AND lakcímek.név LIKE ’Szabó %’ ;
A fenti utasítás minden olyan személy teljes lakcímét fogja eredményül adni, akinek a neve a „Szabó ” szöveggel
kezdődik. Mint látható a két feltételt az AND szó kapcsolja össze, amely miatt a teljes logikai kifejezés csak akkor lesz
igaz, ha mindkét feltétel igaz.
Azonban a fenti utasítások mindegyikének van egy hibája : az irányítószám kétszer szerepel benne. Egyszer a lakcímek
táblából, egyszer pedig az irányítószámok táblából származik. Mivel a feltételek már gondoskodnak arról, hogy a két
irányítószám megegyezzen, ezért fölösleges kétszer kiíratni. Természetesen a SELECT záradékban a kiíratni kívánt mezők
listáját megadva ez a probléma is megoldható. A következő utasítás mutatja, hogy ilyenkor hogyan lehet használni a tábla
nevét a mező pontosítására:
6 A WHERE által megvalósított műveletet, amely kiválasztja a feltételnek megfelelő sorokat, az adatbázis kezelésben és a relációs adatmodellben

egyaránt kiválasztásnak nevezik, ugyanakkor a MS által elterjesztett kifejezés erre a szűrés. Ez utóbbi kifejezést használja az Access mellett az Excel,
és ennek nyomán általában a táblázatkezelők is erre a műveletre.

248
SELECT név, lakcímek.irányítószám, irányítószámok.város,
utca, házszám
FROM lakcímek, irányítószámok
WHERE lakcímek.irányítószám = irányítószámok.irányítószám
AND lakcímek.név LIKE ’Szabó %’ ;
Mint látható, ha olyan mezőre hivatkozunk, amely csak az egyik táblában szerepel, akkor mivel a mezőnév önmagában
is egyértelműen adja meg a megfelelő oszlopot, a tábla neve elhagyható. De ha ilyenkor megadjuk a tábla nevét – mint a
feltételben –, akkor sem követünk el hibát, csupán hosszabbá, de olvashatóbbá tesszük az utasítást.
Előfordulhat olyan eset is, amikor ugyanannak az adattáblának több példányát akarjuk használni egy lekérdezésben.
Ilyen eset lehet az egyed-kapcsolat modell bemutatásánál szereplő példa, amikor egy film és annak folytatásaiként szü-
letett filmek kerülnek kiírásra, vagy az az eset is, amikor azoknak a nevét akarjuk megkapni, akik azonos helyen laknak,
azaz megegyezik a lakcímük.
Ilyen esetben egy adattáblának önmagával vett Descartes-szorzatát kell vennünk. Ekkor minden mező kétszer fog
szerepelni, és mindkét esetben ugyanaz lesz a tábla neve is. Megkülönböztetni a fenti módon nem lehet őket egymástól.
Az ebből adódó probléma megoldására vezették be az SQL-ben a másodneveket, amelyek a SELECT záradéknál már
bemutatott módhoz hasonlóan – ahol az eredményül kapott tábla oszlopát lehetett egy AS szó segítségével új névvel
ellátni – a táblának lehet új nevet adni, amely attól kezdve akár a SELECT, akár a WHERE szó – akár a később bemutatott
záradékok kulcsszavai – akár az ORDER BY után használható a táblanév helyett. Amennyiben enélkül is egyértelmű,
hogy melyik tábláról van szó, akkor a táblanév, és a másodnév egyenrangúan használható.
Az alábbi példa mutatja, hogy a másodneveket hogyan lehet használni :
SELECT t1.név, t2.név
FROM lakcímek AS t1, lakcímek AS t2
WHERE t1.irányítószám = t2.irányítószám
AND t1.utca = t2.utca AND t1.házszám = t2.házszám
AND t1.név < t2.név
ORDER BY t1.név ;
Mint látható, a táblamásodneveket – szokás sorváltozónak is nevezni – a tábla valódi neve után egy AS szó után kell
megadni.7 A példában egyébként egy elég összetett, de a szükségesnél többet nem tartalmazó feltétel szerepel. A feltétel
a következőt jelenti:
• Az azonos lakcím azt jelenti, hogy ugyanaz az irányítószám (ebből következően ugyanaz a város), ugyanaz az utca
és azon belül a ház száma is (ezen belül persze még az emeletnek és az ajtó számának is meg kell egyeznie, de ezt
most beleértjük a házszámba). Így mindhárom mező értékeinek a két táblában – amely most ugyanannak a táblának
két sorából származik – meg kell egyeznie.
• Mivel a Descartes-szorzat ilyen esetben minden elemet önmagával is párba rak, az előző pontban szereplő feltétel
még megtartja azokat a sorokat, amelyekben mind a t1, mind a t2 táblából ugyanazt a személyt kapjuk. Ő nyilván
önmagával azonos lakcímen lakik, de rá nincs szükségünk. Csak azokat a sorokat szeretnénk megtartani, akiknél a
lakcím ugyan megegyezik, de a név nem.

• Ha a feltétel utolsó részében pusztán azt vizsgálnánk, hogy a két név különbözik, az már jó eredményt adna,
de minden azonos címen lakó pár kétszer szerepelne : egyszer amikor X az első táblából származik, Y pedig a
másodikból, egyszer pedig amikor Y származik az első táblából, X pedig a másodikból. Az ebből adódó dupla
szereplést lehet kiszűrni azzal, ha kihasználjuk a nevek rendezhetőségét, és a kisebb relációt adjuk meg. Így a két
eset közül csak az egyik marad meg, a másikra a feltétel nem teljesül.
7 A PostgreSQL-ben az AS elhagyható, a szabvány ezt nem feltétlenül engedi meg, ezért abban az esetben, ha más adatbázis-szerveren is használható

utasításokat akarunk, célszerűbb beleírni az utasításba az AS szót is. . .

249
Persze a fenti példában még egy névsor szerinti rendezés is szerepel. Azonban abban az esetben, ha egy családnak
kettőnél több tagja is van a nyilvántartásban, akkor az első rendezés még nem garantálja, hogy egy család tagjai egymás
után szerepelnek. Ezt meg lehetne oldani, ha a lakcím szerint rendeznénk az eredményt, vagy ha mindkét név alapján
rendeznénk.
Másik megoldás az eredménysorok csoportosítása akár lakcím, akár név szerint. Erre a később bemutatandó GROUP
BY záradék ad majd megoldást. . .
Természetesen a másodneveket akkor is használhatjuk, ha a táblák saját nevei is egyértelműek lennének, de túl hosszú-
ak. Az előző, lakcímes példa a másodnevek használatát mutatja, ráadásul még az oszlopot is átnevezzük, hogy az ered-
mény jobban olvasható legyen:
SELECT név AS lakó, t1.irányítószám AS irányítószám,
város AS település, utca, házszám
FROM lakcímek AS t1, irányítószámok AS t2
WHERE t1.irányítószám = t2. irányítószám
AND t1.név LIKE ’Szabó %’
ORDER BY t1.név ;

További lehetőséget nyújt több tábla összekapcsolására az alkérdések használata, amelyről még később ejtünk szót.
Ezeken kívül meg kell még ismerni a csoportosítás és az ezzel használható speciális függvények használatával, amelyek
számadatok összesítésére alkalmasak. Előbb azonban foglaljuk össze, amit a FROM záradékról tudunk !

19.3.3. A FROM záradék


Az eddigiekben már láttunk néhány példát a FROM záradék használatára. Lesz még egy-két lehetőség, amelyet itt hasz-
nálhatunk, ám ideje összefoglalni, mire is való ez a része az utasításnak.
Tehát a SELECT utasítás végrehajtása minden esetben azzal kezdődik, hogy a FROM záradék alapján elő kell állítani
azt a rekord-halmazt, amellyel az utasítás többi része dolgozik : a WHERE kiválogatja annak a feltételnek megfelelő
sorait, a SELECT záradék kifejezéseit pedig minden megmaradt sorra kiértékeli az utasítás stb.
A FROM szó után megadottak tehát egy táblát állítanak elő. Ez származhat egy adattáblából vagy nézettáblából.
De származhat több táblából, azok Descartes-szorzataként. A későbbiekben még látunk példát arra is, hogy akár egy
egész, SELECT utasítással létrehozott lekérdezés eredménye is felhasználható. A Descartes-szorzat helyett más, hasonló
táblakapcsolódásokat is ismer az SQL, amelyek a JOIN kulcsszóval hozhatóak létre.
Összefoglalva tehát a FROM záradék a táblázatot, amin a SELECT dolgozik, összeállíthatja táblákból, alkérdésekből
(lásd később, a 19.4 fejezetben), táblakapcsolásokból, vagy ezek bármilyen bonyolultságú kombinációjából.

Összekapcsolási típusok
Több tábla összekapcsolható a JOIN szó használatával. A lehetséges összekapcsolások a belső, külső és a kereszt JOIN
(outer, inner és cross join). Lássuk ezeket hogyan lehet használni. A meghatározásokban két táblát kapcsolunk össze, ezek
neve T1 és T2 lesz.

cross join Ez a fentebb részletesen ismertetett Descartes-szorzat :

FROM t1 CROSS JOIN t2

vagy

FROM t1,t2

250
egyaránt azt a táblát eredményezi, amely a T1 × T2 szorzatból származik : T1 minden sorához hozzáragasztjuk
egy-egy eredmény-sorban a T2 minden egyes sorát.
feltételes összakapcsolások Ezek olyan külső vagy belső összekapcsolások, amelyeknél egy adott feltételnek megfelelő
sorok kerülnek összekapcsolásra. Általános szintaxisa a következő :

t1 { [ INNER ] | { LEFT | RIGHT | FULL } [ OUTER ] } JOIN t2


ON feltétel

vagy

t1 { [ INNER ] | { LEFT | RIGHT | FULL } [ OUTER ] } JOIN t2


USING (oszloplista)

vagy

t1 NATURAL { [ INNER ] | { LEFT | RIGHT | FULL } [ OUTER ] } JOIN t2

Amennyiben szerepel az INNER szó, akkor belső, egyébként külső összekapcsolás lesz belőle. A LEFT, RIGHT
vagy FULL szó határozza meg, hogy a külső összekapcsolás hogyan történik.
Az ON utáni feltétel megadása esetén azok az eredmény-sorok maradnak meg, amelyekre a feltétel teljesül. A
USING és az oszloplista megadása esetén a megadott oszlopok értékének kell páronként megegyeznie a két táblából
származó sorokra. Ez azt is jelenti, mintha az ON után ezek két táblabeli megfelelőjét egyenlővé tettük volna. A
NATURAL szó megadása egyenértékű azzal, mintha a USING után pontosan azokat az oszlopokat soroltuk volna
fel, amelyek mindkét táblában szerepelnek.

inner join belső összekapcsolások. A fenti pontban ismertetett feltételes összekapcsolásokban ha az INNER szó szere-
pel, az ilyen összekapcsolást eredményez. Ez tulajdonképpen a szokásos Descartes-szorzatot jelenti, de a korábbi
példáknál a WHERE záradékban megadott szűrőfeltételt az ON szó után kell megadni, vagy egyszerűen felsorolni
a szükséges oszlopokat a USING szó után, és máris csak a szükséges sorok maradnak meg.
Tehát a belső összekapcsolás a Descartes-szorzatnak a feltételeknek megfelelő részhalmazát adja. Éppen ezért elég
sűrűn használható a több lehetséges forma valamelyikében.
outer join külső összekapcsolások. Ez a Descartes-szorzat egy kiterjesztése. Először vesszük a T1 × T2 Descartes-
szorzatot – a megfelelő feltételeket is figyelembe véve a megtartandó soroknál. Ezután T1 minden olyan sorára,
amelyre nem teljesül a megadott kapcsoló feltétel a T2 -beli egyetlen sorra sem, bevesszük a T1 sorának értékeit, de
mellé a T2 -ből származó oszlopok értékéül NULL értéket adunk. Így T1 minden sora legalább egyszer szerepelni
fog az eredményben.
A fentiek akkor igazak, ha a külső összekapcsolás balról történik (left outer join). Jobbról való összekapcsolásnál
(right outer join) a T2 soraihoz veszünk szükség esetén NULL értékeket T1 oszlopaiba. Teljes összekapcsolásnál
(full outer join) a baloldali és a jobboldali összekapcsolás unióját kell venni.

Az összekapcsolások tetszőleges mélységben kapcsolódhatnak egymáshoz. Akár zárójelezéssel is lehet irányítani az


összekapcsolások sorrendjét. Így rendkívül összetett feltételek is alkalmazhatóak (rendkívül bonyolult SELECT utasítá-
sokat eredményezve).

251
19.3.4. Unió, metszet és különbség megvalósítása
A Descartes-szorzat nem az egyetlen halmazművelet, amelyet a lekérdezésekben használhatunk. Amennyiben van két
teljesen egyforma táblánk, akkor vehetjük azok unióját, metszetét vagy különbségét is.
Teljesen egyformának akkor számítanak a táblák, ha pontosan ugyannyi oszlopuk van, az oszlopok neve és típusa
rendre megegyezik. Előfordulhat, hogy a táblák nem adattáblákból adódnak, hanem már eleve valamely lekérdezés ered-
ményeként állnak elő. Ez lehetővé teszi azt is, hogy egymástól eltérő szerkezetű táblákból nyert sorokat használjunk,
hiszen a SELECT utasításban akár át is lehet nevezni az oszlopokat.
Az SQL szabvány szerint az egyes táblákat létrehozó SELECT utasításokat zárójelbe kell tenni, és a megfelelő hal-
mazműveletet közéjük írni. A PostgreSQL használata esetén a zárójelek elhagyhatóak. Az egyes műveleteket megvalósító
kulcsszavak a következők:
unió ∪: UNION. Azokat a sorokat tartalmazza az eredmény, amelyek legalább az egyik táblában szerepelnek.

metszet ∩: INTERSECT. Azokat a sorokat tartalmazza az eredmény, amelyek mindkét táblában szerepelnek.
különbség A−B : EXCEPT. Az első tábla (A) azon sorait tartalmazza, amelyek nem szerepelnek a második (B) táblában.

19.4. Alkérdések
Mind a WHERE, mind pedig a FROM záradékban lehetőség van arra, hogy akár egyetlen értéket, akár egy teljes adattáblát
előállítsunk egy belső lekérdezéssel, amelyet egy beágyazott SELECT utasítás menetközben állít elő. Az ilyen belső
lekérdezéseket nevezi a szakirodalom alkérdésnek, vagy angolul subquery-nek.
A FROM záradékban a szerepe csupán annyi, hogy egy lekérdezés ereményeként kapott táblázatot, mint a SELECT
utasításhoz használt tábla elemét használjuk. Egy adattábla helyén zárójelek között szerepeltetve egy táblázatot ered-
ményül adó SELECT utasítást, annak eredményét a FROM záradék ugyanúgy értelmezi, mint egyszerű táblahivatkozást.
Ilyen esetben az alkérdés eredményét mindenképpen el kell nevezni egy másodnévvel az AS szó segítségével (ha az alkér-
dés egy összekapcsolás eleme, akkor az egész összekapcsolás kap nevet), mivel másképpen nem lehet az ebből származó
oszlopokra hivatkozni.
A WHERE záradékban történő allekérdezések már sokkal összetettebbek. Tulajdonképpen nem is a WHERE zára-
dékhoz kötődnek ezek, mivel akár az UPDATE utasítás SET záradékában is használható alkérdés egy kifejezésben. Ebben
az esetben persze az alkérdés nem táblát kell adjon eredményül, hanem egyetlen értéket.
Ilyen szempontból tehát az alkérdéseket négy csoportba lehet osztani :

skalár értéket adó lekérdezés olyan SELECT utasítás, amely egy egysoros, egyoszlopos táblázatot, tehát egyetlen érté-
ket ad eredményül. Ezt olyan helyen lehet szerepeltetni – de ott bárhol –, ahol egy értéknek kell állnia.
listát adó lekérdezés olyan SELECT utasítás, amely egyoszlopos, de többsoros táblázatot ad eredményül. Az ilyen al-
kérdés ott használható, ahol egy listát kell megadni. Például a logikai értéket adó IN operátor a baloldalán levő
értéknek a jobboldalon álló listában való meglétét vizsgálja. Amennyiben a baloldalon skalár érték áll, akkor a
jobboldalon listát adó alkérdés állhat.
sort adó lekérdezés olyan SELECT utasítás, amely több oszlopos, de garantáltan egyetlen sort adó táblázatot eredmé-
nyez. Olyan helyen használható, ahol egyetlen rekordnak kell állnia. Az előző példában szereplő IN operátor bal-
oldalán állhat ilyen, amely esetben a jobboldlon egy reláció állhat.
relációt adó lekérdezés olyan SELECT utasítás, amely eredményül egy általános táblázatot adhat. Általában a FROM
záradékban szerepelhet, de az IN operátor jobboldalán is állhat, ha a baloldalon egy sort adó lekérdezés áll. Ebben
az esetben persze a két operandusban az oszlopoknak páronként azonos nevűnek és típusúnak kell lennie.
A következőkben megvizsgáljuk a lekérdezéseket fajtánként.

252
19.4.1. Skalár értéked adó lekérdezések
Mint a fenti felsorolásban már szerepelt, vannak olyan lekérdezések, amelyek – bár relációt adnak eredményül, mint
minden SELECT – összesen egy értéket adnak. Tulajdonképpen az oszlopok számát egyre csökkenteni nagyon könnyű,
hiszen ehhez csak az kell, hogy a SELECT záradékban egyetlen kifejezés szerepeljen.
A sorok számát egyre csökkenteni a LIMIT 1 záradék szerepeltetésével lehet, de nem ez a legáltalánosabb. Inkább az
jellemző, hogy valami olyan kifejezést használunk, amely az egész táblára egyetlen értéket számol. Az ilyen kifejezések
általában tartalmaznak egy összesítő függvényt, amelyeket majd később ismertetünk.
Például szeretnénk megkapni azokat a dolgozókat, akiknek a fizetése alacsonyabb az átlagfizetésnél. Az átlagfizetés
egyszerűen megkapható a következő utasítással (megfelelő adattáblát feltételezve) :
SELECT avg(fizetés)
FROM bérek ;
Ez az utasítás egyetlen értéket eredményez, amelyet fel lehet használni az ennél alacsonyabb fizetésű dolgozók lekérde-
zéséhez :
SELECT név, fizetés
FROM bérek
WHERE fizetés < (
SELECT avg(fizetés)
FROM bérek
);
Ekkor először az alkérdés kerül végrehajtásra, majd az eredménye felhasználásával a külső lekérdezés. Ez azt jelenti,
hogy az alkérdés mindössze egyetlen egyszer hajtódik végre. Ez azt is jelenti, hogy ha meg akarjuk növelni tiz százalékkal
azok fizetését, akik átlag alatti fizetéssel rendelkeznek, akkor az megtehető a következő utasítással :
UPDATE bérek
SET fizetés = fizetés * 1.1
WHERE fizetés < (
SELECT avg(fizetés)
FROM bérek
);
Ez az utasítás egyetlen lépésként hajtódik végre még akkor is, ha több száz rekordot módosít. Így a végrehajtás során a
módosítás nem befolyásolja az átlagfizetést, amely csak egyszer kerül kiszámolásra, és utána ez alapján választódnak ki
a módosítandó rekordok.

19.4.2. Relációkat tartalmazó alkérdések


Az alkérdések csoportosításánál szereplő másik három alkérdés fajta valamilyen értelemben már általános relációt ad.
Ezek felhasználhatók a FROM záradékban, de van néhány operátor, amellyel a WHERE záradékbeli feltétel előállításához
is használhatóak. Íme ezek az operátorok:
• Az EXIST R egy olyan feltétel, amely pontosan akkor igaz, ha az R relációnak van sora. Halmazokra lefordítva:
R 6= ∅.
• s IN R pontosan akkor igaz, ha s ∈ R, azaz az s megegyezik az R reláció valamely elemével (ha s skalár, akkor
R mint halmaz egy elemével, de s lehet egy sor is, ekkor R egy sorával kell megegyeznie). s NOT IN R jelentése :
s 6∈ R.
• s > ALL R pontosan akkor igaz, ha s nagyobb az egyoszlopos R reláció minden egyes eleménél. A > reláció
kicserélhető bármely összehasonlító operátorra értelemszerű jelentéssel.

253
• s > ANY R pontosan akkor igaz, ha s nagyobb az egyoszlopos R reláció legalább egy eleménél. A reláció itt is
kicserélhető.
Amennyiben s helyén egy sort akarunk szerepeltetni, azt is megtehetjük, sőt ekkor még konstansként is megadható az
s, zárójelek között az egymás utáni értékek felsorolásával.8 Akár attribútumok is megadhatóak ilyenkor, sőt a konstansok
és a mezőnevek szabadon kombinálhatók is:
(15, ’alfa’)
(név, fizetés)
(15, név)
A fenti mindhárom sorban egy-egy szintaktikailag helyes sor szerepelt.
Amennyiben egy t sornak és egy R relációnak ugyanannyi oszlopa van, és az oszlopokat típus szerint is megegyezőnek
lehet tekinteni, akkor a fenti operátorok használhatók köztük való kapcsolat leírására. Ha például a t < ANY R kifejezést
adjuk meg, akkor a kisebb relációt lexikografikus kisebb relációként kell értelmezni, ahol az oszlopok lesznek az egyes
komponensei az összehasonlításnak (a < b, ha a első oszlopbeli értéke kisebb b első oszlopbeli értékénél, vagy az első
valahány oszlopon megegyeznek az értékek, utána pedig az a-ban van kisebb érték).
Vegyük a következő példát a [5] 5.18. példája alapján. A következő relációkat használjuk a lekérdezéshez :
• Film (cím, év, hossz, színes, stúdiónév, producerAzon) ;
• SzerepelBenne (filmcím, év, színésznév);
• Producer(név, cím, azonosító, nettóBevétel).
Szeretnénk megkapni azokat a producereket, akik által készített filmekben Harrison Ford játszott.
Építsük fel a lekérdezést belülről kezdve. Először meg kellene kapnunk minden olyan filmet, amelyben Harrison Ford
szerepelt. Azokat a filmcímeket és éveket kell megkapnunk,9 amelyeknél a színész neve Harrison Ford :
SELECT filmcím, év
FROM SzerepelBenne
WHERE színésznév = ’Harrison Ford’;
Ha ismertek a filmek, akkor megkereshetjük a Film relációban az azokat készítő producerek azonosítóját :
SELECT producerAzon
FROM Film
WHERE (cím, év) IN (
SELECT filmcím, év
FROM SzerepelBenne
WHERE színésznév = ’Harrison Ford’
);
Ez egy azonosítót ad eredményül, mi azonban jobban szeretnénk a nevét látni az illetőnek. Mi sem egyszerűbb : a fenti
lekérdezést mint alkérdést illesszük be abba a lekérdezésbe, amely az azonosító alapján megadja a nevet :
SELECT név
FROM Producer
WHERE azonosító IN (
SELECT producerAzon
FROM Film
WHERE (cím, év) IN (
8 Tulajdonképpen az INSERT utasításban is így kell megadni a sort, amelyet fel kell vinni a táblába.
9A Film reláció kulcsa a filmcím és az év együtt.

254
SELECT filmcím, év
FROM SzerepelBenne
WHERE színésznév = ’Harrison Ford’
)
);
Megjegyzés. A MySQL jelenleg még nem ismeri az alkérdéseket, így ott a fenti gondolatmenetet alkalmazva ideiglenes
táblákat kell készíteni, amelyben az alkérdések tárolhatóak a következő lépésig. A legnagyobb hiányossága a MySQL-nek
éppen az alkérdések hiánya, hiszen ha belegondolunk az alkérdések erejébe a lekérdezéseknél, látható, mekkora veszteség,
ha nem használhatjuk azokat.
Természetesen a fenti eredmény Descartes-szorzat alkalmazásával is megoldható alkérdések nélkül, de sokkal olvasha-
tatlanabb utasítást eredményez, ráadásul nagyobb memória- és CPU-igénnyel is jár az a megoldás a legtöbb megvalósítás
esetén :
SELECT név
FROM Producer, Film, SzerepelBenne
WHERE azonosító = producerAzon AND
Film.cím = filmcím AND
Film.év = SzerepelBenne.év AND
Színész = ’Harrison Ford’
;
Ugye, mennyivel áttekinthetőbb az alkérdéses változat !

19.4.3. Korrelált alkérdések


A fenti példákban szereplő alkérdések az utasítás végrehajtása során csak egyszer kerültek kiértékelésre. Azonban van
arra is lehetőség, hogy olyan alkérdést készítsünk, amely egy lekérdezésen belül többször is kiértékelésre kerül – esetleg
más-más eredményt adva.
Ismét a [5] (5.19.) példáját használva, keressük meg azokat a filmcímeket, melyek két vagy több filmhez is tartoznak
(ezek miatt kell a Film reláció kulcsába az év mező is).
Ehhez minden egyes sor esetén meg kell vizsgálni, hogy létezik-e olyan sor, amelyben a cím ugyanez. Mivel feltet-
tük, hogy a cím és az év együtt már kulcs, ezért két azonos című film nem készülhetett ugyanabban az évben. Ez azt
jelenti, hogy annak vizsgálatára, hogy a cím egy másik sorban szerepel, alkalmas az év különbözőségének vizsgálata.
Korábbi példánál már láttuk, hogy a dupla szerepeltetés egyszerűen elkerülhető a nem egyenlő helyett a kisebb reláció
használatával.
Egy adott cím esetén a filmkészítés évét nyilván megkaphatjuk a következő lekérdezéssel :
SELECT év
FROM Film
WHERE cím = keresettcím ;
A keresettcím helyére egy konkrét címnek kell kerülnie.10
A keresettcím értéke a táblázat minden egyes sora esetén más lesz. Az alábbi utasításban az alkérdésben már az éppen
vizsgált sor alapján helyettesítjük be az értékét:
SELECT cím
FROM Film AS régi
WHERE év < ANY (
10 Az ilyen alakú utasításokat nevezzük paraméteres lekérdezésnek : valamely azonosító helyére egy konkrét értéket kell megadni. Az MS Access-ben

lehet olyan lekérdezést definiálni, amelyben szerepel egy vagy több azonosító, amely egyébként az érintett táblákban nem szerepel. Ekkor a lekérdezés
megnyitásakor ezen azonosítók helyére írandó értéket megkérdezi az Access, majd a kapott értékeket behelyettesítve hajtja végre az utasítást.

255
SELECT év
FROM Film
WHERE cím = régi.cím
);
Az utasításban egy konkrét sorra a külső feltétel akkor lesz igaz, ha létezik olyan film, amelynek címe megegyezik az
aktuális sorban levő címmel, és a gyártási éve alapján régebben készült, mint az éppen vizsgált film.
Az ilyen lekérdezéseknél felmerül a kérdés, hogy az egyes nevek hol használhatóak. Általában egy lekérdezésben sze-
replő attribútum a lekérdezés FROM záradékában szereplő valamelyik táblához, vagy annak másodnevéhez mint sorválto-
zóhoz tartozik, amennyiben az a reláció tartalmazza a szóban forgó attribútumot. Ha nem tartalmazza, akkor a lekérdezést
tartalmazó lekérdezést kell vizsgálni, folyamatosan haladva kifelé, amíg meg nem találjuk a megfelelő relációt.
Egy attribútum azonban bármely relációhoz hozzá kapcsolható a reláció nevének megadásával az attribútum előtt,
attól ponttal elválasztva. A fenti példában ilyen módon tudjuk a külső lekérdezésbeli sort a régi másodnév megadásával
elérni. Amennyiben a külső és a belső lekérdezésben más-más relációk szerepeltek volna és az attribútum megadása a
reláció megadása nélkül is egyértelmű lett volna, akkor nem lett volna szükség a reláció megadására.

19.5. Halmazok és multihalmazok különbsége


Mivel az SQL a relációkat multihalmazként kezeli, ha szükséges az eredmény egyedi elemeket tartalmazó halmazzá alakí-
tása, akkor azt a DISTINCT szó alkalmazásával tehetjük meg. Ezt a szót közvetlenül a SELECT szó után kell megadni az
érintett lekérdezésben. Például ha egy relációban tároljuk egy iskola valamennyi diákjának hiányzását, és azt szeretnénk
megtudni, hogy melyik napon hiányoztak diákok, akkor annak elkerülésére, hogy egy dátum annyiszor jelenjen meg,
ahány diák aznap hiányzott, a következő utasítást alkalmazhatjuk:
SELECT DISTINCT dátum
FROM hiányzások ;
A halmazműveletek alaphelyzetben valóban halmazokkal dolgoznak, azaz ha egy sor két halmazból is származna,
akkor csak egyszer kerül az eredményhalmazba. Ha ilyenkor minden példányát meg akarjuk tartani, a halmazműveletet
megadó szó után írjuk az ALL szót is.

19.6. Összesítések
Vannak olyan esetek, amikor nem egy rekord adatait felhasználva szeretnénk információhoz jutni, hanem több rekord
valamely oszlopának értékéből szeretnénk egy adatot megkapni. Például ha arra vagyunk kiváncsiak, hogy hány olyan
ügyfelünk van, akinek nem ismert a telefonszáma, akkor azokat a rekordokat kellene megszámolni, amelyekben a tele-
fonszám mező üres. Az is elképzelhető, hogy a napi bevételt szeretnénk tudni, és egy olyan adattáblánk van, amelyben
egy-egy rekordban szerepel minden vásárlás végösszege. Ekkor nyilván a megoldás az egyes vásárlások végösszegeinek
összegzése lenne azokra a rekordokra, amelyekben a vásárlás dátumaként a mai nap szerepel.
Az ilyen és ezekhez hasonló kérdésekre kaphatunk választ az összesítő függvények segítségével. Az összesítő függ-
vények nem egy rekordot dolgoznak fel, hanem egy adott oszlopot. Az SQL a következő összesítő függvényeket ismeri :
• A count függvény megszámolja a SELECT utasítás eredményeként keletkezett rekordokat. A fenti példák közül a
telefonszámmal nem rendelkező rekordokat lehet például megszámolni a következő utasítással (megfelelően defi-
niált adattáblát feltételezve):

SELECT count(*)
FROM ügyfelek
WHERE telefon IS NULL;

256
Amennyiben az adattáblában ugyanaz az ügyfél többször is szerepelhet, akkor persze minden egyes alkalommal
egyszer megszámlálásra kerül. Megfelelően megfogalmazott feltétel esetén az ismétlődést a DISTINCT szóval
kiszűrhetjük, ha a count(DISTINCT *) kifejezést használjuk.
Mivel a count a rekordokat használja, paraméterében egyszerűen a csillag adható meg. Ez az egyetlen függvény,
amelynek paramétereként a csillag (minden oszlop) szerepelhet.
• A sum függvény összeadja a paraméterében szereplő nevű oszlop értékeit a WHERE záradék által kiválasztott
rekordok esetében. Például a napi bevétel kiszámítása lehetséges az alábbi utasítással :

SELECT sum(fizetendő)
FROM számlák
WHERE dátum = current_date();

A current_date függvény az aktuális dátumot adja eredményül.


• A min függvény a paraméterében megadott nevű oszlop esetén megkeresi a WHERE záradék által kiválasztott
rekordok közül a legkisebb értékűt. Dátumokra és szövegekre is alkalmazható.
• Hasonlóan, a max függvény a legnagyobb értéket adja a szóban forgó rekordok megadott oszlopában levő értékek
közül.
• Az avg függvény átlagolja a WHERE záradék által kiválasztott rekordoknak a paraméterben levő nevű oszlopának
értékeit. Például az átlagéletkor kiszámítása lehetséges a következő utasítással :

SELECT avg(életkor)
FROM diákok;

19.6.1. Csoportosítás
Előfordulhat, hogy nem az összes sorra akarunk egy összesítést kapni, hanem például szeretnénk osztályonként az átlagé-
letkort megkapni. Ekkor használhatjuk ki azt a lehetőséget, amit a GROUP BY záradék kínál : csoportosítható akár több
oszlop alapján az eredmény. Az osztályonkénti átlagéletkort megkaphatjuk például a következőképpen :
SELECT osztály, avg(életkor)
FROM diákok
GROUP BY osztály ;
Figyeljük meg, hogy most a SELECT záradékban nem csupán egy összesítő függvény szerepel, hanem egy olyan mező
is, amely a GROUP BY záradékban is szerepel. Alapvető szabály, hogy összesítő függvény a SELECT záradékban nem
szerepelhet együtt csak másik összesítő függvénnyel vagy olyan önálló mezőre hivatkozó kifejezéssel, amely a GROUP
BY záradékban is szerepel. Ez utóbbi biztosítja, hogy minden eredményül kapott sorban egyértelműen meghatározható a
mező értéke, az összesítő függvény pedig éppen azon rekordok összesítését végzi, amely erre a csoportra tartozik.
Fordítva is igaz: ha a GROUP BY záradék szerepel, akkor csak az itt szereplő mezők és az összesítő függvények
szerepelhetnek a SELECT záradék kifejezéseiben.
Tulajdonképpen a GROUP BY záradék egy-egy csoportba rendeli azokat a rekordokat, amelyek a záradékban felsorolt
valamennyi oszlopon azonos értékkel rendelkeznek. Ezzel a módszerrel lehet például összesíteni naponta a bevételt :
SELECT dátum, sum(fizetendő)
FROM számlák
GROUP BY dátum

257
A mezők megadási sorrendje nem lényeges, hiszen egy-egy csoporton belül minden mezőnek a megadottak közül meg
kell egyeznie az összes rekordban.
A csoportosítás minden esetben a WHERE záradék végrehajtása után történik, tehát a feltételnek megfelelő sorokat
kapja meg csoportosításra a GROUP BY záradék.
Amennyiben az így létrejött csoportok közül nem mindegyikre van szükségünk, akkor használhatjuk ezek kiválasz-
tására a HAVING záradékot. Itt olyan feltételeket adhatunk meg, amelyek egy-egy csoportra értelmesek, azaz vagy igaz
vagy hamis értékük meghatározható a csoportra együtt. Ebből az is következik, hogy itt az összesítő függvények szere-
pelhetnek.
Például szeretnénk azokon a napokon látni az összes bevételt, ahol a legkisebb egyszeri vásárlásból származó bevétel
(a fizetendő oszlop értéke) is elérte a 10 000 Ft-ot:
SELECT dátum, sum(fizetendő)
FROM számlák
GROUP BY dátum
HAVING min(fizetendő) >= 10000 ;
A fenti utasítás elméletben11 a következőképpen hajtódik végre :
1. A FROM záradék alapján előállítja a használandó táblát. Ez most egyszerűen azt jelenti, hogy a számlák adattáblát
kell használni.
2. A WHERE záradék végrehajtása most azt jelenti, hogy vesszük a FROM záradékból származó tábla (a számlák
adattábla) minden sorát.

3. A GROUP BY záradék alapján csoportosítjuk a rekordokat úgy, hogy minden csoporton belül a dátum nevű mező
értéke megegyezzen.
4. A HAVING záradék eredményeként a kapott csoportok közül elhagyjuk azokat, amelynél a fizetendő mező értéke
legalább egy rekordban kisebb a megadott értéknél.
5. A megmaradt csoportokra kiszámoljuk a fizetendő mezők összegét a csoportban levő rekordokra nézve, és a SE-
LECT záradéknak megfelelően a dátum mezőnek a csoportban érvényes értékéből és az összeg értékéből képezünk
egy két elemű sort.
6. Az így kapott sor(ok) lesz(nek) az utasítás eredménytáblájának sora(i).
A fenti utasítás persze nem meghatározott sorrendben adja meg az eredménysorokat. Ha azt szeretnénk, hogy a dátu-
mok növekvő sorrendben jelenjenek meg, akkor az eredménytábla sorait még dátum szerint rendezni is kell :
SELECT dátum, sum(fizetendő)
FROM számlák
GROUP BY dátum
HAVING min(fizetendő) >= 10000
ORDER BY dátum;
A fenti példán már látható a záradékok kötelező sorrendje : SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER
BY.
Arra is van lehetőség, hogy az összesítő függvény eredménye alapján végezzük a rendezést. Például szeretnénk a
legnagyobb bevételű napot látni legelöl, a legkisebb bevételűt leghátul. Ekkor csökkenő rendezést akarunk az összbevétel
alapján. Erre két megoldás van, az egyik a precíz megoldás, amikor elnevezzük az összebevétel oszlopát :
11 A SELECT utasítás végrehajtását ténylegesen az adatbáziskezelők nem feltétlenül az elméletileg előírt módon hajtják végre, hanem megpróbálják

a lehető legoptimálisabb megoldást megkeresni, hogy az elméleti végrehajtási móddal azonos eredményt a legrövidebb idő alatt tudják szolgáltatni.

258
SELECT dátum, sum(fizetendő) as összbevétel
FROM számlák
GROUP BY dátum
HAVING min(fizetendő) >= 10000
ORDER BY összbevétel DESC ;
Azonban arra is van lehetőség, hogy az összebevétel alapján közvetlenül végezzük a rendezést, azonban ezt a megoldást
nem minden SQL megvalósítás engedi meg:
SELECT dátum, sum(fizetendő)
FROM számlák
GROUP BY dátum
HAVING min(fizetendő) >= 10000
ORDER BY sum(fizetendő) DESC ;
Az első megoldás egyébként feltehetően gyorsabb, mert esetleg a másik megoldásnál kétszer történik meg az összbevétel
kiszámítása ! A második megoldás azonban rövidíthető úgy is, hogy a sorszámát adjuk meg a rendezési értéket tartalmazó
oszlopnak :
ORDER BY 2
Mivel az ORDER BY záradékban nem csak a SELECT záradékban szereplő kifejezések használhatóak, hanem min-
den olyan kifejezés, amely ott értelmes lenne, ezért lehetőség van a napi legagyobb bevétel alapján történő rendezésre
is:12

SELECT dátum, sum(fizetendő)


FROM számlák
GROUP BY dátum
HAVING min(fizetendő) >= 10000
ORDER BY max(fizetendő) DESC ;

12 Ezeket általában úgy lehet tekinteni, hogy ilyenkor az eredménytáblának az oszlopai közé az ORDER BY záradék kifejezései is felvételre kerülnek,

de nem kerülnek a végén megjelenítésre.

259
Negyedik rész

Dinamikus weboldalak készítése (PHP)

260
Ebben a részben ismét a weboldalak készítésével és a programozással együtt fogunk foglalkozni. Elsősorban olyan
oldalról közelítünk majd a dinamikus weboldalak készítéséhez, hogy milyen módon lehet egy adatbázist felhasználva
webes felületet használó információs rendszereket készíteni.
Ehhez szükség lesz az űrlapok készítésének ismeretére is (14.1 fejezet, 178. oldal), valamint az előző részben is-
mertetett PostgreSQL utasítások használatára. A példák kipróbálásához szükségünk van egy webszerverre, amely olyan
PHP-értelmezővel rendelkezik, amely képes csatlakozni egy PostgreSQL szerverhez, továbbá erre a PostgreSQL szerver-
re, megfelelő hozzáférési jogosultsággal.
Amennyiben nem PostgreSQL szerverrel, hanem MySQL szerverrel tudunk dolgozni, akkor a példákban szereplő
SQL utasítások egy része helyett más utasítást kell alkalmazni, és természetesen más függvényeket a kapcsolódáshoz.
Hasonlóan egyéb SQL-szerverekkel is képes a PHP együttműködni a megfelelő függvények segítségével, a PostgreSQL
csupán egy jól használható példa ezekre.
Először a PHP nyelv alapjaival ismerkedünk majd meg. Ebben sok visszautalás lesz a JavaScript nyelvre, amely
ugyanúgy a C/C++ nyelvcsaládra épül, mint a PHP.13
Utána megnézzük, hogyan lehet az űrlapból érkező adatokat feldolgozni PHP-ben. Itt néhány olyan trükkel is meg-
ismerkedünk, amelyek JavaScript segítségével teszik könnyebben feldolgozhatóvá bizonyos fajta űrlapok feldolgozását
(előfeldolgozás elküldés előtt).
Végül az adatbázis-kezelés során alkalmazott példát használva bemutatjuk, hogyan lehet a PHP-ben adatbázis-kezelést
megvalósítani. Példaként elkészítjük majd a bolti készlet-nyilvántartást végző információs rendszer egyes részeit megva-
lósító PHP-scripteket.
A PHP nyelv teljes ismertetése több nyelven letölthető az internetről (lásd [7]), itt csupán a számunkra fontos függvé-
nyek fognak szerepelni.

13 Ezen nem kell csodálkozni, hiszen akik ezeket a nyelveket megalkották, és a megfelelő programokat elkészítették, amellyel ezek használhatóak,

azok a C/C++ nyelvet használták.

261
20. fejezet

A PHP nyelv

A PHP egy szerver oldali script-nyelv, amelyet a webszerver értelmez és hajt végre. A PHP utasítások eredményeként
létrejövő kimenetet elhelyezi a PHP-script helyén az éppen feldolgozott HTML-kódban. Végül az így előállított kódot
küldi el a böngészőnek, amely a PHP-scriptet tartalmazó weboldalt lekérte.
Ennek eredményeként a böngészőhöz már egy tiszta HTML-kód kerül, amelyen semmi nem látszik abból, hogy volt
benne PHP-script is. Természetesen a HTML-kódban lehet JavaScript is, amelyet szintén előállíthat a webszerver PHP-
értelmezője.
A PHP használatával előállított weboldalakat éppen azért hívjuk dinamikus weboldalaknak, mivel abban a formá-
ban, ahogy a böngészők megkapják azokat, sehol nem léteznek. Helyettük egy több-kevesebb PHP-scriptet tartalmazó
állomány található a webszerver dokumentum-könyvtárában, amelyet a webszerver PHP-értelmezője feldolgoz, és a fel-
dolgozás kimeneteként előállítja a ténylegesen a böngészőhöz érkező kódot. Így tehát az dinamikusan jön létre az oldal
minden egyes lekérésekor.
Hogy ez miért jó? Azért, mert akár a szerveren levő információk módosíthatják a PHP-script eredményeként létrejövő
weboldal tartalmát, akár a böngészőtől a lekérés paraméterei között érkező információk. Például a böngésző a kéréssel
elküldheti egy űrlap tartalmát, amelyet a PHP-script feldolgoz, és az űrlap adatai alapján más és más HTML-kódot állít
elő.
Persze a PHP nem csupán HTML-kód előállítására alkalmas. Lehet vele PNG, JPEG vagy GIFF képeket is előállíta-
ni/manipulálni : egy adott képre valamilyen szöveget helyezni például, vagy térinformatikai adatbázissal együtt, akár egy
épület tervrajzát képként előállítani a megfelelő adatbázisbeli adatok felhasználásával.
Ugyancsak alkalmas a PHP PDF dokumentumok vagy akár Flash készítésére is. Mindezt szintén dinamikusan, a
letöltés pillanatában előállítva.
Az egyik legjobb és legfontosabb tulajdonsága a nyelvnek az adatbázisok széles körű támogatása. Adatbázisokat
kezelő weblap készítése PHP segítségével hihetetlenül egyszerű. Többek között a következő adatbázisokat támogatja :
• Adabas
• dBase
• IBM DB2
• Informix
• mSQL
• Direct MS-SQL
• MySQL

262
• ODBC
• Oracle ( !)
• PostrgreSQL

• Sybase
A fenti lista csupán szemezgetés. A Linux alatt is használható két nyílt kódú SQL szerveren, a MySQL és Postg-
reSQL rendszereken felül két adatbázis-kezelőre kell odefigyelni. Az egyik a Direct MS-SQL. Ez nagy valószínűséggel a
MS-Access-ben használható – nem szabványos – SQL nyelvvel azonost használ, de feltehetően több felhasználós hozzá-
féréssel (ami az Accessre ugyebár nem igaz). A másik pedig a világ talán legprofibb – és legdrágább – adatbázis-szervere,
az Oracle. Ez bizonyítja a PHP hatékonyságát: még az Oracle adatbázisokhoz is lehet vele webes felületű szoftvereket
készíteni !
A PHP rendelkezik egy DBX adatbázis absztrakciós kiterjesztéssel is, amellyel egyöntetűen és áttetsző módon lehet
kezelni bármilyen adatbázist, amit ez a kiterjesztés támogat. Ezen kívül a PHP támogatja az ODBC-t, ezért bármilyen
más, ezt a szabványt támogató adatbázishoz is lehet kapcsolódni.
A PHP a fentieken kívül még sok más hasznos célra is használható, mivel más programozási nyelveken íródott pro-
gramokkal is képes adatcserét folytatni. Ezenfelül nagyon sok hálózati protokollhoz rendelkezik függvényekkel, így akár
webes felületű levelezőrendszert is lehet vele készíteni (lásd freemail, hotmail stb.).

20.1. A PHP szintaxisa


20.1.1. A PHP scriptet jelölő szimbólumok
A PHP értelmező, amely a scriptet is tartalmazó – általában .php kiterjesztésű – állományt feldolgozza, tulajdonképpen
mást nem csinál, mint mindent változatlanul továbbad a webszervernek, mindaddig, amíg nem találkozik egy speciális
szimbólummal, amely jelzi egy script kezdetét. Ha ilyen scripthez ér, akkor azt feldolgozza.
Ez a bizonyos speciális szimbólumpár, amely a scriptként kezelendő részt körbeveszi : <?php . . . ?>. Az ezek közé
írt szöveget az értelmező tehát PHP-scriptként feldolgozza.
Lehetőség van a PHP-script és a HTML-kód keverésére is, például a következőképpen :

<?php
if ($változó<0) {
?>
<strong>A változó negatív</strong>
<?php
} else {
?>
<strong>A változó nem negatív</strong>
<?php
}
?>

Amennyiben a változó értéke negatív, akkor a „változó negatív” szöveget megjelenítő HTML-kód kerül a weboldalba,
ellenkező esetben a másik STRONG elem.

20.1.2. A PHP és a JavaScript szintaxisának összehasonlítása


Ahelyett, hogy a PHP teljes szintaxisát ismertetnénk, vegyük inkább sorra a JavaScript-hez képesti eltéréseket, illetve az
azzal való hasonlóságot.

263
Először is az utasítások elválasztására a PHP-ban sokkal inkább kötelező a pontosvessző. Minden utasítást pontos-
vesszővel kell lezárni – a C nyelvhez hasonlóan –, kivéve a script lezáró szimbóluma előtti utasítást, amely feltételezi az
utasítás végét.
A megjegyzésekhez ugyanúgy használható a C/C++ stílusú megjegyzés (a /* . . . */ többsoros megjegyzésre, és a
// egysoros megjegyzésre), valamint ezeken felül a UNIX környezetben elterjedt # után a sor végéig tartó megjegyzések
is.
Fontos különbség a változók megadása. A JavaScripthez hasonlóan itt is betűvel vagy aláhúzásjellel kezdődhet az
azonosító, majd folytatódhat betűvel, aláhúzásjellel és számjeggyel. Azonban a JavaScripttel ellentétben a PHP változói
a UNIX parancsértelmezőkben használthoz hasonlóan minden esetben egy $-jellel kezdődnek, amelyet követ a változó
azonosítója.1 Az azonosító képzési szabályában is van azonban még egy kis különbség : a JavaScript csak az angol ábécé
betűit tekinti betűnek, míg a PHP-ben betűként a magyar ábécé betűit is használhatjuk. Így nem kell a JavaScripthez
hasonlóan szulinap-ot írnunk, hanem írhatjuk így : $szülinap.

Adattípusok Az adattípusokat mindkét nyelvben használhatjuk anélkül, hogy előre megadnánk őket. A PHP azonban
nem ismeri a var utasítást. Itt nem kell előre deklarálni a használandó változókat : amikor először hivatkozunk rá, akkor
létrejön, amikor új típusú értéket kap, akkor automatikusan megváltozik a típusa.
A négy alaptípus ezúttal is a logikai, egész, lebegőpontos, és a szöveges. A logikai típus lehetséges értékei a true
(igaz) és a false hamis. Amennyiben valahol logikai típusú értékre van szükség, akkor a JavaScript-hez hasonlóan a
nulla automatikusan hamis, minden más érték automatikusan igaz értékké alakul. A speciális null érték szintén hamis
jelentéssel bírhat ilyen esetekben. Karaktersorozatból akkor lesz hamis, ha üres, vagy a "0" karaktersorozat, minden más
esetben igaz lesz belőle. Tömbből hamis érték lesz, ha nincsenek elemei.
A karaktersorozatok megadásánál van néhány eltérés a JavaScript karaktersorozataihoz képest.2 A legnagyobb kü-
lönbség az egyszeres és kétszeres idézőjelek használatában van. Mindkettő használható, de nem teljesen azonos a visel-
kedésük. Egyszeres idézőjelek alkalmazásakor ami azok közé kerül, az pontosan úgy lesz a karaktersorozat tartalma. Ha
egyszeres idézőjelet akarunk használni, akkor az elé egy fordított perjelet (\) kell tenni. Ha a karaktersorozatban a \’
sorozatot akarjuk szerepeltetni, akkor a fordított perjelet meg kell duplázni.
Dupla idézőjel alkalmazása esetén a karaktersorozatba írt szöveg egy részét a PHP értelmező fel fogja dolgozni, és a
feldolgozás eredményét illeszti a szövegbe. Ezek egy része a fordított perjellel kezdődik :
• \n: újsor jel.
• \r: kocsivissza jel.
• \t: vízszintes tabulátor jel.

• \\: fordított perjel.


• \$: a dollárjel.
• \": a dupla idézőjel.
• \ után egy nyolcas számrendszerbeli szám: a megadott kódú karaktert jelenti.

• \x után egy tizenhatos számrendszerbeli szám : a megadott kódú karaktert jelenti.


A másik előnye a dupla idézőjelnek, hogy a változók behelyettesítésre kerülnek. Amennyiben egy dollárjelet talál
fordított perjel nélkül az értelmező, akkor az utána levő, azonosítóba írható karaktereket a változó azonosítójának tekint-
ve megpróbálja azt változóként kezelni, és a szövegbe a változó értékét elhelyezni. Amennyiben így nem a megfelelő
változónevet kapnánk, akkor megtehetjük, hogy a dollárjel után kapcsos zárójelek közé írjuk a változó azonosítóját :
1 Elsőre
talán szokatlan ez a megadási mód, de sokkal jobban olvashatóvá teszi a kódot azáltal, hogy a változókat jobban kiemeli.
2A PHP-ben akármilyen hosszú karaktersorozat megadható, amit bizonyos alkalmazásokban ki is kell használni.

264
"Ez egy ${változó}név" a változó nevű változó értékét, majd közvetlenül utána a „név” szöveget írja a szöveg-
be. Ugyanilyen módon tömbindexet is meg lehet adni a változó neve után. Azonban nem egyértelmű a behelyettesítés, ha
a tömbindex megadása változóval történik!
Harmadik szövegmegadási mód a <<< után egy azonosító megadása, majd az akár több sort is kitöltő szöveg, ami
után egy üres sorban az azonosítót kell megismételni, amely lezárja a szöveget. Ez a megadási mód a többsoros szövegek
megadására ideális. Ebben is behelyettesítésre kerülnek a változók.
Amennyiben a dupla idézőjelen belül, vagy a harmadik megadási módnál a fentieknél összetettebb változót szeretnénk
használni, akkor azt úgy tehetjük meg, hogy az egész változómegadást kapcsos zárójelek közé írjuk.
Egy karaktersorozat értékeire nullától indexelt tömbként tudunk külön-külön is hivatkozni.
A JavaScript-ben a karaktersorozatok összefűzését a + operátor végezte. Ezzel szemben a PHP erre a célra a . operá-
tort használja.
A tömbök használatában is jelentős eltérések vannak. A JavaScript-tel ellentétben nem kell előre deklarálnunk, hogy
a változó tömböt fog tartalmazni. Bármely változóból egy nullától indexelt tömb lesz, ha valamelyik indexű eleme értéket
kap.
Azonban a PHP tömbjeiben nem csak számok lehetnek az indexek, hanem bármely más kulcs is betöltheti ezt a szere-
pet. Amennyiben az Array függvényt használjuk a tömb létrehozására, akkor úgy adhatjuk meg egyszerre a tömb elemeit,
hogy kulcsot is rendelünk hozzá. Természetesen a nem számmal jelölt indexű elem is megadható egyszerű értékadással.
A tömb egyik megadási módja tehát, ha az Array függvény zárójelei között felsoroljuk a tömb elemeit. Amennyiben
csak a tömbelemek értékeit soroljuk fel, akkor azok nullától kezdve folyamatos számozásúak lesznek. Amennyiben meg
akarunk adni egy elemnek konkrét kulcsot (bármilyen konstans érték lehet), akkor azt a => szimbólum, majd az elem
értéke követi. Ha a kulcs számérték lehet, akkor a következő elem – ha ott nem szerepel kulcs – az egyel nagyobb egész
szám lesz. Ellenkező esetben nullától kezdve a következő még nem használt egész szám lesz. Íme egy példa :

$tömb = Array(
’nulladik’,
-2 => ’korábbi’,
’ez is negatív indexű’,
’szöveges’ => ’indexű’
);

Ennek eredményeként a következő tömb jön létre :


Index tömbelem értéke
-2 ’korábbi’
-1 ’ez is negatív indexű’
0 ’nulladik’
’szöveges’ ’indexű’
Megadható azonban tömb az elemei megadásával is : Amennyiben a változó neve után szögletes zárójelben megadunk
egy indexet – akár számot, akár szöveges kulcsot –, amely még nem szerepel a tömbben (lehet, hogy még a tömb sem
létezik), és egy értékadással az így megadott tömbelemnek valamilyen értéket adunk, akkor a megadott kulcs-érték pár a
tömb elemévé válik. Ha nem adunk meg a szögletes zárójelen belül semmilyen értéket, akkor a legnagyobb egész indexnél
egyel nagyobb indexet kapja az új tömbelem. Amennyiben a tömbnek még nincs egész indexű tömbje, akkor az új elem
indexe nulla lesz.
Amikor hivatkozni akarunk egy tömbelemre, akkor is szögletes zárójeleket használunk, benne megadva a használandó
tömbelem indexét. Így tehát ha egy olyan tömbelemre hivatkozunk, amely még nem létezik, akkor az a tömbelem létrejön
a megadott értékkel.
Mivel egy tömb eleme bármilyen típus lehet, így elképzelhetőek egymásba ágyazott tömbök is, ami lehetővé teszi a
tömb adattípus használatát nagyon sokfajta adatszerkezet (többdimenziós tömbök, fák, halmazok stb.) megvalósítására.
Ez egy nagyon nagy erőssége a PHP-nek akár a JavaScripttel, akár a C/C++ nyelvvel szemben is.
Amennyiben egy tömbelemet meg szeretnénk szüntetni, akkor arra az unset függvényt kell használnunk. Ezzel a

265
függvénnyel bármilyen változót meg lehet szüntetni.3 A megszüntetendő változót kell a paraméterében megadni. Ha több
változót is felsorolunk vesszővel elválasztva, akkor azok mindegyike megszűnik. Egy tömbelem megszüntetése a tömbe-
lemre való hivatkozás megadásával történik, például a $tömb 3-as indexű elemét szüneteti meg az unset($tömb[3])
utasítás. Ezután, ha volt 4-es indexű eleme a tömbnek, az továbbra is 4-es indexű lesz, tehát a tömbelemek nem lesznek
újraindexelve !

Változók
A változók használatában jelentős különbség van a PHP és a többi C-stílusú nyelv között, így egyszerűbb a PHP-nyelv
változóit részletesen ismertetni.
Először is a változók minden esetben egy dollárjellel kezdődnek, akár a UNIX parancsértelmezők parancsaiban. Ez
után a dollárjel után következik egy azonosító a megszokott szabályokkal : betű után jöhet betű és szám, ahol a betű
lehet aláhúzás jel, vagy latin betű – beleértve a magyar ékezetes betűket is. Az azonosítókban a kis- és a nagybetűk
különbözőnek számítanak.
Alaphelyzetben a változó az értékadás során egy kifejezés értékét kapja eredményül. Azonban létezik egy speciális
összekapcsolási mód, amikor két változó azonossá tehető. Ezt referencia-értékadásnak hívjuk, és a & jelet használjuk
hozzá :
$alma = 10;
$gyümölcs = &$alma;
$alma = ’gyümölcs’;
echo $gyümölcs;
A fenti utasítássorozat eredményeként a „gyümölcs” érték fog kiíródni, bár látszólag csak az $alma változó értékét
változtattuk meg. Azonban a megváltoztatás előtt összekapcsoltuk a két változót. Ez úgy is elképzelhető, hogy ugyanan-
nak a változónak egy új álnevet adtunk. Tulajdonképpen olyan ez, mint az ext2 állományrendszereknél alkalmazható ln
paranccsal létrehozott állományreferenciák. . .

Előre definiált változók A PHP több előre definiált változóval rendelkezik, amelyek egy része nagyon hasznos lehet
a webszerverrel illetve a kliens oldali böngészővel való kapcsolattartásra. Most csupán egy rövid – és nem teljes – lista
következik. A részletes ismertetése némelyiknek majd a későbbiekben fog szerepelni, például az űrlapok feldolgozásánál.

• $GATEWAY_INTERFACE: A szerver CGI verziója (Apache szerver esetén).


• $SERVER_NAME: a webszerver publikus neve (pl. www.valami.hu).
• $SERVER_SOFTWARE: A webszerver azonosítóneve.
• $REQUEST_METHOD: Az oldal eléréséhez a HTTP-protokolban használt lekérdezési mód. Értéke lehet : ’GET’,
’HEAD’, ’POST’, ’PUT’.

• $DOCUMENT_ROOT: A webszerver dokumentumkönyvtárának abszulút elérési útvonala a webszervert futtató gép


könyvtárszerkezetében.
• $HTTP_REFERER: Annak az oldalnak a címe, ahonnan erre az oldalra érkezett a felhasználó.
• $HTTP_USER_AGENT: Az oldalt lekérő böngésző adatai.

• $REMOTE_ADDR: Az oldalt lekérő böngészőt futtató gép IP-címe (proxy-t használó hálózaton a proxy IP-címét
kapjuk).
3 A változó létrehozása nagyon egyszerű: hivatkozzunk rá, és létrejön. Ugyanakkor időnként szükség lehet egy már létező változó megszüntetésére,

nem csupán az általa használt memória felszabadítása céljából.

266
• $REMOTE_PORT: Az oldalt lekérő böngészőt futtató gépen a kapcsolathoz használt port száma.
• $SCRIPT_FILENAME: Az oldalt tartalmazó állomány abszolút elérési útja a gép állományrendszerében.
• $SERVER_PORT: A webszerveren a HTTP kiszolgálóhoz rendelt port száma, legtöbbször 80, de lehet más is.

• $SCRIPT_NAME: Az oldal útvonala úgy, ahogyan az internetről látszik, a webszerver neve után (tehát a $DOCUMENT_ROOT-
hoz relatív útvonal).
• $argv: A PHP-scriptnek átadott paramétereket tartalmazó tömb. Ha GET metódussal küldünk el a scriptnek egy
űrlapot, akkor az URL-ben a kérdőjel után megjelenő szöveget fogja ez a változó tartalmazni.

• $PHP_SELF: A PHP-scriptnek a webszerver dokumentumkönyvtárához relatív címét adja, akár a $SCRIPT_NAME.


• $HTTP_COOKIE_VARS: A sütiket tartalmazó asszociatív tömb.
• $_COOKIE: A sütiket tartalmazó asszociatív tömb. Inkább ezt célszerű használni az előző helyett.
• $_GET: Amennyiben egy űrlapot GET metódussal kap a script, ez a változó asszociatív tömbként tartalmazza
annak elemeit (lásd 21. fejezet).
• $_POST: Amennyiben egy űrlapot POST metódussal kap a script, ez a változó asszociatív tömbként tartalmazza
annak elemeit (lásd 21. fejezet).
• $_FILES: A POST metódussal feltöltött állományokról tartalmaz asszociatív tömként információkat.

Változók hatásköre Azt nevezzük egy változó hatáskörének, hogy a változóhoz hol lehet hozzáférni, hol létezik. Ala-
pesetben egy változó ott válik elérhetővé, ahol először hivatkozunk rá. Az azt követő programkódban, magában a script
kódjában, és az include vagy require utasítással beszúrt kódban lehet a változó értékét felhasználni.
Kivétel ez alól minden függvény, mivel a fent említett módon létrehozott változók a függvényen belül nem láthatóak.
Ha a függvényen belül hivatkozunk egy változóra, az egy helyi (lokális) változót fog létrehozni. Ez a szabály ellentétben
áll mind a JavaScript, mind a C nyelv szabályával, ahol a globális változók mindaddig elérhetőek a függvények belsejében
is, amíg egy azonos nevű helyi változóval el nem fedjük. A PHP-ben ezzel ellentétben azokat a globális változókat,
amelyeket a függvényen belül is szeretnénk elérni, külön meg kell adni.
Erre a globális deklarálásra a global utasítást kell használni. Ebben az utasításban a kulcsszó után fel kell sorolni
azokat a függvényen kívül létrehozott változókat, amelyeket a függvényben is láthatóvá akarunk tenni. Íme egy példa :

$a = 1;
$b = 2;

function Osszead()
{
global $a, $b;

$b = $a + $b;
}

Ossszead();
echo $b;

A fenti kód hatására a 3 érték jelenik meg, mert a globális változókkal tud dolgozni a függvény. Amennyiben a
global $a, $b; sor hiányozna, akkor a kiírt érték 2 lenne, mivel a függvényben levő változók a külső változóktól
függetlenek lennének.

267
A C/C++ nyelvben létezik egy static kulcsszó, amelynek megadásával olyan lokális változót lehet létrehozni,
amely a függvény két meghívása között is megőrzi az értékét, amit a következő függvényhívás kihasználhat. A PHP
lokális változóit is definiálhatjuk ilyen statikus változóként. A következő példában ha elhagynánk a static kulcsszót,
akkor a függvény teljesen értelmetlen lenne – mindig nullát írna ki –, a static kulcsszóval viszont már számolja,
hányszor kerül meghívásra.

function Test()
{
static $a = 0;
echo $a;
$a++;
}

Közvetett hivatkozású változók Lehetőség van arra is, hogy változó nevét ne közvetlenül, hanem egy másik változó
segítségével adjuk meg. Ez a lehetőség már nagyon összetett programozási gyakorlatot tesz megvalósíthatóvá. Gyakorla-
tilag egyfajta magát módosító programkódnak is tekinthető a használata.
Ha a dollárjel után egy változóhivatkozás áll a saját dollárjelével együtt, akkor a változóhivatkozás által megadott
érték, mint változónév kerül felhasználásra a ténylegesen használandó változó meghatározására. Például, ha az $a változó
értéke „világ”, és kiadjuk a következő utasítást
$$a = ’helló’;
a $világ változó kapja a „helló” értéket. Megváltoztatva a $a változó értékét, más változó válik így elérhetővé. Ha
nem egyértelmű – például egy tömbelemre való hivatkozásnál – hogy mit kell behelyettesíteni, használjuk a belső válto-
zóhivatkozás meghatározására a kapcsos zárójeleket : ${$a[1]} és ${$a}[1] esetén az első változat a $a tömb első
elemében levő nevű változót adja, a második változat a $a változóban levő nevű változó, mint tömb első elemét jelenti.

Konstansok használata
Lehetőséget nyújt a PHP arra is, hogy bizonyos neveket használva egyes értékeket állandóként (konstansként) elnevez-
zünk. Ez arra jó, hogy később a kód módosítása könnyebb legyen. Például ha egy érték sokszor szerepel, és előfordulhat,
hogy később módosítani akarjuk majd, akkor sok kellemetlenségtől kímélhetjük meg magunkat, ha az értékhez defini-
álunk egy konstanst, és ezután mindenhol ezt használjuk. Ekkor ha az értéket meg kell változtatni, akkor összesen egy
helyen kell ezt megtenni, és később mindenhol azt használhatjuk.
A konstans definiálása a define utasítással történik. Miután egy állandót létrehoztunk, az mindenhol látható és
felhasználható. A define utasítás a következőképpen néz ki : A zárójelen belül megadjuk a konstans azonosítóját idé-
zőjelek között (a már ismert szabályok vonatkoznak rá), majd egy vessző után a leendő értékét.4 A konstans értéke csak
alaptípus lehet, tömb, vagy objektum nem. Egy változónak és egy konstansnak lehet azonos a neve, mégis különböző
objektumok lesznek. A konstansra való hivatkozáskor nem használunk dollárjelet.
Ha már definiáltunk egy konstanst, akkor azt nem lehet újabb definiálással sem megváltoztatni. Éppen ezért hasznos
lehet tudni, hogy definiált-e már egy konstans. Erre használható a logikai értéket visszaadó defined függvény, amely a
paraméterében megadott konstans definiáltságát mondja meg.

Kifejezések
A kifejezések gyakorlatilag ugyanúgy működnek, mint a C/C++ vagy a JavaScript kifejezései. Nagyjából a használható
műveletek is azonosak. A legfontosabb különbség, hogy a PHP-ben a karaktersorozatok összekapcsolását a . operátor
végzi. Amennyiben egy változóhoz szeretnénk hozzáfűzni valamit, akkor a .= értékadó operátort használhatjuk.
További speciális kifejezés a végrehajtó operátor használata. Ez valójában egy fordított idézőjelpár belsejébe írt pa-
rancs, amit a PHP értelmező a saját felhasználói azonosítójával a dokumentum gyökérkönyvtárából indulva hajt végre. A
4 Általánosan elterjedt, de megszeghető szabály, hogy a konstansokat csupa nagybetűvel írjuk.

268
parancs végrehajtására kapott kimenet lesz a kifejezés értéke, amelyet egy változóban szövegként tárolni is lehet. Íme egy
példa, amely a PHP-script számára aktuális könyvtár tartalmát írógép típusú betűkkel kilistázza a weboldalban :
$output = ‘ls -al‘;
echo "<pre>$output</pre>";
Tömbök összefűzésére használható a + operátor, amely az első tömbhöz hozzáfűzi a második tömb azon elemeit,
amelyek indexe nem szerepel az első tömbben (vagyis az azonos indexű elemek közül az első tömbbeli kerül a végső
tömbbe, egyébként a két tömb elemeinek uniója lesz az eredmény). Egyéb halmazműveletek a tömbökön függvények
segítségével megvalósíthatóak.

20.1.3. Vezérlési szerkezetek


Bár a vezérlési szerkezetek megvalósítása is nagyrészt megegyezik a JavaScript vezérlési szerkezeteivel, mégis kicsit
részletesebben célszerű ismertetni. Inkább a C/C++ nyelvvel érdemes az összehasonlítást végezni.

Elágazások
A PHP a C/C++ elágazásait ismeri, ezek szintaxisa a JavaScript-ben megismerttel gyakolatilag azonos.

Feltételes utasítás A feltételes utasítás az if kulcsszóval, és utána zárójelek között egy logikai típust adó kifejezéssel
kezdődik. Bármilyen típusú kifejezést írunk is ide, az logikai értékké konvertálódik, azaz nulla vagy null érték esetén
hamis, minden egyéb esetben igaz lesz.
Ezután egy utasítás, vagy kapcsos zárójelek között több utasítás következik, amely(ek)et akkor kell végrehajtani, ha a
kifejezés igaz volt.
Ezt a részt követheti egy else kulcsszó, majd egy utasításblokk a kifejezés hamis értéke esetére, vagy a else után
következhet egy teljes feltételes utasítás, amely akkor kerül végrehajtásra, ha a kifejezés hamis volt. Ez utóbbi esetben az
else if helyett írható elseif is.

Esetszétválasztás Az esetszétválasztást ezúttal is a switch kulcsszóval kezdődő utasítás valósítja meg.


A switch kulcsszó után zárójelben szerepel egy kifejezés, amelynek értéke alapján történik az esetek szétválasztása
a kapcsos zárójelen belüli részben, amely ezután következik.
A kapcsos zárójelben case érték: alakú címkék következnek. Minden ilyen címke a kifejezés egy értékét jelenti. A
megadott érték esetén az ez után az első break utasításig terjedő utasításokat hajtja végre a PHP értelmező.
Ez azt is jelenti, hogy több értéket is meg lehet adni egy-egy case után ugyanahhoz az esethez, kihasználva, hogy az
egyes értékekhez tartozó kódról a végrehajtás másik esetre átfuttatható.
Az utasítás működése nagyon hasonló egy feltételes utasításhoz, amelyben else if . . . else if. . . sorozatok vannak. A
következő feltételes utasítás és switch utasítás ugyanazt eredményezi :
if ($i == 0) {
print "i most 0";
}
if ($i == 1) {
print "i most 1";
}
if ($i == 2) {
print "i most 2";
}

switch ($i) {
case 0:

269
print "i most 0";
break;
case 1:
print "i most 1";
break;
case 2:
print "i most 2";
break;
}
Íme egy példa arra, hogy az egyik esetből a másik esetbe tovább lehet engedni a végrehajtást :
switch ($i) {
case 0:
print "i most 0";
case 1:
print "i most 1";
case 2:
print "i most 2";
}
Ez persze inkább a továbbfutás veszélyére példa, hiszen ha $i értéke nulla, akkor mindhárom szöveg megjelenik. Azon-
ban a továbbfutást néha ki is lehet használni, ami a feltételes utasítások összekapcsolásánál hatékonyabb kódot is lehetővé
tesz.
További előny a feltételes utasításokkal szemben, hogy itt a kifejezés csak egyszer kerül kiértékelésre, míg a feltételes
utasításnál minden alkalommal. Ez a mellékhatással rendelkező kifejezéseknél lényeges különbség, de a kiértékelés is
gépidőt igényel, így az esetszétválasztás gyorsabb is, ami főképp egy cikluson belül lehet jelentős.5
Van egy speciális eset, amelyet a default: címke jelez : minden olyan esetet jelent, amelyet egyetlen más, addig
szerepelt címke sem jelent. Mivel a címkéket a PHP értelmező a megadásuk sorrendjében nézi végig, a default:
címkének a legutolsóként kell szerepelnie, különben az utána levő címkék helyett is ez lesz használva ! Tulajdonképpen a
feltételes utasítások sorozatának végső else ágának felel meg.

Ciklusok
A ciklusok nagyjából megfelelnek a C/C++ ciklusainak.

Előltesztelő ciklus Az előltesztelő ciklus szerkezete talán a legegyszerűbb (és a legolvashatóbb is) : kezdődik egy
while kulcsszóval, ezt kerek zárójelek között – mint minden utasításban a logikai feltételnél – egy logikai kifejezés
következik, majd jön egy utasítás, vagy kapcsos zárójelek között utasítások sorozata, melyek mindaddig újra és újra vég-
rehajtásra kerülnek, amíg a logikai kifejezés értéke igaz (nem logikai kifejezés esetén nullától különböző egész értékké
konvertálható értékű).

Hátultesztelő ciklus A hátultesztelő ciklus szerkezete egy kicsit összetettebb, mivel itt a feltétel vizsgálatát a ciklusmag
végrehajtása után kell elvégezni. Ezért először a do kulcsszó után kapcsos zárójelek között a ciklusmag utasítása(i)
következnek, majd ezt követi a while kulcsszó után – szokás szerint – kerek zárójelben a feltétel, amelynek teljesülése
esetén a ciklusmagot újra végre kell hajtani. Tehát itt is addig hajtjuk végre a ciklusmagot, amíg a feltétel igaz, de itt
egyszer mindenképpen végrehajtjuk.
5 Látszólag nem nagy ügy a lassabb végrehajtás, azonban gondoljunk arra, hogy amit a PHP előállít, az egy weboldal, amit egy távoli gépre el kell

küldeni. Minél lassabb a PHP végrehajtása, annál többet kell várni a kliens gépén az eredményre. Vannak türelmetlen felhasználók, akik ha sokáig
kell várni az eredményre, akkor inkább megszakítják a letöltést. Gondoljuk el ennek a veszélyeit egy adatbázist módosító script esetén – ahol még az
adatbázis elérés is időbe kerül!

270
Számlált ciklus Szintén teljesen megfelel a C/C++-beli for ciklusnak. Vegyük a következő előltesztelő ciklust :
kif1;
while (kif2) {
utasítás;
kif3;
}
Ennek megfelel a következő for ciklus:
for (kif1; kif2; kif3) utasítás
Tehát az utasítás felépítése a következő: a for kulcsszó után kerek zárójelben három kifejezés, majd a ciklusmag
utasítása, illetve kapcsos zárójelek között utasításai.
A három kifejezés szerepe sorban a következő :
1. Induló értékadás(ok) megadása. Itt olyan értékadó kifejezést (esetleg vesszővel elválasztva több ilyet) kell megadni,
amely a ciklusváltozó(k) értékét a kezdőértékre állítja.
2. Kilépési feltétel. Itt lehet ellenőrizni, hogy a ciklusváltozó értéke elérte-e már a végértéket. A fenti két programkód
összehasonlításából következik, hogy addig ismétlődik a ciklusmag végrehajtása, amíg ez a kifejezés igaz értéket
eredményez. Természetesen lehet ciklusváltozótól független feltétel is, amely esetben a gyakorlatban nem számlált
ciklust valósít meg. . .
3. Léptető kifejezés. Itt lehet megadni olyan kifejezéseket, amelyeket a ciklusmag minden végrehajtása után a kilépési
feltétel kiértékelése előtt ki kell értékelni. A többes szám oka ismét az, hogy vesszővel elválasztva több kifejezés
is megadható, hiszen a kiértékelt érték nem kerül sehol felhasználásra. Általában a ciklusváltozó léptetésére hasz-
nálatos, de gyakorlott C-programozók kedvenc szokása, hogy amennyiben az egész ciklus egyetlen célja valamely
kifejezés sokszori végrehajtása, akkor azt is itt helyezik el, és a ciklusmagot üresen hagyják. Erre egy példa szere-
pelt a JavaScript-ről szóló fejezetben a for utasítás bemutatásánál a 12.2.5 szakaszban.

Tömb elemein végigfutó ciklus (csak PHP4-ben !) Ez a ciklusfajta nem szerepel a C-ben, sem a PHP régebbi, 3-as
verziójában. Valójában a for egy speciális esete, ahol nem létezik ilyen utasítás, ott azzal lehet megvalósítani.
Gyakorlatilag a tömb elemein sorra végig lehet vele menni, és a ciklusmag minden tömbelemre egyszer végrehajtódik.
Az egyik formája, amikor a tömbindexet nem használhatjuk így néz ki :
foreach (tömb_kifejezés as $érték) utasítás
A másik fajtája, amikor a tömbelem indexét is használhatjuk a ciklusmagban, így néz ki :
foreach (tömb_kifejezés as $kulcs => $érték) utasítás
Minden egyes alkalommal, amikor a ciklusmag valamely tömbelemre végrehajtódik, az $érték változó tartalmazza
a soronkövetkező tömbelem értékét, valamint a második változat esetében a $kulcs tartalmazza az ő kulcsát/indexét. A
tömb_kifejezés adja meg a tömböt, amelynek az elemeit végig kell nézni.
Minden tömbnek van egy belső mutatója, amelyet a reset függvény állítja az első elemre. Amennyiben a foreach
ciklust használjuk, az először hasonlóképpen az első elemre állítja a mutatót, majd egyenként végigmegy az elemeken,
ahogyan a list függvény is tenné.6 A következő kód ezt a belső mutatót a tömb első elemére állítja, majd a while ciklus
feltételében levő értékadással kiveszi a soron következő elemet. Az each függvény ezután továbblép a következő töm-
belemre. A feltételben azt a tulajdonságot használtuk ki, hogy az each hamis értéket ad eredményül, ha már nincs több
eleme a tömbnek.
6 A list valójában nem függvény, annál is inkább, mert ez értéket nem ad, hanem kap. Értékadás baloldalán szerepelhet, paramétereiben azokat

a változókat kell megadni, amelyek sorra értéket kapnak. A jobboldalon álló, tömb típusú kifejezés rendre egymást követő elemeiből. A következő
példában szereplő másik függvény, az each a paraméterében szereplő tömb belső mutatója által megadott tömbelem indexéből és értékéből képzett
kételemű tömböt adja eredményül, majd továbblépteti a mutatót a következő elemre.

271
reset ($tomb);
while (list(, $ertek) = each ($tomb)) {
echo "Érték: $ertek<br>\n";
}

Ugyanezt valósítja meg a foreach utasítás a következőképpen :

foreach ($tomb as $ertek) {


echo "Érték: $ertek<br>\n";
}

Hasonlóképpen a következő két kód is azonos eredményt ad : ezúttal látható az is, hogy a list „függvénnyel” és az each
függvénnyel hogyan lehet a tömbelem indexét/kulcsát is megkapni, és egyben magyarázatul szolgál az előző kódbeli üres
paraméter jelentésére is.

reset ($tomb);
while (list($kulcs, $ertek) = each ($tomb)) {
echo "Kulcs: $kulcs, Érték: $ertek<br>\n";
}

foreach ($tomb as $kulcs => $ertek) {


echo "Kulcs: $kulcs, Érték: $ertek<br>\n";
}

A continue utasítás : ciklus folytatása Egy ciklusmagon belül használható a continue utasítás a ciklus továbbléptetésé-
re. Ahol az utasítás szerepel, a ciklusmag végrehajtása befejeződik, és a ciklus feltétele kerül ismét megvizsgálásra, majd
ha kell, a ciklusmag újra végrehajtása kezdődik. Tehát ezzel az utasítással a ciklusmagon belül bárhol kezdeményezhető
a következő ciklusmag-végrehajtás elkezdése.
Az utasítást kétféleképpen lehet használni. Az egyszerűbb eset, amikor csak a continue kulcsszó szerepel. Ekkor
annak a ciklusnak a folytatását jelenti, amelynek a ciklusmagjában szerepel. Ha a kulcsszó után egy számérték is szerepel,
akkor annyi beágyazott ciklus magjának hátralevő részét ugorja át a végrehajtás.

Függvény befejezése A függvény végrehajtását a return utasítással lehet kezdeményezni. Amennyiben úgy ér el a
függvény végrehajtása az utolsó utasításig, hogy nem volt ilyen utasítás, az megfelel a return utasítás egyszerűbb alak-
jának, amikor egyetlen return kulcsszó szerepel : a függvény véget ér, értéket nem ad vissza, és a vezérlés a függvény
meghívását követő utasítással folytatódik.
Az utasítás másik változata, amikor egy kifejezés szerepel a return kulcsszó után. Ekkor a függvény végrehajtá-
sának befejezése után a függvény által az őt hívó kifejezésbe szolgáltatott érték a megadott kifejezés értéke lesz, és a
végrehajtás a hívó kifejezés további kiértékelésével folytatódik.
A return utasítás nem csak függvény befejezésére használható. Ha függvényen kívül szerepel, akkor megszakítja a futó
script végrehajtását. Ha egy include vagy require utasítás által beillesztett scriptben szerepel, akkor annak végrehajtását
fejezi be, és a hívó script végrehajtását a következő utasítással folytatja. Ebben az esetben az include illetve require
utasítás mint függvény visszatérési értékként szolgáltathatja a return értékét.

Külső kód beillesztése Lehetőség van a C/C++ nyelvben megszokotthoz hasonlóan külső állományban elhelyezett
programkód beillesztésére és lefuttatására. Ez nagyon hasznos tud lenni, amikor egy nagyobb szoftvert készítünk PHP-
ban, amelynek egyes részei más és más címen elérhető weboldalként léteznek. Ezek mindegyikébe a közös kódot ilyen
külső állományok betöltésével lehet beilleszteni.
Erre a célre összesen négy utasítás szolgál: a require, require_once, include és include_once utasítások. A négy
utasítás mindegyike beilleszti a paraméterében (zárójelek között, vagy egyszerűen a kulcsszó után) megadott szöveges

272
kifejezés által meghatározott nevű állományt. Az elérési útvonal a webszerver belső állományrendszerén belüli útvonallal
rendelkezik. Relatív útvonal esetén az induló könyvtár megegyezik a legelsőként meghívott script könyvtárával. Ezt a
viselkedést módosíthatja az include_path konstans beállítása.
A két _once végű utasítás csak abban az esetben illeszti be az állományt, ha a scriptbe azt még egy korábbi utasítás
nem illesztette be. Ez a függvények többszöri definícióját akadályozhatja meg.
A require kezdetű utasítások esetén az állománynak mindenképpen léteznie kell, különben a script végrehajtása
hibaüzenettel megszakad. Az include kezdetű utasítások csak figyelmeztetést adnak, ha az állomány nem létezik, majd
folytatódik a végrehajtás a következő utasítással.
Bármely utasítást használjuk is a beillesztésre, a beillesztett kódban az utasítás kiadásának helyén érvénes változó-
hatáskör marad érvényes. Ez egyben azt is jelenti, hogy a függvény belsejébe illesztett kód úgy fog viselkedni, mint a
magában a függvényben szereplő kód.
Arra figyelni kell, hogy minden beilleszett állomány elején az értelmező HTML módba kerül, majd az állomány végén
visszaáll PHP módba. Ez azt jelenti, hogy ha a beillesztett állományban PHP-kódot akarunk megadni, azt a határoló szim-
bólumokkal (<?php . . . ?>) közre kell fogni. Másrészt ez azt is jelenti, hogy a HTML-kódot akarunk beilleszteni, akkor
azt könnyedén megtehetjük. Például ha a fejléc részét a weboldalnak egységesen akarjuk létrehozni, azt egy egyszerű
HTML kódrészletet tartalmazó állomány beillesztésével könnyedén megtehetjük.
A get_required_files függvény értéke egy tömb, amely tartalmazza azoknak az állományoknak a nevét, amelyeket a
script végrehajtása során a require_once utasítás már egyszer beillesztett. Ugyanilyen tömböt ad az include_once utasí-
táshoz a get_included_files függvény.
A readfile függvény a megadott állományt egyszerűen a kimenetre másolja.

20.1.4. Függvények használata


A PHP függvényei a JavaScript függvényeihez hasonlóan működnek. A definiálás során teljesen hasonlóan kell eljárni, a
különbség mindössze abból adódik, hogy a PHP változó dollárjellel kezdődnek, így a paramétereket is ezzel kell kezdeni.
A PHP-ben a függvényen belül bármilyen PHP kód szerepelhet, így akár belső függvénydefiníció is. Ekkor értelem-
szerűen a belül definiált függvény csak az őt tartalmazó függvényen belül hívható meg.
A változók érvényességi köréről már a változóknál szót ejtettünk (20.1.2 szakasz).
A függvény paraméterei általában értéket adnak át. Ez azt jelenti, hogy a függvényhívásnál a megadott paramétert
mint kifejezést feldolgozza az értelmező, majd a kifejezés értékét a függvény paraméterét jelentő változóba másolja. Ezt
a változót használja azután a függvény. Ezt a fajta paraméterátadást hívjuk érték szerint paraméterátadásnak.
Íme egy példa az érték szerinti paraméterátadást használó függvényre :

function példa($első, $második) {


...
}
Az érték szerint átadott paraméterek értékét a függvényen belül szabadon megváltoztathatjuk anélkül, hogy annak
hatása lenne a függvényen kívüli értékre. Van azonban olyan eset, amikor azt szeretnénk, hogy annak a változónak az
értéke is megváltozzon, amelyet a híváskor megadtunk. Ezt a C/C++ nyelvben cím szerinti paraméterátadásnak nevezzik.
A PHP-beli megfelelője a referencia szerinti paraméterátadás. Ez azt jelenti, hogy valójában azt az információt adjuk meg
a függvénydefiníciónál és a hívásnál, hogy melyik változót kell használni a függvényben. Ezt úgy lehet megadni, hogy a
függvénydefinícióban a paraméter előtt egy & jelet is szerepeltetünk :
function fgv_extrakkal(&$string)
{
$string .= ’és a szükséges plusssz.’;
}
$str = ’Ez egy karakterfüzér, ’;
fgv_extrakkal($str);
echo $str; // kiírja, hogy ’Ez egy karakterfüzér, és a szükséges plusssz.’

273
A C++ ismerőinek nem újdonság, hogy lehetőség van arra is, hogy valamely paraméternek alapértelmezett értéket
adjunk meg.7 Amennyiben egy paraméterben egy egyenlőségjel után megadunk egy értéket a függvénydefinícióban, akkor
a függvény meghívásakor azt a paramétert el lehet hagyni. Ebben az esetben az egyenlőségjel után szereplő értéket
használja a függvény ennek a paraméternek az értékeként.
A paramétereket minden esetben a függvény végéről kezdve lehet elhagyni, mivel a függvényhíváskor balról kezdve
az első annyi paraméter kap értéket, amennyi a hívásnál szerepel. Így tehát nincs értelme olyan paramétert alapértelmezett
értékkel ellátni, amitől jobbra a paraméterlistán ilyennel nem rendelkező paraméter is fog szerepelni.

20.2. További információk a PHP nyelvről


A kesőbbi fejezetekben ugyan még lesz szó a PHP nyelv lehetőségeiről, azonban arra nincs mód, hogy minden lehetőséget,
amire a PHP képes, ismertessünk. Sőt az eddig leírtak sem voltak teljesek abban az értelemben, hogy a PHP szintaxisából
sem volt szó minden lehetséges nyelvi elemről. Ennek oka, hogy ez a könyv nem kíván a PHP teljes referencia kézikönyve
lenni, csupán a dinamikus weboldalak készítéséhez leginkább fontos ismereteket kívánja átadni.
A további fejezetekre még inkább jellemző lesz, hogy a leggyakrabban használt eszközöket fogják bemutatni. Termé-
szetesen később további fejezetekkel bővülhet még a könyv, de soha nem fogja a PHP teljes eszköztárát bemutatni.
Aki többet is szeretne tudni a PHP nyelvről, annak érdemes felkeresnie az interneten a nyelv hivatalos lelőhelyét.
Címe : http ://www.php.net/. Ezen a címen megtalálható a PHP értelmezők legfrissebb változata, valamint a legaktuálisabb,
teljes ismertető a nyelvről – természetesen angolul. A leírás – nem teljesen naprakész – magyar nyelvű változata is elérhető
a http ://weblabor.hu/ címen.8
A következő fejezetek arról szólnak, hogy hogyan lehet a gyakorlatban használni a PHP nyelvet olyan alkalmazások
készítésére, amelyek felhasználói felületként weboldalakat használnak. Ezek az alkalmazások általában egy adatbázis-
szervert is igényelnek, így a következő fejezetek egyike arról szól majd, hogy hogyan lehet a Linux alatt is elérhető, és
ezért leggyakrabban alkalmazott két adatbázis-szervert elérni a PHP scriptjeiből. Az adatbevitel és adatlekérdezés meg-
valósításához szükség van egy interaktivitást biztosító részére a HTML-nek, az űrlapokra. Éppen ezért mielőtt tovább
haladnánk, fel kell idézni – vagy most végre el kell olvasni a könyvnek az űrlapokról szóló, 14.1 fejezetét. Ezután lehet
rátérni a következő fejezetre, amely bemutatja, hogyan lehet az űrlapokból érkezett információt a PHP scriptben kinyerni
és feldolgozni. Ezt követően bemutatjuk, hogyan lehet a MySQL illetve a PostgreSQL szerverrel kapcsolatot teremteni.
Majd mindezeket az adatbáziskezelésről szóló részben bevezetett példát használva egy konkrét információs rendszer elké-
szítésével fogjuk szemléltetni (szokás szerint a PostgreSQL-t használva a példákban.) Ezt követi majd még egy-két olyan
fejezet, amely a PHP további hasznos szolgáltatásait is megmutatja, mint például azt, hogy hogyan lehet képeket készíteni
PHP-vel, ami akár egy egyszerűbb térinformatikai adatbázis használatát is lehetővé teszi, főleg a HTML képtérképeivel
kombinálva.

7A C nyelv nem ismerte az alapértelmezett paraméterérték fogalmát, csupán a C++ nyelvben lehet ilyet használni.
8 Amennyiben a szerző terveinek megfelelően sikerül összeállítani egy CD-t az informatika tantárgy oktatási segédanyagaiból, akkor azon ennek a
dokumentumnak PDF formátumú, legfrissebb változatával együtt a PHP angol és magyar nyelvű változata is megtalálható lesz. Azonban abból, hogy a
könyv jelen változatában ezen a helyen ez a lábjegyzet található, az is következik, hogy ilyen CD-összeállítás jelenleg még nem létezik. . .

274
21. fejezet

Űrlapok feldolgozása PHP-vel

Ebben a fejezetben a PHP egyik leggyakoribb felhasználási területével ismerkedünk meg, az űrlap adatainak feldolgozá-
sával. Ehhez először szükségünk lesz a HTML űrlapkészítő elemeinek ismeretére, amely a 14.1 fejezetben található. Ott
már volt róla szó, hogy a FORM elem method paraméterében kell megadni, hogy az űrlap adatait milyen módon kell
elküldeni a feldolgozó programnak, amely pedig a action paraméterrel határozandó meg.
A lehetséges elküldési módok a POST és a GET. A kettő között az alapvető különbség, hogy a GET esetében az URL-
hez egy kérdőjel után hozzáadódik az űrlap tartalma, míg a POST esetében a felhasználó nem látja ilyen módon, hogy mi
került elküldésre. Mindkét esetben azonban ugyanúgy a (mezőnév,érték) párokat kapja meg a feldolgozó erőforrás.
A GET metódus esetén az URL-hez hozzáfűzött tartalom felhasználható arra is, hogy az űrlapot szimuláljuk a hivat-
kozásba beírt értékekkel. Ilyen módon paraméteresen hívható scriptek is előállíthatóak, ami alkalmas lehet akár a később
ismertetendő feliratos képek generálására is. Másrészt mivel a PHP képes egyszerre mindkét metódussal kapott értékek
feldolgozására, így akár paraméterezett űrlapok is készíthetők : az action elemben megadjuk a paramétereket, mintha a
GET metódust használnánk, de az űrlapot POST metódussal küldjük el.

21.1. A GET metódus által generált URL szerkezete


A kérdőjel után a (mezőnév,érték) párok a következőképpen kerülnek bele az URL-be :
• Minden párt a többitől egy & jel választ el.
• Egy pár a mezőnévből, egy = jelből, majd a mező értékéből áll.
Többértékű mezők esetén a legtöbb böngésző csak az egyik – általában a legelső – értéket küldi el. Mindez megkerül-
hető azzal, hogy a mező neveként egy index nélküli tömbhivatkozást adunk meg, amely esetben a tömb elemei lesznek az
értékek. Később egy másik, JavaScript-et is igénylő megoldást is látni fogunk ennek kezelésére.
Íme egy példa GET metódussal elküldött űrlap esetén létrejövő URL-re :
http://valami.com/getform.php?nev=Manó%20Gábor&szulhely=Budapest&szulido=1999.12.30.
A fenti URL a következőket jelenti:

1. Az űrlapot a http://valami.com/getform.php néven található PHP script fogja feldolgozni.


2. Az űrlap három mezőjének értéke került elküldésre.
3. Az egyik mező neve nev volt, ennek értéke „Manó Gábor”. Mint látható, a böngésző a szóközt lecserélte egy
%20 karaktersorozatra, ahol a 20 a szóköz kódja tizenhatos számrendszerben. A böngészők egy része elvégzi ezt

275
a cserét, másik része azonban nem. Igazából a problémát az szokta jelenteni, hogy a webszerverek általában a
szóközt vagy ékezetes betűt tartalmazó weboldalakat visszautasítják, ezért ennek elkerülésére szokták a böngészők
kicserélni a kódjára ezeket a karaktereket. Azonban kérdőjel utáni részben a webszervereknek illik elfogadniuk
ezeket a karaktereket is.
4. A második mező neve szulhely, értéke „Budapest”.
5. A harmadik mező neve szulido, értéke „1999.12.30.”.
Megjegyzés. Bár a PHP azonosítóként elfogad ékezetes betű tartalmazó neveket is, mégis érdemes megfogadni a taná-
csot, miszerint űrlap mezőjének nevébe nem teszünk ékezetes betűt. Nem feltétlenül lehet ugyanis megbízni abban, hogy a
felhasználó által használt böngésző, illetve a PHP értelmezését végző webszerver ezeket a karaktereket megfelelően fogja
kezelni. Történetesen a Galeon elképzelhető, hogy Unicode kódolással küldi el ezeket a karaktereket, míg a webszerver
Latin-1 vagy Latin-2 kódolással várja azokat. Ebben az esetben az azonosítók nem fognak megegyezni.
Az űrlap minden mezőjének értéke szöveges adatként kerül elküldésre, a másként kezelendő adatokkal a feldolgozó
scriptnek kell törődnie.
Megjegyzés. Fontos: az űrlapban szereplő password típusú mezők tartalma minden titkosítás nélkül kerül elküldésre
akár GET, akár POST metódussal. A POST metódus esetén nem jelenik meg az elküldött érték az URL-ben, tehát bizton-
ságosabb. Ilyen szempontból nézve nem ajánlatos jelszavakat GET metódussal elküldeni.
Mindazonáltal a POST metódus sem jelent teljes biztonságot, mivel az adatforgalmat figyelő programok ezekhez az
információkhoz is hozzájuthatnak. Azonban a lekért URL-eket maga a webszerver is naplózni szokta, amely esetben a
GET metódussal elküldött jelszó a webszerveren tárolásra is kerül !

21.2. Az értékek elérése a PHP-scriptben


Akár a POST, akár a GET metódussal küldjük el az űrlap adatait, a hozzáférés hasonlóan történik a feldolgozásnál.
Mindkét esetben létrejön egy asszociatív tömb1 a metódust meghatározó néven. GET metódus esetén a tömb neve
_GET, POST metódus esetén _POST lesz.
Az asszociatív tömb minden egyes eleme egy-egy elküldött űrlap mező lesz. A mező neve lesz a tömbelem kulcsa,
a mező értéke pedig a tömbelem értéke. Ilyen módon tehát a fenti példában szereplő URL esetén a _GET tömbnek a
következő elemei lesznek:

• $_GET[’nev’]: ’Manó Gábor,


• $_GET[’szulhely’]: ’Budapest’,
• $_GET[’szulido’]: ’1999.12.30.’.

Hasonlóan érhetőek el egy űrlap elemei a POST metódus esetén a _POST tömb elemeiként.
Amennyiben egy olyan tömbelemre hivatkozunk, amely nem létezik, az üres karakterlánc lesz az érték, amely a
kifejezésben szerepel. Ez felhasználható arra, hogy ellenőrizzük valamely mező meglétét, vagy akár azt is, hogy a PHP
script az űrlap elküldése előtt került feldolgozásra, vagy az után : ha még nincs a tömböknek eleme, akkor nem kapott a
script űrlapot.
Kapcsolók esetén a mező és értéke csak akkor kerül elküldésre, ha a kapcsoló be van kapcsolva. Ilyenkor tehát a
kapcsolót reprezentáló tömbelemnek két értéke lehet :
1. A kapcsolót létrehozó INPUT elem value paraméterének értéke, vagy
2. az üres karaktersorozat (’’ vagy "").
1 Asszociatív tömbnek a PHP-ben azokat a tömböket nevezik, amelyben az elemek nem egész számokból álló indexekkel, hanem nevesített kulcsok-

kal érhetőek el.

276
Bármelyik használatával a kapcsoló állapota megvizsgálható. Például a következő űrlaprészlet POST metódussal
elküldése esetét vegyük:
<input type="checkbox" name="kapcsol" value="on">
Ebben az esetben, ha a kapcsoló bekapcsolt helyzetét akarjuk vizsgálni, akkor a következő feltétellel tehetjük ezt meg :
if ($_POST[’kapcsol’]=="on") {
// ha be van kapcsolva:
} else {
// ha nincs bekapcsolva:
}
A fenti kóddal azonos:
if ($_POST[’kapcsol’] != ’’) {
// ha be van kapcsolva:
} else {
// ha nincs bekapcsolva:
}
Azt azonban ne felejtsük el, hogy mindkét változat esetén a „nincs bekapcsolva” eset kerül végrehajtásra akkor, ha
nincs is űrlap, amit fel kell dolgozni!
Választógombok esetén más a helyzet: ilyenkor több választógomb osztozik ugyanazon az azonosítón – ez kapcsolók
esetén problémákhoz vezethet –, és mindig a kiválasztott választógomb value paraméterének értéke adódik át az űrlap
elküldésekor. Vegyük a következő részletet egy űrlap kódjából :
<input type=’radio’ name=’nem’ value=’male’> Férfi<br>
<input type=’radio’ name=’nem’ value=’female’> Nő
Ebben az esetben három lehetséges értéke lesz a megfelelő tömbelemnek :2
1. ’male’, ha az első gomb van kiválasztva,
2. ’female’, ha a második gomb van kiválasztva,
3. ’’ (üres karaktersorozat), ha egyik gomb sem lett kiválasztva – és így a mező nem lett elküldve –, vagy ha nincs
is feldolgozandó űrlap. Amennyiben azt szeretnénk, hogy valamelyik gomb feltétlenül legyen kiválasztva – így
az üres karaktersorozat az űrlap hiányát jelezze –, két megoldást választhatunk. Az egyik, hogy valamelyik gom-
bot alaphelyzetben bekapcsolttá tesszük a selected paraméter szerepeltetésével. A másik, hogy JavaScripttel
előzetesen ellenőrizzük az űrlapot, és csak akkor engedjük elküldeni, ha a mezőnek van értéke.
A választógombok feldolgozását – főleg ha kettőnél több gomb van – leginkább a switch utasítással szokás elvégezni.
A fenti példának megfelelő kód alább látható. Természetesen két érték esetén még az if utasítás is hasznosnak tűnhet.
swicth ($_POST[’nem’]) {
case ’male’:
// férfi van kiválasztva
break;
case ’female’:
// nő van kiválasztva
break;
default:
// egyik sincs kiválasztva, vagy nincs űrlap
break;
}
2A példákban inkább a POST metódus használatát preferáljuk.

277
Amennyiben más módon már gondoskodtunk arról, hogy ne lehessen érték nélküli a tömbelem, akkor a fenti utasí-
tás egy if utasítással helyettesíthető, azonban több lehetőséges választógomb esetén kifejezetten a fenti formát javasolt
használni.

21.3. Állományfeltöltés
Az állományfeltöltés egy kicsit speciálisan kezelendő része az űrlapnak. Ilyenkor nem csupán néhány szöveges adatot
kell továbbítani, hanem akár több MByte méretű egész állományokat, a nevükkel együtt, amelyeknek a tárolásáról a PHP
scriptnek kell gondoskodnia.
Az állományfeltöltéshez az űrlap kódolási típusát speciálisan „multipart/form-data” típusúnak kell megadni, és POST
metódussal kell elküldeni (később ismertetünk egy másik lehetséges módszert, a PUT metódust is). Íme az állomány
feltöltésére használható űrlap:

<form enctype="multipart/form-data" action="_URL_" method="post">


<input type="hidden" name="MAX_FILE_SIZE" value="1000">
Fájl elküldése: <input name="userfile" type="file">
<input type="submit" value="OK">
</form>

A fenti példában az _URL_ helyére természetesen annak a PHP scriptnek a címét kell írni, amely a feltöltött állomány
kezelni fogja. A rejtett MAX_FILE_SIZE mezőnek mindenképpen a feltöltő mező előtt kell szerepelnie. Funkciója, hogy
beállítsa azt a legnagyobb állományméretet, amit a PHP-nek kezelnie kell. A megadott érték byte-ban mérendő, így a fenti
példa legfeljebb 1 kByte méretű állományokat fogad el.
A megfelelően beállított PHP környezetben – a track_vars beállításnak bekapcsoltnak kell lennie – létrejön a
HTTP_POST_FILES és a $_FILES tömb (az utóbbit célszerűbb használni, mert mindig elérhető).
A $HTTP_POST_FILES gyakorlatilag egy asszociatív tömböket tartalmazó asszociatív tömb. Az első index határoz-
za meg, hogy melyik feltöltő mezőről van szó. A fenti példában a $HTTP_POST_FILES[’userfile’] hivatkozik a
feltöltőmezőre. Az így megadott tömbelem viszont maga is egy asszociatív tömb, amely a következő értékeket tartalmaz-
za :

• $HTTP_POST_FILES[’userfile’][’name’] : A kliens gépen az állomány (eredeti) neve.


• $HTTP_POST_FILES[’userfile’][’type’] : Az állomány MIME típusa, amennyiben a böngésző ezt az
információt elküldi. Egy jpg kép esetén ez ’image/jpg’ lesz.
• $HTTP_POST_FILES[’userfile’][’size’] : Az állomány mérete byte-ban.
• $HTTP_POST_FILES[’userfile’][’tmp_name’] : Az állomány ideiglenes útvonala és neve, ahova a fel-
töltés után került.

A PHP 4.1.0 verziójától kezdve már a $_FILES tömb is használható a fenti elemekkel – célszerűbb inkább azt
használni.
A feltöltéskor, mint a fentiekből már sejthető, először egy ideiglenes könyvtárba kerülnek a feltöltött állományok. Itt
addig maradnak, amíg a PHP script le nem fut. Ha addig nem teszünk velük valamit, akkor törlésre kerülnek. Az ideiglenes
könyvtár helye a /etc/php.ini állományban befolyásolható a upload_tmp_dir beállítással. Ha ez nem szerepel,
akkor a rendszer szokásos ideiglenes könyvtárát – általában a /var/tmp vagy /tmp – használja a webszerver.
Tehát ha az állományt meg akarjuk tartani, akkor az ideiglenes könyvtárból máshova kell másolni azt. Erre két függ-
vény szolgálhat, az egyik a copy, a másik a move_uploaded_file függvény. Mindkettő az első paraméterében kéri a má-
solandó állomány jelenlegi helyét, második paraméterként pedig az új helyét. A különbség, hogy az első megtartja az
eredeti helyen is, a második csak az új helyen tartja meg.

278
Az állományfeltöltéshez tartozó függvények:
• is_uploaded_file: igaz értéket ad, ha az állományt feltöltötték, hamis értéket, ha nem. Paraméterként az ellenőri-
zendő állomány elérési úttal megadott nevét várja. Ezzel a függvénnyel lehet megvizsgálni, hogy egy állomány
tényleges feltöltés útján érkezett, vagy sem. Ilyen módon lehet elkerülni az olyan támadási kísérleteket amelyek
rendszerállományokhoz kívánnak hozzáférni.
• move_uploaded_file: igaz értéket ad, ha a műveletet végre tudta hajtani, hamisat különben. Első paramétere a forrás
állomány elérési útvonallal megadott neve, második paramétere az az elérési útvonal és állománynév, ahova át kell
helyezni az állományt. A végrehajtás előtt a függvény ellenőrzi, hogy állományfeltöltéssel kapott állományról van-e
szó, és csak ha igen, akkor végzi el a mozgatást. Ha a célként megadott állomány már létezik, azt az új állomány
felülírja !
• copy: általában állományok másolását teszi lehetővé. Első paramétere a forrás, a második a cél elérési úttal együtt
megadott neve. Ha a célállomány már létezik, felülírásra kerül. Ha a másolás nem sikerült (például jogosultsági
gondok miatt), akkor nem hajtja végre azt, és hamis értékkel tér vissza.
• rename: általában egy állomány átnevezését végzi. Első paramétere a régi név, a második az új név, elérési útvo-
nallal megadva. Siker esetén igaz, egyébként hamis értékkel tér vissza. Tulajdonképpen az mv parancsot valósítja
meg, tehát mozgatást is lehet vele végezni.
• unlink : a paraméterében megadott nevű állományt megkísérli törölni. Ha sikerül, igaz, egyébként hamis értéket ad
vissza. Az állomány nevét elérési úttal együtt kell megadni.
Természetesen a fenti függvények az első kettő kivételével más állományokra is használhatóak. . .

21.3.1. Több állomány egyidejű feltöltése


Természetesen lehetőség van több állomány egyidejű feltöltésére is. Ennek legegyszerűbb módja, ha több feltöltő mezőt
adunk meg más-más name paraméterértékkel. Ekkor a $_FILES tömb egy-egy eleme lesz az egyes mezőkkel feltöltött
állomány leírása.
Arra is van lehetőség – mint általában a többi űrlap elemnél is –, hogy azonos nevű elemkből tömböt alkossunk :

<form action="file-feltolt.php" method="post" enctype="multipart/form-data">


Az alábbi fájlok elküldése:<br>
<input name="userfile[]" type="file"><br>
<input name="userfile[]" type="file"><br>
<input type="submit" value="OK">
</form>

Ebben az esetben az első elemben kiválasztott állomány nevét a $_FILES[’userfile’][’name’][0], a má-


sodikét a $_FILES[’userfile’][’name’][1] változó tartalmazza.3 A többi tulajdonság hasonlóan érhető el.

21.3.2. Feltöltés a PUT metódussal


A HTTP 1.1 protokoll ismer egy állományfeltöltési módot, amelynél mindössze ennyit kell elküldeni a szerverhez:
PUT /elérési/út/filename HTTP/1.1
3A második és a harmadik index sorrendje fordítva lenne logikusabb, de a PHP leírása szerint így kell megadni. . .

279
(persze ezután magát az állomány tartalmát is el kell küldeni a szerverre. . . )
Persze a webszerver ilyenkor még nem engedélyezi azonnal az állománynak a megadott könyvtárba a megadott néven
történő elmentését, hiszen ez azt jelentené, hogy bárki bármikor bármelyik weboldalt kedvére felülírhatja. Az egyes
webszervereknél erre az esetre egy programot be kell állítani, amely kezeli a kéréseket. Ez lehet egy PHP script is, amely
ilyenkor meghívásra kerül, és egy ideiglenes állományban megkapja a felmásolandó állományt. Az állomány az ideiglenes
helyen addig marad, amíg a PHP script véget nem ér – vagy el nem másoljuk onnan. Az ideiglenes állomány fellelési
helyét a $PHP_PUT_FILENAME változó tartalmazza. A kívánt feltöltési helyet a $REQUEST_URI változó tartalmazza.
Így a megfelelő ellenőrzések elvégzése után a feltöltés „jóváhagyása”, vagyis a célhelyre másolás a következő PHP
utasítással történhet:
copy($PHP_UPLOADED_FILE_NAME,$DOCUMENT_ROOT.$REQUEST_URI);

A fenti utasításban a $DOCUMENT_ROOT változó a webszerver dokumentumkönyvtárának a gép főkönyvtárán belüli


elérési útvonalát adja.

280
22. fejezet

Adatbáziskezelés PHP-n keresztül

Ebben a fejezetben a PostgreSQL szerver használatán keresztül mutatjuk be, hogy milyen módon lehet egy PHP scripten
keresztül adatbáziskezelési műveleteket végrehajtani. Természetesen az itt bemutatott megoldás használható más SQL-
szerverekkel is, ha a használt függvényeket kicseréljük arra, amely az adott adatbázis szerverrel való kommunikációra
szolgált. A szükséges függvények leírása megtalálható a [6]-ban a függvényreferencia részben.
A fejezetben szükség lesz az SQL nyelv ismeretére (16. fejezet), valamint az adatbázis tervezéséről szóló rész végén
megadott példa-adatbázisra, mivel ebben a fejezetben fogjuk bemutatni, hogyan lehet ahhoz az adatbázishoz egy webes
felületet használó információs rendszert készíteni. A példa rendszer valamennyi PHP scriptje teljes egészében elérhetővé
lesz téve a későbbiekben. . . 1

22.1. Csatlakozás és kapcsolatbontás


Ahhoz, hogy a PHP script hozzáférjen az adatbázishoz, először létre kell hozni a kapcsolatot az adatbázis szerverrel. Egy
adatbázis szerver több adatbázist is kezelhet egyszerre, és mindegyikhez pontosan meghatározott felhasználók férhetnek
hozzá – egy-egy felhasználó is esetleg más-más jogosultságokkal rendelkezve.
Ebből következően a kapcsolat létrehozásakor (csatlakozáskor) meg kell adni azokat az információkat, amelyek alap-
ján az adatbázis szerver el tudja dönteni, hogy melyik adatbázishoz, milyen hozzáférést kell biztosítania. Ez a PostgreSQL
esetén a pg_connect függvénnyel lehetséges.
Amikor már nincs tovább szükség a kapcsolatra, akkor a pg_close függvénnyel lehet a kapcsolatot lezárni. Amennyi-
ben a PHP script véget ér, akkor általában az adatbázis-kapcsolatai is automatikusan lezárásra kerülnek. Azonban mégis
célszerű a pg_close függvénnyel lezárni a kapcsolatokat, mivel előfordulhat néhány speciális eset, amikor a kapcsolat
magától nem kerül lezárásra. Ilyen speciális eset lehet a tartós adatbázis-kapcsolat, amelyről ebben a dokumentumban
nem ejtünk szót.
1 Ennek módja jelen pillanatban még nem dőlt el, de valószínűleg letölthető lesz ugyanonnan, ahol ez a könyv is fellelhető.

281
A pg_connect függvény: A pg_connect függvény egy PostgreSQL szerverrel létesít kapcsolatot. Amennyiben a kap-
csolat sikeresen létrejön, a visszaadott érték egy kapcsolat-referencia, amely a későbbiekben a további adatbáziskezelő
függvényekben a kapcsolat beazonosítására használandó (éppen ezért egy változóban ajánlatos megőrizni). Hamis ér-
téket ad eredményül, ha a kapcsolatot nem lehet létrehozni valami miatt.
A függvény paraméterei:
1. host : a gép neve vagy IP címe, amelyen az adatbázis szerver fut.
2. port : annak a portnak a száma, amelyen az adatbázis szerver figyeli az esetleges kliensek üzeneteit.
3. options: a csatlakozáshoz szükséges egyéb kapcsolók adhatók itt meg.
4. tty: a kliens azonosítására szolgáló információ.
5. dbname: az adatbázis neve, amelyet a kapcsolatban használni szeretnénk.

Általában a fenti paraméterezés helyett azonban egy alternatív, és jobban használható megoldást használunk, amikor
egyetlen szöveges paraméterben, szóközzel elválasztva adjuk meg egy egyenlőségjel után a következő értékek közül a
szükségeseket:
host : a gép neve vagy IP címe, amelyen az adatbázis szerver fut.
port : a port címe.
dbname : az adatbázis neve.
user : a felhasználó azonosítója, amelyet a kapcsolat során használni kell.
password : a felhasználói azonosítóhoz tartozó jelszó.
Ezeken felül a fenti további paraméternevek is használhatóak.

A pg_close függvény A pg_close függvény lezárja a paraméterében megadott kapcsolatot. A paramétere egy korábbi,
még nem lezárt kapcsolat azonosítója, amely azonosítót a kapcsolatot megnyitó pg_connect függvény adott eredmény-
ként.
A függvény egy igaz értéket ad vissza, kivéve abban az esetben, ha a hamis visszatérési értékkel kell jeleznie, hogy a
paraméter nem egy még nyitva levő kapcsolat érvényes azonosítója.

22.2. SQL-kérés küldése


A leglényegesebb része az adatbázis használatnak az SQL-kérés. Tulajdonképpen a csatlakozás után minden adatbázis-
műveletet az adatbázis-szerver számára küldött SQL utasítással hajtunk végre. Ez a PostgreSQL-PHP páros esetén a
pg_query függvény meghívását jelenti.

282
A pg_query függvény: A pg_query függvény az első paraméterében meghatározott kapcsolaton keresztül elérhető
adatbázison megkísérli végrehajtani a második paraméterében megadott SQL utasítást. Amennyiben ez nem lehetséges,
hamis értéket ad vissza. Ebben az esetben a hiba okát a pg_last_error függvénnyel lehet lekérdezni.
A függvény paraméterei:
connection : egy esetlegesen elhagyható paraméter, amely annak a kapcsolatnak – a pg_connect függvény által vissza-
adott – azonosítója, amely kapcsolatban a kérést végre kell hajtani. Ha a paraméter nem szerepel, akkor a legutóbb
használt kapcsolatra fog a kérés vonatkozni. Célszerű azonban mindig megadni ezt a paramétert.
query : A végrehajtandó SQL utasítást tartalmazó karakterlánc. Az SQL utasításnak a PostgreSQL szabályainak meg-
felelőnek kell lennie, ahogyan például a psql kliensen keresztül is ki lehetne adni. Az egyetlen különbség, hogy
a végén a pontosvesszőt nem kell – és nem is szabad – szerepeltetni.
Amennyiben az SQL utasítást végre lehetett hajtani és az utasítás ad valamilyen eredményt, akkor a függvény vissza-
térési értéke lesz felhasználható az eredmény feldolgozására.

A függvény logikai igaz értéket ad eredményül minden olyan esetben, ha az utasítást sikerült végrehajtani. Ebben az
esetben a visszaadott érték egy referenciát tartalmaz arra a táblára, amit az utasítás eredményezett, ha van ilyen tábla. Ha
nincs visszaadandó eredmény, akkor is igaz értéket ad.
Amiatt azoknál az SQL utasításoknál, amelyek eredményt adnak vissza, egy változónak kell a függvényt értékül adni.
Íme egy példa :
$eredmény = pg_query($connect,"SELECT * FROM termékek");
A visszaadott tábla sorainak számát lekérdezhetjük a pg_num_rows függvénnyel. Ha ez nulla, az azt jelenti, hogy
bár a lekérdezés sikeres volt, az eredménytábla nem tartalmaz sort. Ez teljesen természetes, ha feltétel is szerepel a
lekérdezésben, hiszen lehetséges olyan eset, amikor nincs a megadott feltételnek megfelelő sor.
A pg_num_rows függvény: A függvény a paraméterében szereplő referenciához tartozó eredménytábla sorainak szá-
mát adja eredményül. Ha a referencia nem valós referencia, akkor figyelmeztetést ad.

Ha van sora az eredménytáblának, akkor azokhoz egyenként férhetünk hozzá. Ennek legegyszerűbb módja, ha a
pg_fetch_row függvényt használjuk. Ez azonban olyan tömböt ad eredményül, amelyben a sor egyes oszlopai nullától
kezdődő indexű elemekbe kerülnek.
A pg_fetch_row függvény: A függvény a paraméterében szereplő referenciához tartozó eredménytábla soronkövet-
kező sorát adja vissza eredményül numerikusan indexelt tömb formájában, vagy hamis értéket ad, ha már nincs több
visszaadható sor.
A függvény első meghívása az eredménytábla első sorát adja. Minden egyes meghíváskor a tábla következő sora lesz
az eredmény, azaz végig lehet lépegetni az eredménytábla elemein.

Sokkal jobban használható lehet a pg_fetch_array függvény, amely egy asszociatív tömböt ad vissza.
A pg_fetch_array függvény: A függvény a paraméterében szereplő referenciához tartozó eredménytábla soronkövet-
kező sorát adja vissza olyan asszociatív tömbként, amelyben a kulcsok az eredménytábla egyes oszlopainak nevével
egyeznek meg. A tömbelemek emellett elérhetőek az oszlop nullától kezdődő sorszámával, mint tömbindex-szel is.
A függvény első meghívása az eredménytábla első sorát adja. Minden egyes meghíváskor a tábla következő sora lesz
az eredmény, azaz végig lehet lépegetni az eredménytábla elemein.

Miután a lekérdezés eredményét feldolgoztuk, célszerű az eredménytáblát tároló memóriaterületet felszabadítani.2


Erre szolgál a pg_free_result függvény.
2 A script befejeződése után minden memóriaterület felszabadul, amit a script igénybe vett, így ha nem tesszük meg, akkor legkésőbb ekkor megtör-

ténik.

283
A pg_free_result függvény: A paraméterében megadott referenciához tartozó eredménytábla tárolására szolgáló me-
móriaterületet felszabadítja, majd igaz értéket ad vissza. Ha a referenciának megadott érték nem eredménytáblát jelöl,
akkor hamis értéket ad vissza.

Ezek felhasználásával egy PHP scriptben például így lehet egy lekérdezés eredményét feldolgozni :

$eredmény = pg_query($connect, "SELECT * FROM termékek");


while ($sor = pg_fetch_array($eredmény)) {
// amennyiben a $sor egy asszociatív tömb lesz, feldolgozzuk
}
// ide akkor jutunk, ha már nincs több sor
pg_free_result($eredmény);

22.3. Egy példa a PHP-n keresztüli adatbáziskezelésre: bolti árukészlet


Mint azt már néhányszor ígértük, egy bolti árukészletet nyilvántartó – nem tökéletes – adatbázishoz fogunk információs
rendszert készíteni, hogy ezen keresztül bemutathassuk az adatbáziskezelést, és a PHP használatát egyaránt.
Először ismerkedjünk meg közelebbről az információs rendszer fogalmával. Mint már az adatbáziskezelés elméletét
ismertető fejezetben definiáltuk (202. oldal), az információs-rendszer egy olyan szoftver, amely egy adatbázishoz bizto-
sít hozzáférést valamilyen felhasználóbarát felületen keresztül. Ez egyben azt is jelenti, hogy a felhasználónak nem kell
ismernie az adatbázis szerkezetét, sőt arról sem kell tudnia, hogy a szoftver, amit éppen használ, valamilyen adatbázisra
támaszkodik. Éppen ezért elmondhatjuk, hogy az a jó információs rendszer, amely a szükséges adatfelviteleket, és lekér-
dezéseket az emberi logikának, és nem az adatbázis logikájának megfelelő formában teszi elérhetővé. Ez általában azt
jelenti, hogy akár az adatfelvitel, akár a lekérdezés egyszerre egynél több adattáblát is érinthet.
Ezen megfontolások figyelembe vételével kezdjünk neki a rendsze elkészítéséhez. Először lássuk nagy vonalakban,
hogy milyen műveleteket kell a felhasználó számára elérhetővé tennünk :
• Adatfelvitel: szükség lesz egyrészt a különböző termékeknél alkalmazható forgalmi adó lehetséges mértékeinek
felvitelére – később a módosítására is. A leglényegesebb adatfelvitel azonban a termékek adatainak felvitele lesz.
• Adatmódosítás: a termékek adatainak vagy a forgalmi adó mértékének módosítása egészen biztosan szükséges
lehet.

• Értékesítés : a vásárló által megvett termékeket tartalmazó számla előállítása és nyomtatása.


• Napi összesításek: a napi forgalom kilistázása és nyomtatása.
• Utánrendelés: a termékek utánrendelése a megfelelő szállítónak küldendő megrendelőlap kinynyomtatása útján.
óooooooooo

284
Irodalomjegyzék

[1] W3C. HTML 4.01 szabvány (angol). http://www.w3c.org/.

[2] W3C. CSS2 szabvány (angol). http://www.w3c.org/.


[3] Michael Moncur. Tanuljuk meg a JavaScript használatát 24 óra alatt. KisKapu, 2002.
[4] Christian MacAuley and Paul Jobson. JavaScript Programozói referencia. Panem, 2003.
[5] Jeffrey D. Ullmann and Jennifer Widom. Adatbázisrendszerek – Alapvetés. Panem–Prentice-Hall, 1998. Egyetemi
tankönyv, de nem csak egyetemistáknak szánva.
[6] ftp ://ftp.postgresql.org/. PostgreSQL dokumentáció. Több különálló részből áll, mint a nyelv-referencia, felhasználói
kézikönyv, adminisztrátori kézikönyv, programozói kézikönyv stb.
[7] http ://www.php.net/docs.php. PHP kézikönyv.

285

You might also like