A weboldalkészítő suli legutóbbi három leckéjében megpróbáltunk minél több lehetőséget bemutatni arra, hogyan lehet kizárólag a kaszkád stíluslapok kínálta lehetőségekre alapozva (vagy legalábbis a JavaScriptet csak némi „fűszerezésként” használva) kicsinosítani egy fotógaléria nyitólapját, majd azt, hogy hogyan lehet ebbe a galériába némi életet vinni: megjeleníteni a képek nagy(obb) változatát, esetleg a képek címeit és a hozzájuk kapcsolódó hosszabb-rövidebb képaláírásokat.
Ez alkalommal azt fogjuk megnézni, miként tudjuk életünket kissé egyszerűbbé tenni a JavaScript használatával – de a websuli hagyományaihoz híven természetesen azért felruházzuk képtárunkat egy kis extrával is.
Képlista – igazolt hiányzóval
Legutóbbi alkalommal azzal a mottóval kezdtük galériánk HTML-kódjának összeállítását, miszerint „győztes csapaton ne változtass!”. Mi most mégis megbontjuk a csapategységet, és egy kicsit egyszerűsítünk a korábban már jól bevált képlistánk felépítésén, egész pontosan megköszönjük az indexképek eddigi hathatós segítségét, és érzékeny búcsút veszünk a thumb osztályú, a fotók kicsinyített változatait tartalmazó képobjektumoktól. Így a hivatkozáson belül kizárólag a teljes méretű fotót tartalmazó ‹img›, a jelenleg a képcím szerepét betöltő ‹b›, valamint a hosszabb képleírásokat magába foglaló ‹em› elemeket tartjuk meg, még a különféle segéd ‹span›-okra sem lesz szükségünk. Minimális dekorációként a container ‹div›-en belül – a képlista előtt – létrehozunk egy üres, ovarlay nevű ‹div›-et (14. sor), amit a képlista áttetsző háttereként fogunk majd használni.
A budapesti fotók sorát kibővítettük három újabb képpel, azért, hogy később megírandó programunk dolgát egy kicsit nehezebbé tegyük. Ugyanis az új fotók az eddigiektől eltérően nem fekvők, hanem állók, így a szélességük és magasságuk más lesz, mint a régebbieké. Ugyanakkor annyit azért mégiscsak könnyítünk a saját dolgunkon, hogy a fotóknál land (landscape) osztállyal jelöljük meg a fekvő és port (portrait) osztállyal az álló tájolású képeket. Galériánk első (ki)nézetének kialakítása már-már rutinmunka mindazoknak, akik megtanulták (és ugye megtanulták!) a legutóbbi három lecke anyagát – ezért is raktunk bele egy kis „csavart”, hogy azért mégse legyen olyan unalmas.
A dokumentumot, egész pontosan a ‹body› elemet ismét mintás háttérrel látjuk el, hogy jól láthatóak legyenek a különféle „átlátszóságalapú trükkjeink”, ahogyan a galéria címsorának két sorát is kissé eltérően formázzuk meg, hogy még jobban nézzen ki. A container ‹div›-et a szokásos módon igazítsuk középre, és lássuk el egy dupla fekete kerettel, de mindezeknél sokkal fontosabb, hogy pozícióját állítsuk relatívra, hogy innentől kezdve az ő bal felső sarka legyen a benne lévő elemek origója, de mivel sem a left, sem a top értékét nem piszkáljuk, így elmozdulni emiatt nem fog (26–31. sorok). Az overlay ‹div›-et ez esetben szó szerint takaróként használjuk – rögzítsünk a szülőelem bal felső sarkához, feszítsük ki teljes szélességében és magasságában, valamint gondoskodjunk arról, hogy ez a fehér színű takaró minden „modern böngészőn” félig átlátszó legyen (33–43. sorok). A bal felső sarokhoz rögzítést, vagyis a top és a left stíluselemeket el is hagyhatnánk, hiszen ez az alapértelmezett, ahogyan a „kifeszítést” megoldhatnánk úgy is, hogy nem az elem szélességét és magasságát maximalizáljuk (width: 100%; height: 100%;), hanem a jobb alsó sarkot rögzítjük a szülőelem jobb alsó sarkához (right: 0; bottom: 0;). A végeredmény a lényeg: a container ‹div›-et takarjuk le egy félig átlátszó elemmel, így ezzel elhalványítjuk az oldal mintás hátterét.
A képlista formázása remélhetőleg mostanra már minden websulisnak szinte rutinból menne – ha nem lenne két nem is olyan apró változtatás a korábbiakhoz képest. Az első természetesen az, hogy nincsenek indexképeink – azokat a teljes méretű fotókból állítsuk elő úgy, hogy a fekvő (vagyis land osztályú) képek szélességét 90 pixelre állítjuk, míg az állóknak (vagyis a port osztályúaknak) a magasságát határozzuk meg 60 pixelben. Szerencsére a böngészők – hacsak másképp nem rendelkezünk – a képek méretét arányosan változtatják, így nem kell azzal foglalkoznunk, hogy a „méretpárokat” is megadjuk. Annak érdekében, hogy az álló fotókat tartalmazó listaelemek ugyanúgy 90 pixel szélesek legyenek, ezeknek a képeknek állítsunk be 25-25 pixelnyi margót, mivel a 3:2 képarány miatt a 60 pixel magasság 40 pixel szélességet fog eredményezni (66–73. sorok). Miután ebben a nézetben a képcímre és képaláírásokra nincs szükségünk, ezért ezeket tüntessük el egyszerűen, mintha ott sem lennének (75–78. sorok).
Ha most megnéznénk galériánkat, két furcsaságot vennénk észre: az egyik, hogy a szépen lekicsinyített fotóink is halványabbak lettek, a másik, hogy annak ellenére, hogy minden kép egy hivatkozáson belül található, az egérkurzor alakja egyik fölött sem változik meg. Mindkét jelenség abból adódik, hogy a gondosan elhelyezett takaró ‹div›-ünk nemcsak a container ‹div›-et, hanem a képlistánkat is takarja – teljesen jogosan, hiszen a position: absolute; stílustulajdonság megadásával ezt az elemet a normál folyamban maradt objektumok – mint amilyen jelenleg a képlista is – fölé helyeztük. Miután nem ez a célunk, ezért a képlistánkat vegyük ki a takaró alól úgy, hogy őt is kiemeljük a normál folyamból a position: relative; megadásával (46. sor). Miután képlistánk a HTML-kódban hátrébb helyezkedik el, mint az overlay ‹div› – és a sorrendjüket nem változtatjuk meg z-index segítségével –, így utóbbi már tényleg csak a kívánt szülőobjektumot fogja szépen takarni, a fotókat már nem.
Végül azért, hogy jól látható legyen, melyik kép fölött is áll az egér, ezért ennek az eredetileg „átlátszó színű” keretét (55. sor) és hátterét színezzük ugyanannak a kéknek sötétebb és világosabb árnyalatára (80–83. sorok).
További elrendezések
Hasonlóan a Windows Intézőjéhez és a képböngésző programokhoz készítsük el a képlista legtömörebb megjelenítését, amikor is a képeknek csak a címe látszik. Tulajdonképpen ez esetben van a legegyszerűbb dolgunk, hiszen nem kell mást tennünk, mint eltüntetni magát a képet és a képaláírásokat (70–73. sorok), és hagyni, hogy a félkövér címek simán megjelenjenek a listában.
Ám miután galériánkhoz nem igazán illene egy ilyen túl egyszerű megoldás, ezért annyit tegyünk hozzá a fentiekhez, hogy az egyes listaelemek szélességét állítsuk akkorára, hogy két hasábban tudjanak megjelenni, és mintegy felsorolásjelként illesszünk eléjük például egy fényképezőgép ikont (52–58. sorok), amit a szöveg hátterével együtt változtassunk meg, amikor az egér az elem fölé ér (75–82. sorok).
Ennek a nézetnek pont az ellentettje, amikor minden látszik, vagyis a listában megjelenik a fotó – természetesen az első nézetnél bevált 90×60 pixeles méretűre kicsinyítve –, mellette pedig a kép címe és a hosszabb képaláírás.
Ehhez nem is kell mást tennünk, mint az eredetileg sorszintű elemeket (‹img›, ‹b› és ‹em›) balra folyatott blokkszintű elemekké alakítsuk, minimális egyéb formázások kíséretében (64–91. sorok). Egész pontosan a ‹b›-ket nem is kell balra folyatnunk, mert ezek amúgy is a kép mellett fognak megjelenni, ugyanakkor ha az ‹em›-eknél elhagynánk a float: left;-et, akkor a hosszabb szövegek befolynának a képek alá is, márpedig ez esetben nem ez a cél.
Képlistánk negyedik elrendezése csak annyiban tér el az elsőtől, hogy nem 90×60 pixeles befoglaló négyzetekben jelenítjük meg a fotókat, hanem a próba kedvéért 300×200 pixelesekben, és miután a 200 pixel magas állóképeink így 133 pixel szélesek lesznek, ezért a korábbi 25 pixeles margók helyett 83 pixel szélesekre lesz szükségünk.
További előkészületek
Miután ilyen szépen „belőttük” készülő képtárunk különböző nézeteit, módosítsunk egy kicsit az eredeti HTML-kódon. E módosítás során először is a container ‹div› legelejére – az overlay ‹div› elé – szúrjunk be egy újabb listát, ami a különböző nézetek ikonjait, valamint egy nagyon rövid méretválasztó listát fog tartalmazni (15–27. sorok).
Ez utóbbinál az egyszerűség kedvéért a méreteket jelölő betűket ne csak megjelenő tartalomként, hanem értékként is vigyük fel, ugyanis egyes böngészők sajnos a value hiányában nem a tartalmat, hanem üres értéket adnak vissza, amit ugyan megkerülhetnénk azzal, hogy megnézzük, melyik a kiválasztott sor, majd lekérdezzük annak tartalmát, de ennél sokkal kényelmesebb és gyorsabb a ‹select› value tulajdonságát elkérni a böngészőtől.
A kiválasztott fotókat, hasonlóan legutóbbi leckénk második galériájához, Lightbox-szerűen fogjuk megjeleníteni, azonban az ehhez valókat – köszönhetően a JavaScript segítségének – ezúttal nem kell minden képnél előkészítenünk, hanem elegendő „egy csomagot” összeállítanunk, például a képlista után (154–163. sorok). Ebben a „csomagban” helyezzünk el egy majdnem ugyanolyan takarót, mint amilyent a képlista mögött is használunk, csak feketét (155. sor), ezenkívül egy kép- (158. sor), egy képcím- (160. sor) és egy képaláírás- (161. sor) tárolót, valamint némi extraként egy „ablakbezárót” (159. sor), ami tulajdonképpen nem lesz más, mint egy nagyra nőtt szorzásjel.
Végül a képlista nyitó címkéjén módosítsunk annyit, hogy az osztályt változtassuk azonosítóvá, ugyanakkor osztályként adjuk meg az alapértelmezett nézet stílusát. Értelemszerűen a korábban gondosan összeállított stíluslapokból ki kell vágnunk a képlisták formázását, és globális cserével az ul.photos jelölőket ki kell cserélni ul.photo_list-re, ul.photo_icon-ra, ul.photo_desc-re és ul.photo_thum-re, majd ezeket szépen helyezzük egymás alá az új CSS-ben. Utóbbi nézethez még érdemes előkészíteni a választható méretekhez igazított szélességeket, magasságokat és margókat (például size_m és size_l osztálynéven), hogy ezeknél se a JavaScriptnek kelljen gondolkodnia.
Természetesen a két új blokk, vagyis az ikonlista és a nagy képek „vetítővásznának” (elő)formázását is meg kell csinálnunk stíluslapunkban. Az ikonlistát hasonlóképpen egy nagyobb kép háttérben történő tologatásával oldjuk meg, mint ahogyan azt tettük korábban a rádiógombok és a választómezők képesítésénél (49–79. sorok), míg a listát formázzuk meg ugyan, de egyelőre rejtsük el (81–86. sorok), míg a felhasználó a miniatűrök nézetet ki nem választja. Hasonlóképp gondosan végezzük el a fotók teljes méretű megjelenítésére használt „vásznat” és a rajta lévő szöveges elemeket is, így a nagy X-et is (275–324. sorok), ám az első kattintásig természetesen ezt is dugjuk el (276. sor).
A lightbox ‹div› és tartalmának formázása során igazából két dolog egyelőre függőben marad. Egyrészt ugyan a ‹div› magasságát beállítottuk 100%-ra, azonban sokszor még ez is kevésnek bizonyulhat, ahogyan most még azt sem tudjuk, hogy a képet és a hozzávalókat tartalmazó lightimg ‹div›-nek milyen szélességet is kell adnunk, hiszen ez természetesen a kiválasztott fotó szélességétől függ.
Változó galéria
Most már tényleg mindent olyannyira előkészítettünk, hogy JavaScript programunknak szinte alig maradt tennivalója – de azért akad.
Először is, miután a kép- és a méretlistára az inicializáló részen túl máshol is hivatkozunk, kényelmesebb, ha ezeket globális változóként definiáljuk, majd ezeket rögtön az inicializáló függvény elején állítsuk is be, hogy a megfelelő nevű objektumokra mutassanak (1. és 28–29. sorok). Ezt követően valamennyi ikonhoz rendeljük hozzá a selectView függvényt, paraméterként az ikon azonosítóját átadva (57–61. sorok). Ez a függvény nem csinál mást, mint a kapott azonosító elején lecseréli az „icon_”-t „photo_”-ra, és ezt állítja be a képlista osztálynevének – ezzel megváltoztatva annak megjelenését –, majd ha a „miniatűrök” nézetet választottuk, akkor megjeleníti a méretlistát és meg is hívja a hozzá kapcsolódó changeSize függvényt (ami szükség esetén további osztályokat rendel a képlistához), míg ha a másik három nézet valamelyike lett a befutó, akkor eltünteti a méreteket tartalmazó ‹select› elemet (3–12. sorok). A changeSize függvénynek természetesen akkor is el kell indulni, ha a felhasználó megváltoztatja annak értékét, erről a 63. sorban gondoskodunk is.
Miután azt szeretnénk, hogy a képekre kattintva azok ne a jelenlegi oldal helyére töltődjenek be – mint ahogy azt teszik még jelen pillanatban –, ezért mondjuk meg a böngészőnek, hogy a képlista bármelyik hivatkozására kattintva showPhoto függvény induljon el, majd szakítsa is meg a további műveleteket (65-67. sorok). Ez a showPhoto függvény először is átmásolja a kijelölt hivatkozáson belül található képet (31. és 35. sorok), annak címét (32. és 36. sorok), valamint leírását (33. és 37. sorok) a lightbox ‹div› megfelelő elemébe. Ezt követően a program megnézi, milyen széles a fotó, és ezt beállítja a lightimg ‹div› szélességének (39–42. sorok), ahogyan azt is megvizsgálja, hogy mekkora felületet is kell letakarni (azaz a dokumentum vagy az ablak hosszabb-e). Ezt a lightbox ‹div› magasságaként állítja be (43. sor), majd – minden lehetséges tájszólásban – megkérdezi a böngészőt arról, hogy hol is van most az oldal teteje (45. sor), és annak megfelelően esetlegesen lejjebb tolja a lightimg ‹div›-et (46. sor), hogy az mindig az ablak teteje alatt 15 pixellel jelenjen meg, végül láthatóvá teszi az eddig rejtett lightbox ‹div›-et (48. sor).
Jogosan merülhet fel a kérdés, hogy a képméret lekérdezéséhez miért kell létrehoznunk egy új képobjektumot, amit nem sokkal később törlünk is? Nos, erre az elemre azért van szükségünk, mert a böngészők közül egyedül a Firefox képes megmondani, hogy mekkora is egy kép eredeti mérete (naturalWidth, naturalHeight), az összes többi csak az éppen aktuális (jelen esetben a CSS-ben megadott) méreteket tudja visszaadni.
A legvégén pedig már nem is maradt más dolgunk, mint a bezáró gombot „élővé varázsolni”, hogy amikor rákattintunk, akkor tegye ismét láthatatlanná a lightbox ‹div› tartalmát (69. sor).
A cikkben bemutatott programok és mintaoldalak letölthetők innen.