Megosztás-sáv készítése jQuery-vel, összesített képekkel

A következő leírásban bemutatom, hogyan lehet egy animált “megosztás-sávot” készíteni CSS sprite-ok és jQuery segítségével.
A végeredmény a demo oldalon látható.

Mivel a tooltip-nél CSS3-as beállításokat is alkalmaztam, így érdemes Firefox, Chrome vagy Safari böngészővel megnézni.

1. lépés: Összesített képek elkészítése

A tutorialnak jelen esetben nem célja bemutatni a CSS sprite-okkal kapcsolatos tudnivalókat, ha valaki nincs tisztában velük, rengeteg leírást talál róluk a neten.
A lényeg, hogy készítsünk egy ilyen, vagy ehhez hasonló képet:

sprites

Jelen esetben fix szélességekkel és magasságokkal dolgoztam, az ikonok alapesetben 36×36 pixelesek, “nyitott” állapotban pedig 140×36 pixelesek.
Ezért, mivel 5 elem lesz végül a listában, az összesített kép szélessége 5 x 140 pixel = 700 pixel lett.
A kép magassága 72 pixel (2 állapot, 2 x 36 pixel).

Az ikonokat az IconFinder ikonkereső oldalról szedtem le, valamint használtam még a Google képkeresőjét is. Előbbit ajánlom mindenkinek, aki még esetleg nem találkozott vele, rengeteg, jó minőségű ikont lehet találni rajta.

2. lépés: HTML

A HTML forráskód nagyon egyszerű, gyakorlatilag létre kell hoznunk egy egyszerű listát, a lista-elemekben pedig hivatkozásokat.

1
2
3
4
5
6
7
8
9
<div id="wrap">
  <ul id="nav">
    <li class="rss"><a href="#">Feliratkozás RSS csatornára</a></li>
    <li class="facebook"><a href="#">Megosztás Facebook-on</a></li>
    <li class="twitter"><a href="#">Megosztás Twitter-en</a></li>
    <li class="digg"><a href="#">Diggelés</a></li>
    <li class="delicious"><a href="#">Megosztás Delicous-on</a></li>
  </ul>
</div>

A DIV-elem nem kitétel, de valós helyzetben is valószínűleg egy tárolóban lesz a lista.
Ezek a közösségi oldalak rendelkeznek megfelelő API-val, tehát a hivatkozásunkat ennek megfelelően kell megformáznunk. Általában egy-két GET paramétert kell egy URL-nek átadni és kész.

3. lépés: CSS

Talán ez az egész projekt legbonyolultabb része (de nem kell megijedni, ez sem bonyolult, csak a többihez képest).
Tehát, haladjunk sorban:

A body tag-nek, valamint a wrap div-nek a következő beállításokat adtam:

1
2
3
4
5
6
7
8
9
10
body{
  margin:0;
  padding:0;
  font-family:Tahoma;
  color:#333;
}
 
#wrap{
  margin:40px;
}

Túl sok magyarázat nem kell hozzá: a böngésző alapértelmezett margin ill. padding beállításainak lenullázása; betűtípus ill. betűszín beállítása, a wrap esetében pedig egy 40 pixeles margin beállítása.
Jöhet a lista:

1
2
3
4
5
6
7
8
9
10
11
12
13
#nav{
  margin:0;
  padding:0;
  list-style:none;
}
 
#nav li{
  float:left;
  width:36px;
  height:36px;
  margin:0;
  overflow:hidden;
}

A lista beállításainál töröljük az alapértelmezett margin és padding beállításokat, valamint a list-style none beállítással megakadályozzuk, hogy bármilyen lista-jelzés jelenjen meg a lista-elemeknél.

A lista-elemek: Először is, mivel azt akarjuk, hogy egymás mellett jelenjenek meg, lebegtetnünk kell őket balra. Mivel fix méretekkel dolgozunk, a magasságot és szélességet is beállítjuk. A margin-t nullára állítjuk, tehát a lista elemek összeérnek.
Végül egy nagyon fontos beállítás: overflow: hidden. Ezzel azt érjük el, hogy bármely tartalom, ami a lista elemen belülre kerül, és szélesebb (vagy magasabb) mint az általunk megadott érték, nem fogja széttolni a lista-elemet, és scrollbar sem fog megjelenni.

Linkek stílusa:

1
2
3
4
5
6
#nav li a{
  display:block;
  height:36px;
  background:url(sprites.png) no-repeat;
  text-indent:-9999px;
}

Mivel a hivatkozás-elemekben jelenítjük meg a háttérképet, így fontos, hogy jó méretekkel dolgozzunk. Ahhoz, hogy egy hivatkozást (ami egyébként egy inline-elem) fix méretekkel tudjunk ellátni, először meg kell határoznunk egy display: block beállítást. Adjunk meg neki egy 36 pixeles magasságot. Szélesség meghatározására nincs szükség, azt majd a későbbiekben, JavaScript segítségével állítjuk be.

Ezután beállítjuk a háttérképet, ami ugyebár (mivel sprite-okat használunk) minden hivatkozásra érvényes lesz. A text-indent beállítás az elemen belül található szöveg behúzását mondja meg.

Esetünkben nincs szükség arra, hogy látható legyen a link szövege, de viszont szükségünk van rá a későbbiekben, mert így egyszerűen tudunk tooltip-et készíteni.
(És nem utolsó sorban a szöveg nélküli linkek a forráskódunk kinézetét is ronthatják, plusz a keresőrobotok sincsenek oda érte…)

Rendben, miután ezzel elkészültünk, már csak a háttérképet kell pozícionálnunk.
Föntebb, a lista elkészítésénél bizonyára észrevettétek, hogy minden LI-elemnek adtam egy egyedi osztálynevet. Erre pont a most következő lépés miatt volt szükség:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#nav .rss a {
  background-position:0 0;
}
 
#nav .rss a:hover {
  background-position:0 -36px;
}
 
#nav .facebook a {
  background-position:-140px 0;
}
 
#nav .facebook a:hover {
  background-position:-140px -36px;
}
 
#nav .twitter a {
  background-position:-280px 0;
}
 
#nav .twitter a:hover {
  background-position:-280px -36px;
}
 
#nav .digg a {
  background-position:-420px 0;
}
 
#nav .digg a:hover {
  background-position:-420px -36px;
}
 
#nav .delicious a {
  background-position:-560px 0;
}
 
#nav .delicious a:hove r{
  background-position:-560px -36px;
}

Amint az látható, minden osztály esetében fölülírjuk a hivatkozások stílusát, mégpedig a background-position értékekkel. Ennél a beállításál a háttérkép bal oldali (left) és felső (top) értékét lehet meghatározni (ebben a sorrendben!). Aki még nem használta ezt a beállítást, kicsit bonyolultnak tűnhet, de ha jobban megnézzük, egyértelmű: mindig annyi képponttal tologatjuk el a háttérképet, hogy beleférjen egy, a mi méreteinkkel ellátott, képzeletbeli keretbe.

Pl.: nézzük az rss osztályt. Mivel ez az első link, ezért az összesített kép bal felső sarka lesz a kiindulópont. A hover-beállításnál a bal oldal ugyanúgy nulla marad, de a felső részt már el kell tolni 36 pixellel, hogy a megfelelő képrészletet lássuk.
És így tovább…
Hogy ne kelljen mindig számolgatni, célszerű a kép létrehozásakor a képszerkesztőben segédvonalakat elhelyezni, és később a megfelelő értékek egyszerűen leolvashatók a vonalzóról.

4. lépés: jQuery

Miután a stílusokat is létrehoztuk, ideje írni egy kis JavaScript kódot, hogy életre keltsük az egészet, mert így még nem sok semmi történik.

Alapvető jQuery ismeretek elengedhetetlenek a leírás megértéséhez, ezért ha valaki most lát először ilyet, annak javaslom, hogy olvasson el egy gyorstalpalót ezzel kapcsolatban. (Természetesen másolás + beillesztés módszerrel is működésre lehet bírni, de jobb ha az ember érti amit csinál.)

Oké, először hívjuk meg a jQuery és jQuery Easing fájlokat a HEAD-be, valamint készítsünk egy SCRIPT-blokkot, ahová a saját kódunk kerül (természetesen külön fájlban is elhelyezhetjük):

1
2
3
4
5
6
7
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="jquery.easing.1.3.js"></script>
<script type="text/javascript">
  $(document).ready(function(){
    //eseménykezelők...
  });
</script>

Írjuk meg a hover eseménykezelőt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$('#nav li').hover(function(){
  //over:
  $(this).animate({ width: '140px' },{
    duration: 600,
    easing: 'easeOutBounce',
    queue: false
  });
},function(){
  //out:
  $(this).animate({ width: '36px' },{
    duration: 600,
    easing: 'easeOutBounce',
    queue: false
  });
});

A $(‘#nav li’) szelektorral megmondjuk a programnak, hogy csak a “nav” azonosítóval ellátott elemen belüli összes “li” tag-re legyen érvényes a hover-eseménykezelő. (Ha csak “li”-t írnánk, akkor minden lista-elemre lefutna az oldalon.)
Tulajdonképpen az egész effekt lelke az animate() függvény. Amikor a kurzor a lista-elem fölött van, akkor az 600ms alatt 140 pixel szélességűre “nő”. Az easing beállítással különböző mozgás-effekteket adhatunk meg az animációnak.
Én a bounce család egyik tagját választottam, mert talán ez az egyik leglátványosabb. Az összes lehetséges easing-típus egyébként megtalálható az easing-plugin hivatalos oldalán.

A queue: false beállítás meghatározza, hogy az animáció azonnal induljon, ne kerüljön bele az animációs sorba (queue). Ha ezt nem állítjuk be, akkor az éppen aktuális animáció nem indul el addig, amíg az előtte lévő be nem fejeződött.
A második függvényben, amikor a kurzor nincs a lista-elem fölött, szinte ugyanaz történik, csak itt értelemszerűen az elem szélességét visszaállítjuk 36 pixelesre.

5. lépés: Tooltip

Tehát az animációnk készen is van, a következő lépést csak egy extraként gondoltam: A tooltip. Ha nem is ilyen esetben, de rengetegszer hasznos lehet, ha rövid információt szeretnénk megosztani, és már “nem tudjuk hova tenni” az oldalon.
Annyi a lényege, hogy ha egy általunk meghatározott elem fölé húzzuk az egeret, akkor megjelenik egy szöveges blokk, ami követi a kurzort egészen addig amíg az adott elem fölött mozgatjuk. Nem egy nagy ördöngősség megcsinálni,
mégis nagyon fel tud dobni egy weboldalt.

Lássunk hozzá: A BODY-n belül hozzunk létre bárhol egy üres DIV-elemet, és lássuk el egy egyedi azonosítóval:

1
<div id="tooltip"> </div>

Most jöhet a CSS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#tooltip {
  display:none;
  position:absolute;
  width:140px;
  text-align:center;
  background:#333;
  -moz-border-radius:4px;
  -webkit-border-radius:4px;
  -moz-box-shadow:0px 0px 10px #666;
  -webkit-box-shadow:0px 0px 10px #666;
  padding:4px;
  color:white;
  font-size:11px;
  z-index:10;
}

Adtunk neki egy abszolút pozíciót, amely a későbbi pozícionálás miatt nagyon fontos. Természetesen, alapértelmezésként nem szeretnénk látni, a display: none gondoskodik erről. A szélessége jelenleg fix 140px, a háttérszín sötét szürke, a szöveg pedig fehér benne (csak hogy jól elkülönüljön a tartalomtól).
A magasabb z-index beállítás lehetővé teszi, hogy ne kerüljön egy másik elem alá az oldalon. A -moz és -webkit beállítások (ők felelősek a lekerekített sarkakért és az árnyékért) csak a CSS3-at támogató böngészőknél jelennek meg. Ezek a böngészők jelenleg a Gecko és WebKit motorra épülők, név szerint Firefox, Safari, Chrome. (IE-ben nyilván nem működik…).

Miután megvagyunk a CSS-el is, jöhet a JavaScript.

Biztos emlékeztek még, hogy amikor a listát légrehoztuk a hivatkozásoknak adtunk meg egy-egy rövid szöveget, holott ezek nem is látszanak. A tooltip-ünkben pontosan ez fog megjelenni. Első lépésként tehát meg kell keresni az aktuális szöveget, és beletenni a tooltip div-ünkbe. Ehhez a hover eseménykezelő első (mouse over) függvényét ki kell egészítenünk:

1
2
3
4
5
$('#nav li').hover(function(){
  var title = $(this).find('a').html();
 
  //animáció...
}

Ez a szelektor azt mondja, hogy “vedd az aktuális lista-elemet ($(this)), találd meg benne a hivatkozás-elemet (find(‘a’)), és szedd ki a benne található HTML-tartalmat (html())”.
A következő lépés, hogy feltöltsük a tooltipünket az aktuális szöveggel, és megjelenítsük:

1
2
3
4
5
var title = $(this).find('a').html();
 
$('#tooltip').html(title);
$('#tooltip').fadeIn(100);
//animáció...

Rendben, most már megjelenik a tooltip-ünk, mindig az aktuális tartalom van benne (legalábbis elvileg). De el is kellene tüntetni.
A hover eseménykezelő második (mouse out) függvényébe írjuk a következő sort:

1
2
3
$('#tooltip').fadeOut(100);
 
//animáció...

Nem egy bonyolult kód, mindösszesen eltünteti a DIV-et a szemünk elől.
Még egy problémát kell megoldanunk: igaz, megjelenik a tooltip, meg el is tűnik, amikor kell, csak épp nem mozog. Erre a következő a megoldás:

1
2
3
4
5
6
7
8
9
10
11
12
13
$(document).ready(function(){
  //mouse move:
  $("#nav li").mousemove(function(e){
    var topVal = (e.pageY - 40);
    var leftVal = (e.pageX - 70);
    if (leftVal <= 4){
      leftVal = 4;
    }
    $("#tooltip").css({
      top: topVal+'px',
      left: leftVal+'px'
    });
  });

Létrehozunk az adott lista-elemekhez egy mousemove eseménykezelőt. a függvény megkapja az aktuális eseményt (e = event), amelyben a pageX és pageY értékek határozzák meg a kurzor helyzetét.
Itt egy kis számolgatás, tologatás után egyszerűen frissítjük a tooltip elem left és top CSS tulajdonságait, ilyen egyszerű az egész.

A végeredmény a demo oldalon látható.

Bár a leírás nem volt a legszakszerűbb, de pont az a célja, hogy érthető legyen, és könnyen megjegyezhető. Remélem sokaknak tudtam segíteni vele … ;)

13 HOZZÁSZÓLÁS

  1. Valóban látványos, máshol is tudnék ilyesmi effekteket használni… akár egy menünek is érdekes lehet.

  2. Köszönöm, örülök hogy tetszik. Igen, menüknél is jól tud kinézni (láttam is valahol erről egy leírást, ott egy, az Apple főoldalán lévő headernav-hoz hasonló menüt csinált az illető).

  3. További jQuery, MooTools, Prototype vagy más framework leírásnak/tutorialnak én örülnék :)
    Sőt, akinek van rálátása a dologra, az csinálhatna egy összefoglalót, h melyiknek mi a +/-
    bár ez nem kis meló, mert annyi féle van, de szerintem a népszerűbbeket, egyszerűbbeket érdemes lenne.

  4. Jó cikk. Én pont most kezdtem ráállni a jquery-re. (Bár lehet, hogy a javascript-be kéne mélyebben beleásni magam OFF: tényleg, nem tud valaki egy jó, mélyebb szinttel is foglalkozó javascript könyvet/oldalt) ON: A leírás jó és könnyen érthető.

  5. Rengeteg javascript könyv van, elég csak rákeresni pl. Amazonon. van sokszor preview-lehetőség is, tehát meg tudod nézni a tartalomjegyzéket, bele tudsz olvasni a könyv egy részébe. Ha pedig megtetszik, akkor e-book formájában biztosan le lehet okoskodni valahogy a netről (bár én nem tudom, csak hallottam…).

    Ha pedig csak online tutorial formájában akarsz olvasgatni, akkor ajánlom figyelmedbe az alábbi oldalakat:
    http://tutorialzine.com/ (marha jó jquery és css tutorialok)
    http://net.tutsplus.com/ (ugyanez, csak több és változatosabb. itt videók is vannak…)

  6. Nekem valamiért nem sikerül megcsinálni :(

    a képet sikerül beillesztenem, minden frankó, de sajnos amozgás valahogy nem működik :( Esetleg letölthető valahol a projektfájl, hogy összetudjam hasonlítani?
    Köszielőre is a választ!

  7. Köszi, de próbáltam már így is, hogy onnan másolom be a kódot, de az ikonokat még mindig nem tudom mozgásra bírni :(

  8. Külső js fájlokat helyesen hívod meg?
    Az oldal javascript kódjában nincs elírás nálad? (Firebug, konzol, ott megjelennek az esetleges javascript hibák).
    Más baja nem lehet. Ha itt a demó működik, és ugyanazt a kódot használod, akkor nálad is működnie kell. márpedig itt működik.

HOZZÁSZÓLOK A CIKKHEZ

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