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:

<a id="image" href="/example.jpg">link</a>
Ehhez JavaScipt tudja hozzákapcsolni a felugró ablak kódját:

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:

<a href="/example.jpg?js_width=400&js_height=300">link</a>
A feldolgozó JavaScript eseménykezelő kódrészlet pedig:

var parameterString = this.href.replace(/.*\?(.*)/, "$1");
var parameterTokens = parameterString.split("&");
var parameterList = new Array();

for (i = 0; i < parameterTokens.length; i++)
{
var parameterName = parameterTokens[i].replace(/(.*)=.*/, "$1");
var parameterValue = parameterTokens[i].replace(/.*=(.*)/, "$1");
parameterList[parameterName] = parameterValue;
}
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:

<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.

function initPopups() {
  // add an onclick event to every hyperlink with a class of 'popup'
  var els = document.getElementsByTagName("a");
  for(var i = 0; i < els.length; i++) {
    if (els[i].className.indexOf("popup") !=- 1) {
      els[i].onclick=popup;
    }
  }
}

function popup() {
  // load the popup image into a temporary Image structure
  // once its finished loading, open the window with the correct Image dimensions
  // pulled from the Image structure

  var img=new Image;
  img.src=this.href;
  img.onload=function () {
    var win=window.open(img.src, "popup", "width="+(img.width+16)+",height="+(img.height+16))
  };
  // prevent the hyperlink from doing its default behaviour
  return false; 
}

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