Archive for the ‘Böngésző fix’ Category

Észrevehetjük, hogy az Internet Explorer régebbi verziói nem tudják támogatni a PNG fájlokat. A jelenség az, hogy nem kezeli az átlátszóságukat, és ez elég nagy probléma mivel (sajnos) a mai napig is a felhasználók legnagyobb része IE6-ot használ.

Szerencsére erre is van megoldás, nem is bonyolult, nem is sok idő megoldani.

Mindösszesen három fájlra lesz szükségünk:

Az első css fájlt a Conditional Comment feltételes megoldással kell beilleszteni a weboldalunkba (Drupal CMS esetén a page.tpl.php fájlba):

  1. <!–[if lt IE 7]>
  2.   <link rel="stylesheet" href="http://www.kalman-hosszu.com/ie-fix/ie.css" type="text/css" media="screen" />
  3. <![endif]–>

Ezzel elérjük azt, hogy az IE7 előtt böngészőknél hozzáadja az oldalhoz az ie.css fájlt is.

Ha megnézzük ennek a css fájlnak a tartalmát akkor láthatjuk, hogy hova kell elhelyezni a többi fájlt:

  1. img {
  2.   behavior: url(/images/png.htc);
  3. }

Tehát az itt megadott könyvtárba (esetemben /images) elhelyezzük a png.htc és a transparent.gif fájlokat, és IE alatt is használhatunk PNG képeket.

Létezik egy jQuery fgv: show(). Ennek az a szerepe, hogy a nem látható html elemet láthatóvá teszi.

Tehát végülis annyi történik, hogy egy html elemet ami el van rejtve (display: none;) megmutat, mégpedig úgy, hogy inline css-sel ad neki egy display: block tulajdonságot.

Ez így rendben is lenne, ha nem akarnánk táblázatok soraira is alkalmazni (table tr). A probléma az, hogy pl. a Firefox szétcsúszik, ha a sor elemre vonatkozó css display: block. Erre a megoldás a display: table-row css definíció. Ezzel viszont az a gond, hogy az IE nem támogatja. Az IE viszont kezeli a táblázat soraira is a display: block tulajdonságot.

Nem értem miért nem építették bele a jQuery-be a böngésző ellenőrzését a show() fgv. meghívása esetében, de akkor vegyük figyelembe magunk, hiszen nem mindegy, hogy a táblázatunk így néz ki:

FF tr elem display: block

Vagy így:

FF tr elem display: table-row

Láthatjuk, hogy az első esetben a táblázat első oszlopa sokszorosára nőtt, ezért az oldal szétcsúszott.

JS-ből lekérdezni a böngésző típusát, nem nehéz, és a jQuery-be is beépített (core).

A következő kódot aztán símán beépíthetjük egy saját fgv-be.

  1. <script type="text/javascript">
  2. function show_tr_element(object) {
  3.   if ($.browser.msie) {
  4.     object.show();
  5.   } else {
  6.     object.css("display", "table-row");
  7.   }
  8. }
  9. </script>

Ü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.