Lightbox beépítése AJAX-os oldalba

A Lightbox és a Lightbox 2 nagyon hasznos segédeszközök lehetnek weblapjainkon, azonban van egy hibájuk: kliens oldalon előállított oldalakhoz kicsit trükközni kell, hogy rendesen működjön. Ehhez szeretnék kis segítséget adni ebben a rövid leírásban.

Ahhoz, hogy az alapvető problémát megértsük egy kicsit a JavaScript alapjaihoz vissza kell térni: a JavaScript eseményvezéreltsége. Gondoljunk csak a HTML fájlokban levő onclick, onsubmit, onload és hasonló tulajdonságokra. Mind egy-egy függvényt állít be, ami lefut, ha az adott esemény (a user kattintgat, elküldi a formot vagy akár a usertől független oldal-betöltődés) bekövetkezik.

A felhasználó persze többször is kattinthat egy-egy elemre, akár többször is elküldhet egy formot (pl.: rosszul töltötte ki, így a JS megálljt parancsolt neki), viszont egy oldal csak egyszer töltődik be. Ezt az eseményt a böngésző hívja meg, amikor az oldal megjelenítése és a hozzá tartozó elemek (pl.: képek) letöltése kész.

A Lightbox pont erre az eseményre épít, így a linkek működését csak egyszer írja felül, ekkor hozza létre a megjelenítéshez szükséges HTML elemeket (div-ek, img-k, szövegek). Innen már egyszerű kitalálni, hogy az utólag felvitt elemekre nem lesz hatással. Szerencsére a kód nagyon jól meg van írva, egy újabb függvény-hívással bármikor képes a képeinkre lazadobozt varázsolni.

initLightbox();

A probléma az, mint azt korábban írtam, hogy ez a függvény tölti fel a DOM-ba a szükséges elemeket. A 20-ik hívásnál így már 19-szer feleslegesen lennének az elemek betöltve, így ezt elkerülendő egy kicsit módosítanunk kell az eredeti kódon.
Szerencsére a 2-es és 1-es verziók felépítése hasonló, így pillanatok alatt bármelyikre bevihető a – ráadásul megegyező – javítás, csak a sorok száma nem stimmel. Ez a 2.02 verzióban a 219., az 1-es verzióban pedig a 312. sor. (A sor számok persze változhatnak az új verziókkal, azonban könnyen megkereshetjük ezt a helyet: van valahol kommentelve egy rövidebb HTML részlet (ezzel tölti fel az oldalt), az ezután levő sorokba kell írni a következőkek. Ez az 1-es verziónál az initLightbox függvényben, a 2-esnél a Lightbox osztály konstruktorában (initalize) található.)

if(document.getElementById('overlay') != null) {
   return;
   }

Ez csak annyit csinál, hogy amennyiben már létezik overlay azonosítójú elem a DOM-ban visszatér a függvényből, így az utána levő kódok nem kerülnek értelmezésre. Vagyis nem helyez felesleges elemeket az oldalba.

Ezzel az első problémát áthidaltuk, már csak az initLightbox() függvényt kell minden oldal-módosításkor meghívni. Ebben – az ahány oldal annyi megoldás elv miatt – nem tudok segíteni, a lényeg, hogy mindig az oldal módosítása után kell azt megtenni.

Azonban hogy valami használhatót is írjak a Harder által leírt AJAX-os megoldáshoz egy kis segítség. Amilyen jól működik az a kód, annyira szörnyen néz ki az htmlhttprequest.js fájlja. Nem igazán látszik a kódban, de az abban leírt RemoteFileLoader osztálynak van egy onload eseménye. Ez – az xmlhttprequest objektumok onreadystatechange függvényével ellentétben – nem az adat letöltése után kerül meghívásra, hanem annak az oldalba illesztésekor – ugyanis szintén a RemoteFileLoader végzi ezt is. Éppen ezért nem kell ezt az átláthatatlan kódrengeteget módosítanunk, elég az inside.js fájlban módosítanunk egy keveset:

var docClickLoader = new RemoteFileLoader('docClickLoader');

Ezzel készítünk egy példányt a RemoteFileLoader-ből. Egész egyszerűen a docClickLoader onload tulajdonságát írjuk felül:

docClickLoader.onload = function() { initLightbox() };

Ezt beszúrva a második sorba a LightBox-unk minden így használt oldalunkon működni fog.

16 HOZZÁSZÓLÁS

  1. Ennyi infó alapján segíteni nem tudok, ha mutatsz egy oldalt, hogy hol szeretnéd megoldani, találunk vmi. megoldást.
    (Legrosszabb esetben a setInterval(initLightbox, 1000); megoldás működik, bár így lehet akár 1 mp-s késés is a LightBox aktiválásában.)

    BlackY

  2. Beírtam a nevembe az oldalt ahová szeretném beépíteni kérlek, hogy segíts nagyon megköszönném a segítségedet. (Az e-mail az msnem)

  3. Úgy tűnik a legújabb LB 2-ben már nincs initLightbox() függvény, úgyhogy:

    docClickLoader.onload = function() { new Lightbox(); };

    (Az initLightbox-ra való hivatkozásokat pedig töröld a fájlokból)

    BlackY

  4. Köszi de sajnos még mindig csak IEben működik FF-ben nem és valamiért nem jelennek meg a képek sem.!?!?

  5. Az az oldal több sebből vérzik, a legsúlyosabb: a modulok/galeria.html-ben a modulok könyvtárhoz képest használod a relatív útvonalat, holott amikor ezt ajax-szal hívod be, a gyökérkönyvtárhoz képest kéne az útvonalat megadni.
    Megoldás: használj abszolút útvonalat, vagy simán töröld a ../-t az img src-éje elől. Továbbá a két anchor rakd egy blokk-szintű elembe, mert így „felcsúsznak” a heading mellé.

    BlackY

  6. Okés javítottam de semmi nem változott ffben még mindig semmi nem jelenik meg! Ez mitől van??? IEben meg pro az egész???!?!?!

  7. Sziasztok!

    Egyszerű html oldalba lehetséges beépíteni a lightbox-ot? Ha igen, hogyan?

    Köszönöm!

  8. amatyi: Töltsd le a Firebug kiterjesztést, egyszerűbb azzal fejleszteni. Ha azzal /galeria/… -re állítom az anchort és az img src-t is, akkor működik. Viszont továbbra is áll, hogy kéne köréjük egy blokkszintű elem (pl. , , akármi).
    (És nem kell két percenként írni egy üzenetet, nem 24 órás help-desk vagyunk, ha és amikor ráérünk, segítünk; kontraproduktív, ha sürgetsz, mert elmegy az idő azoknak a hozzászólásoknak a törlésével.)

    Codee47: Igen. Alapvetően arra tervezték ;) Legegyszerűbb: letölltöd a Lightbox-ot az oldaláról, az ott levő script tagokat becopy-pasteled az oldalad head részébe, aztán a képekhez, amiket LB-vel akarsz megnyitni hozzáadod a rel=”lightbox” attribot.

    BlackY

  9. Okés sorry. Megvan a firebug. De nekem egy konkrét példára lenne szükségem mert nem értem, hogy mit takar amit leírtál csak kbra. Kérlek, hogy majd írj egy példát thx.

  10. 1
    2
    3
    4
    5
    6
    
    <h1>Galéria</h1>
    <a href="galeria/bigpics/eletkepek/1.jpg" rel="lightbox[roadtrip]" rel="nofollow"><img src="galeria/thumbpics/eletkepek/1.jpg" alt="1" /></a>
     
    <a href="galeria/bigpics/eletkepek/2.jpg" rel="lightbox[roadtrip]" rel="nofollow"><img src="galeria/thumbpics/eletkepek/2.jpg" alt="2" /></a>
    <p><br />
    </p>

    helyett

    1
    2
    3
    
    <h1>Galéria</h1>
    <p><a href="/galeria/bigpics/eletkepek/1.jpg" rel="lightbox[roadtrip]" rel="nofollow"><img src="/galeria/thumbpics/eletkepek/1.jpg" alt="1" /></a>
    <a href="/galeria/bigpics/eletkepek/2.jpg" rel="lightbox[roadtrip]" rel="nofollow"><img src="/galeria/thumbpics/eletkepek/2.jpg" alt="2" /></a></p>

    BlackY
    ui.: Azon se lennék egyébként meglepve, ha az FX-nek az nem tetszene, hogy egy div-be próbálsz doctypeostól-headestűl-bodystúl berakni egy teljes oldalt…

  11. MŰKÖDIK MŰKÖDIK MŰKÖDIK | KÖSZÖNÖM | KÖSZÖNÖM | KÖSZÖNÖM Nagyon szépen köszönöm, nélküled nem sikerült volna. Ezer hála mely örökké üldözni fog :)

    Már csak 1 olyan gáz maradt, hogy a lightbox képeit nem tölti be pl.: a preloadert meg a close gifet. De szerintem ez már menni fog thank you még1szer!

  12. Köszönöm, nekem is megy tökéletesen és elnézést, ismerem a lightbox honlapját de nem hiszem el, hogy majd ki verte a szemem a megoldás! :)

    Üdv!

HOZZÁSZÓLOK A CIKKHEZ

Kérjük, írja be véleményét!
írja be ide nevét