Emlékeim szerint a Google Reader-ben találkoztam vele először, aztán a Netvibes is átvette (egy ideig a feedolvasóban lehetett használni, most pedig a fülek közti mozgásra szolgál): a J és K billentyűk nyomkodásával történő navigációról van szó, mely segítségével előre-hátra lehet halani. A bejegyzés egy olyan JavaScript kódot mutat be, mely ezt a navigációt valósítja meg a Webakadémia címlapján az egyes bejegyzések közti ugrálás céljából.

Mindenekelőtt definiáljuk a feladatot. Az oldalra érkező felhasználónak tegyük lehetővé a bejegyzés címek közötti ugrálást. Ha a J billentyűt lenyomja az oldalon, akkor az éppen aktuálishoz (amin áll éppen) következő bejegyzés címéhez ugorjunk, ha a K billentyűt lenyomja az oldalon, akkor pedig az éppen aktuális előttire.
Válasszunk JavaScript keretrendszert a feladathoz. A Webakadémia sminkjét a K2 nevű sablon szolgáltatja, mely a jQuery-t használja a JavaScriptes effektek megvalósításához, így ez a választás adta magát. A jQuery egyébként is egy jó választás lehet (én folyamatosan ugrálok a Prototype, jQuery, mooTools és még ki tudja milyen keretrendszerek között), amire szükségünk lesz a kivitelezéshez, az pedig benne van, kivéve a scrollozást lehető tevő jQuery.ScrollTo kiegészítő, amit egy gyors mozdulattal gyorsan letöltöttem és behúztam az oldal fejlécéből.
Elsőként az aktuális scroll pozíció megállapítására lesz szükségünk, hogy aztán meghatározhassuk, hogy melyik bejegyzésen is áll éppen a böngészőnk. Ezt a jQuery(document).scrollTop() segítségével kérdezzük le:
var c = jQuery(document).scrollTop();
Ez pixelben fogja nekünk megadni az oldal tetejétől kapott távolságot. A változó neve “c”, mint “current” lett a hirtelen névválasztás égisze alatt. Következő kérdés, hogy melyik bejegyzésen állunk éppen, avagy hova kell scrolloznunk. Ehhez vesszük az összes bejegyzéscímet az oldalról:
var titles = jQuery('.post');
Majd addig pásztázzuk végig a bejegyzések pozícióját, míg egy olyan bejegyzéscímhez nem érünk, ami az éppen aktuális pozíció alatt kezdődik (nagyobb az offszetje).
var i = 0; while (i < titles.length && jQuery(titles[i]).offset().top - 32 <= c) { i++; }
A 32 pixelt a K2 téma sajátossága miatt vontam le, mely az oldal tetején mindig megjelenít egy ilyen magas csíkot az oldalak közötti ugráláshoz. A műveletek végén az “i” változó arra a címre mutat, mely lejjebb helyezkedik el az oldalon az aktuális oldal tetejéhez képest, avagy következő bejegyzésnek nevezhető.
Ennél a pontnál célszerű a billentyűlenyomások kezelését behozni a képbe. Mivel egy az aktuális oldalhoz képest globális billentyű kezelő függvényt szeretnénk megvalósítani, a billetnyűlenyomások elkapását a documentumunkhoz kell rendelni. Végeznünk kell azonban egy ellenőrzést, hogy hol történt az esemény, hiszen nem szeretnénk lekezelni az eseményt, ha a kurzor egy input mezőn textarea-n, stb. áll. Ezért megnézzük, hogy a HTML/BODY (böngészőfüggő) elemhez rendelhető-e az esemény:
jQuery(document).keypress(function(e){if(e.target.tagName=='HTML'||e.target.tagName=='BODY'){ // ide jön az esemény lekezelése }});
Meg kell még néznünk azt is, hogy J vagy K billentyűt nyomtunk-e le, ehhez a CTRL és ALT billentyűk állapotát is lekérdezzük (nem akarjuk lekezelni a CTRL-J, ALT-K, stb. kombinációkat:
if (!e.altKey && !e.ctrlKey && (e.which==106 || e.which==107)) { }
Most kérdezhetjük le a fentebb már bemutatott kóddal az aktuális pozíciót, és számíthatjuk ki a következő bejegyzéscím sorszámát. Ha ezzel megvagyunk, a scrollozás előtt még korrigálni kell az “i” értékét ha a K betűt nyomtuk le, ekkor ugyanis nem a következő (most + 1), hanem az előző (most -1) elemre szeretnénk ugrani. Ha az “i”-ben a “most + 1″ szerepel, akkor kettőt levonva belőle ki is jön a kívánt érték:
if (e.which == 107) { i-=2; }
És a scrollozás (ha i-ben értelmes érték van):
if (i >= 0 && i < titles.length) { jQuery.scrollTo(jQuery(titles[i]).offset().top-32, 500, {easing:'swing'}); }
A teljes kód egyben:
jQuery(document).keypress(function(e){if(e.target.tagName=='HTML'||e.target.tagName=='BODY'){ if (!e.altKey && !e.ctrlKey && (e.which==106 || e.which==107)) { // J and K var c = jQuery(document).scrollTop(); var titles = jQuery('.post'); var i = 0; while (i < titles.length && jQuery(titles[i]).offset().top - 32 <= c) { i++; } if (e.which == 107) { i-=2; } if (i >= 0 && i < titles.length) { jQuery.scrollTo(jQuery(titles[i]).offset().top-32, 500, {easing:'swing'}); } } }});
A bővíthetőség, átalakíthatóság száma közel végtelen, a kód pedig teljesen szabadon felhasználható.
Valójában a (*nixos) Vimből származik ez a navigációs megoldás (a hatékonyság a Vimben fétis). Csak a történeti pontosság kedvéért…
Séra Bálint: na ezt nem tudtam, köszi a kiegészítést!
FF 2.0.0.14 nem megy es a 32px -es csuszka se koveti, mostanaban volt a jqueryvel egy kis gond (en a scroll es a dimensionnal is belefutottam)
Benjamin: kösz, bár ez így fog most maradni (kemény jáccótéri projekt volt).
Okosakat nem tudok hozzáfűzni, csak annyit, hogy: wow. Köszi a bejegyzést, így kicsit közelebb hoztál hozzám egy általában (számomra) varázslatnak tűnő területet.
[off]
Séra Bálint:
Ha már történeti pontosság, a hjkl navigáció megtalálható a vi-ben is, ami a vim előtt volt, de ki tudja, még hány másik elődjében.
[/off]
Pingback: Infinite scroll, a végtelen történet at ‹Webakadémia /›
Pingback: Google Reader szerű navigáció, megint at ‹Webakadémia /›