DropDown menü készítése jQuery-vel és a velejáró IE-fix
Ü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:
Az internet Explorerben elég érdeksen mutatott:
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ü:
-
<div class="menu-sor">
-
<div class="ddown-menu">
-
<div class="fomenu-ikon">
-
<a href="/beteg-vagyok-gyogyulni-akarok"><img src="/themes/nyitolap/images/segiteni_img.jpg" alt="" /></a>
-
</div>
-
<ul class="submenu">
-
<li><?php print l("Pozitív hozzáállás", "pozitiv-hozzaallas"); ?></li>
-
<li><?php print l("Gyógyító nevetés", "gyogyito-nevetes"); ?></li>
-
<li><?php print l("Függőségek", "fuggosegek"); ?></li>
-
<li><?php print l("Mozgásszervi betegségek", "mozgasszervi-betegsegek"); ?></li>
-
<li><?php print l("Orvosok, akik agykontrollt végeztek", "orvosok-akik-agykontrollt-vegeztek"); ?></li>
-
<li><?php print l("Kiadványok gyógyulni vágyóknak", "kiadvanyok-gyogyulni-vagyoknak"); ?></li>
-
</ul>
-
</div>
-
<div class="fomenu">
-
<p><a href="/beteg-vagyok-gyogyulni-akarok">Beteg vagyok és gyógyulni akarok</a></p>
-
</div>
-
<div class="clear"></div>
-
</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
-
<li><?php print l("Pozitív hozzáállás", "pozitiv-hozzaallas"); ?></li>
Sorok nyugodtan lecserélhetőek síma HTML elemekre:
-
<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:
-
<style type="text/css">
-
ul.submenu {
-
position: absolute;
-
display: inline;
-
z-index: 99;
-
border: 5px solid #962ab2;
-
display: none;
-
margin-left: 65px;
-
margin-top: 0;
-
width: 250px;
-
margin-bottom: 0;
-
}
-
ul.submenu li {
-
margin: 0;
-
padding: 0;
-
width: 250px;
-
}
-
ul.submenu li a {
-
font-size: 10pt;
-
display: block;
-
color: #409066;
-
background: #fdf3fd;
-
padding: 5px 20px;
-
border-bottom: 1px solid #962ab2;
-
-
margin: 0;
-
width: 210px;
-
line-height: 14pt;
-
}
-
ul.submenu li a:hover {
-
background: white;
-
text-decoration: none;
-
}
-
div.ddown-menu {
-
width: 70px;
-
float: left;
-
}
-
div.ddown-menu div.fomenu-ikon {
-
width: 70px;
-
}
-
div.fomenu {
-
width: 250px;
-
float: left;
-
}
-
div.fomenu p {
-
padding-left: 10px;
-
padding-top: 5px;
-
}
-
div.menu-sor {
-
padding-top: 10px;
-
}
-
div.clear {
-
clear: both;
-
}
-
</style>
Itt volt egy-két érdekesség, amit mindenképpen szeretnék megmelíteni!
Az ul.submenu css definícióban fontos elemek:
-
position: absolute;
-
display: inline;
-
z-index: 99;
-
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:
-
<!–[if lte IE 7]>
-
margin-left: -5px;
-
<![endif]–>
De sajnos ez nem reagált semmit, úgyhogy megoldottam ezt is JavaScript-el:
-
<script type="text/javascript">
-
$(function() {
-
if ($.browser.msie) {
-
$('ul.submenu').css("margin-left", "-5px");
-
}
-
});
-
</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:
-
<script type="text/javascript">
-
$(function() {
-
var submenu_active = false;
-
$(".ddown-menu").hover(
-
function() {
-
$("ul.submenu", $(this)).show();
-
$("ul.submenu", $(this)).hover(
-
function() {
-
submenu_active = true;
-
},
-
function() {
-
$(this).hide();
-
submenu_active = false;
-
});
-
},
-
function() {
-
if (!submenu_active) {
-
$("ul.submenu", $(this)).hide();
-
}
-
}
-
);
-
});
-
</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.
