Archive for November, 2008

Ügyfelünk kérése alapján el kellett készítenünk egy DropDown menüt a nyitólapjára. Most is - mint általában - a jQuery JavaScript könyvtárban kerestem a megoldást. Rövid keresgélés után megtaláltam a Superfish jQuery plugin-t, mely tökletesen megfelelőnek tűnt a célra…legalábbis első ránézésre.

A probléma a tesztelés során jelentkezett, mégpedig a szokásos IE6/IE7/FF kompatibilitási ellentétek keretében.
Mondanom sem kell, hogy a plugin FF alatt teljesen jól teljesített (ugyanúgy mint Safari-n vagy Opera-n), a Microsoft két böngészőjénél az oldal gyakorlatilag összeomlott.

A menü FF-ban:

DropDown menü FF

Az internet Explorerben elég érdeksen mutatott:

DropDown menü IE
DropDown menü IE
DropDown menü IE

Először úgy gondoltam megkeresem a megoldást, mert biztosan lokális gond van, hiszen az oldalon található bemutatókon nincs gond Internet Explorer alatt sem, de akárhogy csürtem csavartam nem akart működni. Nem csak a kinézettel volt összeakadás, hanem a funkcionalitás sem működött. IE alatt egyszerüen eltünt a DropDown menü amikor elhagytam az egérrel a legfelső meüelemet.

Néhány órányi küszködés után úgy felidegesítettem magam, hogy eldöntöttem inkább írok egy sajátot, hiszen nem egy atomfizika a DropDown menü, főleg a jQuery-t használva.

Nézzük meg, először a HTML osztályokat, az elrendezési szabályokat!

Íme egy főmeü, és a hozzá tartozó DropDown menü:

  1. <div class="menu-sor">
  2.   <div class="ddown-menu">
  3.       <div class="fomenu-ikon">
  4.         <a href="/beteg-vagyok-gyogyulni-akarok"><img src="/themes/nyitolap/images/segiteni_img.jpg" alt="" /></a>
  5.       </div>
  6.       <ul class="submenu">
  7.         <li><?php print l("Pozitív hozzáállás", "pozitiv-hozzaallas"); ?></li>
  8.         <li><?php print l("Gyógyító nevetés", "gyogyito-nevetes"); ?></li>
  9.         <li><?php print l("Függőségek", "fuggosegek"); ?></li>
  10.         <li><?php print l("Mozgásszervi betegségek", "mozgasszervi-betegsegek"); ?></li>
  11.         <li><?php print l("Orvosok, akik agykontrollt végeztek", "orvosok-akik-agykontrollt-vegeztek"); ?></li>
  12.         <li><?php print l("Kiadványok gyógyulni vágyóknak", "kiadvanyok-gyogyulni-vagyoknak"); ?></li>
  13.       </ul>
  14.   </div>
  15.   <div class="fomenu">
  16.     <p><a href="/beteg-vagyok-gyogyulni-akarok">Beteg vagyok és gyógyulni akarok</a></p>
  17.   </div>
  18.   <div class="clear"></div>
  19. </div>

Az l() fgv. használata ne tévesszen meg senkit sem, ez egy beépített Drupal fgv., síma link generálódik belőle.
Tehát a

  1. <li><?php print l("Pozitív hozzáállás", "pozitiv-hozzaallas"); ?></li>

Sorok nyugodtan lecserélhetőek síma HTML elemekre:

  1. <li><a href="/valamilyen-tartalom">Tartalom címe</a></li>

Nézzük meg a css-t, hogy ki is nézzen valahogy, nameg azért vannak benne fontos részek:

  1. <style type="text/css">
  2. ul.submenu {
  3.   position: absolute;
  4.   display: inline;
  5.   z-index: 99;
  6.   border: 5px solid #962ab2;
  7.   display: none;
  8.   margin-left: 65px;
  9.   margin-top: 0;
  10.   width: 250px;
  11.   margin-bottom: 0;
  12. }
  13. ul.submenu li {
  14.   margin: 0;
  15.   padding: 0;
  16.   width: 250px;
  17. }
  18. ul.submenu li a {
  19.   font-size: 10pt;
  20.   display: block;
  21.   color: #409066;
  22.   background: #fdf3fd;
  23.   padding: 5px 20px;
  24.   border-bottom: 1px solid #962ab2;
  25.  
  26.   margin: 0;
  27.   width: 210px;
  28.   line-height: 14pt;
  29. }
  30. ul.submenu li a:hover {
  31.   background: white;
  32.   text-decoration: none;
  33. }
  34. div.ddown-menu {
  35.   width: 70px;
  36.   float: left;
  37. }
  38. div.ddown-menu div.fomenu-ikon {
  39.   width: 70px;
  40. }
  41. div.fomenu {
  42.   width: 250px;
  43.   float: left;
  44. }
  45. div.fomenu p {
  46.   padding-left: 10px;
  47.   padding-top: 5px;
  48. }
  49. div.menu-sor {
  50.   padding-top: 10px;
  51. }
  52. div.clear {
  53.   clear: both;
  54. }
  55. </style>

Itt volt egy-két érdekesség, amit mindenképpen szeretnék megmelíteni!

Az ul.submenu css definícióban fontos elemek:

  1.   position: absolute;
  2.   display: inline;
  3.   z-index: 99;
  4.   width: 250px;

Az első három nélkül az oldal IE-ben szétcsúszik, a szélesség megadása nélkül pedig IE6-ban csak 70px lesz a lehullómenü szélessége.

Az “ul.submenu” és az “ul.submenu li a” css definíciónál is nagyon fontos a szélesség megadása, mert különben IE6-ban eltűnik a DropDown menü ha az első elemet elhagyjuk (tehát nem tudjuk kivűlasztani mondjuk a második, vagy harmadik elemet a mnüből).
Az a (link) elemnél nyiván a paddingot kivonjuk a szélességből, ezért lesz 40px-el kevesebb.

A harmadik dolog amire figyelni kell az, hogy mindenhol megadtam a margin-bottom értékét, mégpedig 0-nak. Ez is fontos, különben IE6 alatt nagy alsó margót rak minden menüelem alá.

Végül, mint IE6 mint IE7 alatt nem volt megfelelő az “ul.submenu” bal oldali margó értéke (65px), ezért teljesen kiment a DropDown menü a jobb oldalra. Erre a Conditional comments megoldással probálkoztam, vagyis:

  1. <!–[if lte IE 7]>
  2.   margin-left: -5px;
  3. <![endif]–>

De sajnos ez nem reagált semmit, úgyhogy megoldottam ezt is JavaScript-el:

  1. <script type="text/javascript">
  2. $(function() {
  3.   if ($.browser.msie) {
  4.     $('ul.submenu').css("margin-left", "-5px");
  5.   }
  6. });
  7. </script>

Nézzük meg végül a lényeget, a HTML-hez tarotó jQuery kódot, amiben kivitelezzük a DropDown menüt:

  1. <script type="text/javascript">
  2. $(function() {
  3.   var submenu_active = false;
  4.   $(".ddown-menu").hover(
  5.   function() {
  6.     $("ul.submenu", $(this)).show();
  7.     $("ul.submenu", $(this)).hover(
  8.     function() {
  9.       submenu_active = true;
  10.     },
  11.     function() {
  12.       $(this).hide();
  13.       submenu_active = false;
  14.     });
  15.   },
  16.   function() {
  17.     if (!submenu_active) {
  18.       $("ul.submenu", $(this)).hide();
  19.     }
  20.   }
  21.   );
  22. });
  23. </script>

Mit is csinál?

Az oldal betöltődése után létrehoz egy bool tipusú változót, melyben a DropDown menü aktivitását figyeljük, majd végigmegy az összes ddown-menu osztályon, és figyeli a hover esemény.
Amikor bekövetkezik, a hozzá tartozó submenu osztályt előhozza (show), majd ennek a megjelenített menünek figyeli a hover eseményét.
Ha bekövetkezik, akkor a submenu_active változó értéke igaz lesz, hiszen éppen a menüben vagyunk, ha pedig elhagyjuk, akkor elrejtjük, és a submenu_active értékét hamisra állítjuk.
Végül megnézzük, hogy a ddown-menu osztályba tartozó elemek hover eseményének végén a submenu_active igaz-e, és ha nem akkor a DropDown listát eltávolítjuk. Erre azért van szükség, mert olyan szituáció is elképzelhető, hogy valaki nem lép be a submenu-be, csak előhozza. Ha ez a sor kimaradna, akkor ilyen esetekben a sumenu nem tunne el.