ugrás a tartalomhoz

Paraméter átadás felugró ablakoknak kompatiblisen

Hojtsy Gábor · 2004. Aug. 16. (H), 09.24
Cameron Adams a The Man in Blue blog szerkesztője akadt abba a problémába, hogy felugró ablakokat szeretett volna nyitni képei számára, ezt azonban JS nélküli böngészőkkel kompatibilis módon szerette volna elkészíteni. Ez azt jelenti, hogy a HTML-t eleve úgy kellett elkészítenie, hogy a kis képek közvetlenül a nagy képekre linkeltek. Ezután a - nálunk éppen ma reggel is bemutatott - diszkrét JavaScript metodológiát alkalmazta a felugró ablak kódok elhelyezésére.

Tehát a képekre mutató linkek valahogy így néznek ki:
  1. <a id="image" href="/example.jpg">link</a>  
Ehhez JavaScipt tudja hozzákapcsolni a felugró ablak kódját:
  1. document.getElementById("image").onclick = popUp;  
Ez sokkal jobb, mint a HTML attribútumban megadott onclick eseménykezelő, hiszen JavaScriptet nem támogató böngészőkben (kereső indexelő számára például) is működik a link, ráadásul az oldal kisebb lesz, és jobban kézben tarthatóbbak a dinamikus események.

Ahhoz azonban, hogy a nagyobb képet megjelenítő felugró ablak tudja a kép méretét, ezt valahogy el kell oda juttatni. A bemutatott JavaScript esemény hozzárendelés azonban nem teszi lehetővé a paraméterezett eseménykezelők beállítását. Ezért valahogy lehetővé kell tenni a HTML-ből a szükséges paraméterek eljutását a JavaScript számára.

Cameron úgy oldotta meg a dolgot, hogy a képhez felvett GET paramétereket, melyeket az eseménykezelőben dolgoz fel, így a megfelelő adatok eljutnak az új ablakot nyitó kódhoz, és a kép méretének megfelelő lesz az ablak, másrészt viszont a link JavaScript nélküli klikkelésekor is tökéletesen fog működni (csak néhány felesleges GET paraméter lesz benne, amik működését nem befolyásolják).

Így a link kódja:
  1. <a href="/example.jpg?js_width=400&js_height=300">link</a>  
A feldolgozó JavaScript eseménykezelő kódrészlet pedig:
  1. var parameterString = this.href.replace(/.*\?(.*)/, "$1");  
  2. var parameterTokens = parameterString.split("&");  
  3. var parameterList = new Array();  
  4.   
  5. for (i = 0; i < parameterTokens.length; i++)  
  6. {  
  7. var parameterName = parameterTokens[i].replace(/(.*)=.*/, "$1");  
  8. var parameterValue = parameterTokens[i].replace(/.*=(.*)/, "$1");  
  9. parameterList[parameterName] = parameterValue;  
  10. }  
Hasonló technikák használhatóak akkor is, ha nem nagyobb képekhez készítünk felugró ablakokat, hanem valamilyen más célú JavaScript hozzárendelésnél van szükségünk paraméterekre. Ha azonban a képekhez automatikusan méretezett ablakok kellenének, jobban jöhet Richard Allsebrook automatikusan működő megoldása, melyet a fenti kódra válaszul küldött be. Richard HTML kódja:
  1. <a href='clip_track.jpg' class='popup'>link</a>  
A hozzá tartozó JavaScript pedig minden popup osztályba tartozó linket felruház ablak nyitó képességgel, úgy, hogy az ablakok automatikusan méreteződnek a képhez.
  1. function initPopups() {  
  2.   // add an onclick event to every hyperlink with a class of 'popup'  
  3.   var els = document.getElementsByTagName("a");  
  4.   for(var i = 0; i < els.length; i++) {  
  5.     if (els[i].className.indexOf("popup") !=- 1) {  
  6.       els[i].onclick=popup;  
  7.     }  
  8.   }  
  9. }  
  10.   
  11. function popup() {  
  12.   // load the popup image into a temporary Image structure  
  13.   // once its finished loading, open the window with the correct Image dimensions  
  14.   // pulled from the Image structure  
  15.   
  16.   var img=new Image;  
  17.   img.src=this.href;  
  18.   img.onload=function () {  
  19.     var win=window.open(img.src, "popup""width="+(img.width+16)+",height="+(img.height+16))  
  20.   };  
  21.   // prevent the hyperlink from doing its default behaviour  
  22.   return false;   
  23. }  
  24.   
  25. window.onload = initPopups;  
Ez a megközelítés eléggé jól működik, ha képekhez képest automatikusan méretezendő ablakokra van szükségünk. Egyéb paraméter átadásnál azonban érdemes lehet elgondolkodni Cameron módszerének valamely variánsán.
 
1

onloadra inicializalas

Jano · 2004. Aug. 16. (H), 14.31
Lehet mar itt is emlitettem mas cikk kapcsan az onloadra inicializalas hatranyat. Egy gyors kapcsolaton a user valoszinuleg nem fogja eszrevenni a kulonbseget de a mai bongeszok eleg jol vannak mar optimalizalva arra, hogy a tartalmat szedjel le eloszor es gyorsan ki is tedjek mikozben a hatterkepek es egyeb inyencsegek meg toltoednek a hatterben az oldal lenyegeben hasznalhato a latogato szamara. Ha a latogato eleg furge a netkapcsolata pedig eleg lassu akkor siman elofordulhat, hogy ugy kattint ra a kepre, hogy a javascriptes esemenykezelo meg nincs hozzarendelve.

Azt mondanank ilyenkor, hogy nem olyan nagy baj, mert a nagy kep meg fog neki nyilni vagyis az oldal elerheto mnden szep.

DE!

A konzisztencia elveszik. Nem fogja erteni, hogy miert nyilik egyik kep uj ablakba es a masik miert nem.

3 alternativ dolog jutott eszembe amik hasznalhatok lennenek:

1. Behavior-ok hasznalat
Ezzel minden egyes link/kep inicializalasakor megkapja az esemenykezelot. Hatrnya,hogy csak IE es FireFox tamogatja. Ezert mindenkeppen csak az eredeti onloados megoldas kiegeszitesevel hasznalhato, hogy az lefusson a tobbi bongeszonek.

2. Globalis esemenykezelo
A body-hoz rendelunk egy globalis esemenykezelot es itt kezeljuk le az ablaknyitast ha eppen olyan linkre kattintunk.
Ez nem annyira elegans hiszen feleslegesen fut le a script minden egyes egyeb kattintaskor is (ez persze gyakorlatilag elhanyagolhato). Masreszt ha valamiert blokkoljuk az esemeny feljutasat a body elemhez a DOM faban akkor nemtudjuk azt lekezelni. Ez persze eleg ritka es egyedi eset. (Mondjuk valami drag&drop -os elemen vannak a linkjeink es a huzigalas script tesz keresztbe)


3. Link prototipus megvaltoztatasa
A javascript nem teljesen objektumorientalt nyelv hanem prototipusos vagy akarhogy is mondjak ezt helyesen.
A megoldas tehat az lenne ha a link prototipusban felul tudjuk irni az onclick esemnykezelot.
Valahogy igy:
Usefull prototype methods for JavaScript
2

className

wiktor · 2004. Aug. 16. (H), 19.58
> (els[i].className.indexOf("popup") !=- 1)

Javítsatok ki ha rosszul tudom, de a className az nem IE specifikus? Nekem teljesen így rémlik... :)
3

DOM level 1

Hojtsy Gábor · 2004. Aug. 16. (H), 20.38
A className a DOM 1-ben definiált tulajdonság:
http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-58190037
7

tuDOM :)

wiktor · 2004. Aug. 17. (K), 00.53
Való igaz, már én is rájöttem. Nem tudom miért rémlett nekem... :( Bíróságra nem kell mennünk... :))
4

nem.

bbalint · 2004. Aug. 16. (H), 20.39
egy DOM Inspector-ral egyetemben merem vállalni állításom akár bíróság előtt is...
5

getElementsByClassName()

bbalint · 2004. Aug. 16. (H), 20.41
van egy ilyen getElementsByClassName() függvény is a böngészőkben (amik támogatják a DOM-t). miért nem evvel vannak gyűjtögetve a bizonyos linkek?
(persze-persze, nem csak popup class illetve popup érték van a világon...)

bbalint
6

Mert a getElementsByClassName() nem DOM :)

Hojtsy Gábor · 2004. Aug. 16. (H), 21.02
http://blog.mooncalf.me.uk/archive/2003/03/25/RefinedClassFetching