HTML

Gyakorlat: képmegjelenítő 2. - lapozással

Ebben a részben kicsit tovább fejlesztjük az előzőben megalkotott képmegjelenítő plugint, méghozzá olyan formában, hogy megjelenítés után jobbra-balra váltogatva végig tudjuk nézni az összes képet bezárás nélkül. Egy "prettyPhoto" plugin esetében is ez már alap követelmény :) akkor mi sem adjuk alább ennél.

Akkor most nézzük, mi változik az eddigi konstrukcióhoz képest... Előre megmondom, sok minden máshogy fog kinézni :D de ez ne rémisszen el minket. Kezdetnek ott az "append" függvény, amivel hozzáadtuk a dokumentumunkhoz a megjelenítendő kép tábláját. Ebben szükségünk lesz még a két "lapozó" linket magában foglaló oszlopra:

<table id="myPhoto_cont" style="position:fixed;left:0px;top:0px;width:100%;height:100%;">
<tr><td align="center"><a id="prev" class="nav"> < </a></td>
<td align="center" valign="top"><img/><br/><span></span></td>
<td align="center"><a id="next" class="nav"> > </a></td></tr>
</table>

A zölddel kiemelt rész az újdonság. Az egyszerűség kedvéért most a "<" és ">" jelek lesznek a lapozó nyilak. Mindkét link a "nav" osztályhoz fog tartozni, de az azonosítójuk eltérő: "prev" és "next". Ezekre ráhúzunk még pár "css" függvényt és két egér-eseményt is (a cél csak ennyi: legyenek jól láthatók, alapesetben áttetszőek, majd mikor fölé visszük az egeret, teljese láthatóak):

$('#myPhoto_cont .nav').css('color','white')
.css('font-size','36px').css('margin','50px')

.css('display','block').css('font-weight','bold')
.css('cursor','pointer').css('opacity','0.5');

$('#myPhoto_cont .nav').hover(function(){
    $(this).css('opacity','1');
});

$('#myPhoto_cont .nav').mouseout(function(){
    $(this).css('opacity','0.5');
});

Itt szimplán csak beállítjuk ezeknek a navigációs "gomboknak" a betűtípusát (jó nagyra), a margókat, az áttetszőségüket, még azt is, hogy az egérkurzor "kézfejre" váltson, ha föléjük visszük. Aztán még a két esemény: "hover" esetén teljesen látható, a "mouseout" visszaállítja az áttetszőséget. Ezek itt mind csak esztétikai célokat szolgáltak...

További elképzelések a működésről...

Mivel itt már három esemény is képmegjelenítéshez vezet (a képre kattintás, illetve a jobbra-balra navigáció), célszerű a kép betöltését, illetve annak megjelenítését egy külön függvényre bízni, aminek a neve legyen "open". Mivel adott elemen belül tudunk az alapján kijelölni, hogy hányadik objektumról van szó ("nth-child"), a megjelenítéshez csak egy számot kellene eltárolni, hogy hányadik "a" linkről van szó épp, szóval a "selected_a" változónak most nem a konkrét objektum tárolása lesz a szerepe, hanem csak az aktuális link sorszámának tárolása. Tehát... ha rákattintunk egy képre, megtudakoljuk, hogy ő hányadik sorszámú kép és ez alapján megjelenítjük az "open" metódussal... ezután ha a "next", vagy "prev" gombokra kattintunk, akkor növeljük-csökkentjük a sorszám értékét, és ismét jöhet egy "open"... aztán bezárás esetén ismét - ahogy eddig is volt - a "noclose" értékétől függően eltüntetjük a felületet...

A fő függvényünk most bővülni fog kettő darab változóval:

var mainobj=$(this);
var img_count=$(this).find('a').length;

Tehát a "this" elem az a főobjektumunkat jelenti, amire definiáljuk a plugint, jelen esetben ugye a "gallery" azonosítójú "div" lesz ez. Nos, ha mondjuk egy ezen belül található elemre vonatkozó eseményben meghatározott függvényben szeretnénk hatást gyakorolni erre a főobjektumra, akkor a $(this) szócska már nem lesz alkalmas a célra, mivel az akkor már egy teljesen más elemre fog vonatkozni. Ezért célszerű a főobjektumunkra történő hivatkozást egy változóban eltárolni, most ezt a célt szolgálja a "mainobj", tehát ebbe szépen belepakoljuk a "this" értékét. 
A másik változónk pedig az "img_count" lesz, amibe a képek darabszámát tartjuk nyilván (a navigációhoz lesz fontos). Lényegében a jQuery kijelölései, valamint például az azokon belül végrehajtott "find" metódus is a szelektálás feltételeinek megadott elemeket gyűjti össze (és a továbbiakban megadott függvények majd azokra fognak hatást gyakorolni), tehát ezek az összeválogatott elemek gyakorlatilag egy tömböt alkotnak... egy tömb elemeinek számát pedig a JavaScript-ben a "length" kifejezés segítségével tudhatjuk meg. A második sorban ezek zajlanak: a főobjektumon belül megkeressük (összegyűjtjük) az "a" linkeket, majd ennek a kollekciónak (tömbnek) a hosszát (elemek száma) tároljuk el az "img_count" változóban. Ez azt is jelenti, hogy a plugin feltételezi az adott főelemről, hogy abban csakis kizárólag képekre hivatkozó linkek vannak... de egy galéria "dobozban" miért is lenne más :)

A vezérlő események:

A képmegjelenítési folyamat tehát akkor veszi kezdetét, ha az egyik kép-linkre rákattintunk. Ez ugyanúgy - ahogy az előző feladatban is volt - az "a" tag-ekhez rendelt "click" eseményben kerül kifejtésre. Most viszont nem ide írjuk a megjelenítéshez szükséges műveleteket (mivel most az a terv, hogy azért egy "open" függvény lesz a felelős), hanem szimplán csak meghatározzuk a kiválasztott link sorszámát (amit a "selected_a" változó eltárol), és meghívjuk a már említett "open" függvényt, ami majd ezen sorszám alapján elvégzi a szükséges további feladatokat. 

$(this).find('a').click(function(){
    selected_a=$(this).index()+1;
    open();
    return false;
});

function open(){}

Tehát így néz ki most a linkekre kattintáskor bekövetkező esemény, ami után odabiggyesztettem azért az "open" függvény definícióját is, hogy ne fulladjon hibába a program (mert ugye amikor a "click" esemény végén meghívjuk az "open"-t ha a szkript nem talál ilyen funkciót, akkor az hiba). Itt két újdonsággal is szembesülünk: az egyik "index" függvény. Ő igazából semmi bonyolult dolgot nem csinál, megmondja nekünk, hogy az aktuális "a" tag hányadik indexű elem az objektumunkban. Az indexelés viszont 0-tól indul (tehát az első elem a nulladik indexű), így hozzá kell adnunk 1-et, hogy a sorszám értékét kapjuk meg. Másik érdekesség: mi a fene az a "return false" a végén? Nos... az előző feladatban meg kellett oldanunk, hogy a link kattintást követően ne navigáljon el az oldalról a "href" tulajdonságban megadott címre, ezért azt ideiglenesen eltávolítottuk, majd vissza is kellett tennünk megtekintés után, stb... Ezt a gyakorlás és problémamegoldó készség "tornáztatása" érdekében csináltuk így, de van egy egyszerűbb módszer is: ha a "click" eseményben a függvény hamis értékkel tér vissza, akkor nem történik ugrás a hivatkozásra :) így nem kell szórakoznunk kiskapukkal ez a két kis szó a metódus végén mindent megold.

Ha már bejött a kép, akkor nyílik lehetőség a további navigálásra a jobbra-balra mutató nyilakkal. Emlékezzünk arra, hogy a képernyőt teljesen kitöltő tárolónk területére történő kattintás után a megjelenítő bezárul, ezért itt is szükségünk lesz a "noclose" változó értékének módosítására, hogy blokkoljuk ezt. Terveink szerint csak a megnyitni kívánt kép sorszámára van szükségük a megjelenítéshez, így csak a sorszámot tartalmazó "selected_a" változó értékét kell variálnunk, azaz csökkenteni, illetve növelni. Figyeljünk arra, hogy ne tudjunk "kiszaladni" a megadott tartományból, azaz: ha a sorszám 1 alá csökkenne, ugorjunk az utolsó képhez, ha pedig az utolsó kép után a "következő" gombra kattintunk, térjünk ismét az elsőhöz. 

$('#myPhoto_cont #prev').click(function(){
    noclose=true;
    if(selected_a>1)selected_a--;
    else selected_a=img_count;
    open();
});
$('#myPhoto_cont #next').click(function(){
    noclose=true;
    if(selected_a<img_count)selected_a++;
    else selected_a=1;
    open();
});

Akkor itt vannak a "prev" elem (előző képre ugrás) és a "next" elem (következő kép) kattintási eseményei. Mindkettő azzal kezdődik, hogy a "noclose" értékét igazra állítja, tehát a kattintást követően eszébe se jusson a szkriptnek bezárni a megjelenítő "ablakot". Ezután jön a "selected_a" (a kép sorszáma) változó értékének módosítása... a "prev" esetében: amennyiben ez még 1-nél nagyobb, akkor szimplán csak csökkentjük eggyel az értéket, ellenkező esetben pedig egyenlővé tesszük a képek darabszámával (és így lesz az utolsó kép a soron következő). A "next" esetében pedig: amíg ez az aktuális sorszám kevesebb, mint a képek száma, akkor csak növeljük eggyel, ellenkező esetben pedig az értéke egyenlő lesz 1-gyel (a legelső kép). Így jobbra-balra navigálva mindig "körkörösen végtelenítve" járjuk be a képeket. 

Most már minden hely megvan, ahol az "open" hívására kerül a sor. Itt az ideje, hogy megírjuk ezt a megjelenítésért felelős metódust is.

function open(){
    $('#myPhoto_cont span').text('');
    var tmp_a=mainobj.find('a:nth-child('+selected_a+')');
    $('#myPhoto_cont img').attr('src',tmp_a.attr('href'));
    if(ops.labels)
        $('#myPhoto_cont span').text(tmp_a.attr('title'));

    $('#myPhoto_back').fadeIn(250);
    $('#myPhoto_cont').fadeIn(500);
}

Itt a biztonság kedvéért máris azzal indítunk, hogy a "span"-ban lévő szöveget kitöröljük (ha volt, ha nem), mert ha esetleg az újonnan megjelenített képnek nincs "title" attribútuma, fennáll a veszélye, hogy ott marad az előző kép címszövege, az meg ugye gáááz lenne :D Ezután a főobjektumunkon belül "find" függvény segítségével egy "nth-child" szelektálással megkeressük a "selected_a" sorszámú "a" linket, majd ezt az elemet egy ideiglenesen felvett "tmp_a" változóban eltárolunk, hogy ne kelljen mindig végrehajtanunk ezt a keresést és ezt a hosszú kifejezést kiírni (tehát a "tmp_a" most az aktuálisan kiválasztott kép linkjét fogja jelenteni). A továbbiakban ugyanaz történik, mint eddig... a "myPhoto_cont" táblán belüli "img"-nek az "src" tulajdonságába betesszük a kiválasztott link "href" attribútumának értékét, így betöltődik a megfelelő kép a megjelenítőbe. Amennyiben az opciók közt engedélyezett a címkék megjelenítése ("labels" változó), a "span" belsejébe beírjuk a link "title" tulajdonságát is (már ha van). Végül pedig megjelenítjük a sötétítő hátteret és a megjelenítő tárolóját is.

Amelyik esemény még változást szenved az előző feladathoz képest, az a "myPhoto_cont"-hoz rendelt kattintási esemény, ami a bezárást biztosítja. A változás lényegében annyi, hogy két sort kikapunk belőle, így csak a "noclose" ellenőrzés és az eltüntetés marad:

$('#myPhoto_cont').click(function(){
    if(!noclose){
        $('#myPhoto_back').fadeOut(150);
        $('#myPhoto_cont').fadeOut(150);
    }else noclose=false;
});

Itt már nem kell foglalkoznunk a címszöveg törlésével, mert az az "open" metódus minden lefutásánál amúgy is megtörténik, valamint a "href" érték visszaállítására sincs szükség, mert már egyszerűbb módszert alkalmazunk a linkek kezelésére. 

Ennyi módosítást kellett eszközölnünk a plugin továbbfejlesztéséhez. Most már ezen is túl vagyunk, nagy királyok vagyunk :) Ha nem akar még ezek alapján megfelelően összeállni a dolog, akkor szedd le a forrásomat innen: KLIKK

Szólj hozzá: