Paraméter átadás felugró ablakoknak kompatiblisen
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:Ehhez JavaScipt tudja hozzákapcsolni a felugró ablak kódját: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 feldolgozó JavaScript eseménykezelő kódrészlet pedig: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 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.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.
■ Tehát a képekre mutató linkek valahogy így néznek ki:
<a id="image" href="/example.jpg">link</a>
document.getElementById("image").onclick = popUp;
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>
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;
}
<a href='clip_track.jpg' class='popup'>link</a>
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;
onloadra inicializalas
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
className
Javítsatok ki ha rosszul tudom, de a className az nem IE specifikus? Nekem teljesen így rémlik... :)
DOM level 1
http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-58190037
tuDOM :)
nem.
getElementsByClassName()
(persze-persze, nem csak popup class illetve popup érték van a világon...)
bbalint
Mert a getElementsByClassName() nem DOM :)