Ez egy Kecs.es blog webfejlesztési ötletek, tanácsok, észrevételek

1jan/120

IE6 float és a margin bug

Tudom, hogy az IE6 halott és már el is temették. Sőt a jelenlegi kereskedelmi honlapokon amelyeket üzemeltetünk az IE6 előfordulása aránya kisebb mint 1%, de akkor is előfordulhat, hogy valaki egy olyan speciális környezetre kell, hogy optimalizáljon ahol még mindig IE6 a menő.

Ha ilyennel feladattal találkozol, akkor ez a post igen hasznos lesz számodra. Ismeretes ugyanis, ha IE6 alatt egy elemet float:left tulajdonsággal látunk el, akkor valami miatt a margint megduplázza a böngésző. Ezt nevezzük IE6 floating bug-nak. Ennek kivédésére a régebbi és általam ismert módszer az IE6-ra optimalizált CSS volt (minden úsztatott elem margin értéke az eredeti fele), azaz feltételhez kötött stíluslapot használtunk:

<!--[if IE 6]>
<style type="text/css" rel="stylesheet" media="screen" href="theme.ie6.css" />
<![endif]-->

Ezzel szemben ma egy új és sokkal egyszerűbb megoldást találtam. Egyszerűn az úsztatandó elemnek meg kell adni, hogy innentől legyen inline elem. A modern böngészőkben ennek semmi hatása, viszont IE6 esetén megjavítja a box modellt!
.float {
  float: left;
  display: inline;
}

1jan/120

PHP osztályok egységtesztelése

A weblabor oldalán találtam a következő cikksorozatot, ami szerintem igen hasznos. A PHP osztályok egységteszteléséről szól. Ez egy fontos és kicsit elhanyagolt témakör, így gondoltam megosztom itt is. Hátha sokkal jobban elterjed.

A cikket nem írom le újra, mert jelenleg semmivel sem tudnám kibővíteni az írást. Így most csak meghivatkozom a leírásokat, remélve, hogy a weblaborral nem történik semmi és a cikk megmarad nagyon sokáig a jelenlegi helyén.

http://weblabor.hu/cikkek/php-osztalyok-egysegtesztelese

http://weblabor.hu/cikkek/php-osztalyok-egysegtesztelese-2

30dec/112

Külső linkek mindig új ablakban nyíljanak meg

A jelenlegi postom arról szól ami a címe :) Egy weboldalon elég sok link lehet, ezeket két kategóriába sorolhatjuk: belső és külső linkek. A belső linkeket nem kellene piszkálni, hiszen azok úgy jók ahogy vannak. Viszont a külső oldalakra mutató linkek általában elviszik a látogatót a mi honlapunkról, mert ugyan abban az ablakban halad a látogató tovább. Ez nem biztos hogy mindig szerencsés. Talán jobb megoldás ha a látogató marad a mi honlapunkon és minden külső link amit mi biztosítunk, az egy új lapban jelenik meg a böngészőjében. Így ha a külső oldalt megtekintette és bezárta, akkor a mi honlapunk már várja is szeretettel.

Most mindenki mondhatja jó oké ezt ismerjük... Nem nagy újdonság... csak target="blank" és kész is. Természetesen igazatok is lenne, akkor ha nem arról lenne szó, hogy portolj egy weboldal 200-300 belső lappal, amelyeken átlagban 2 külső link található. Megnézném ki szeretne közel 4-600 linket egyesével átírni, mert elég unalmas egy munka lenne.

Ehhez egy gyors és univerzális megoldást nyújt a következő jQuery alapú JavaScript. A megoldást természetesen bármikor lehet natív JS-re portolni, de mivel az oldalon a jQuery adott volt, így a szkript megírása is kényelmesebb volt.

 
function getDomain(url) {
       if( url.substr(0, 7).toLowerCase() == "http://" )  { url = url.substr(7); }
  else if( url.substr(0, 8).toLowerCase() == "https://" ) { url = url.substr(8); }
  return url.substr(0, url.indexOf("/"));
}

$(document).ready(function(){
  var url = getDomain(top.location.href);
  $("a").each(function(){
    var link = getDomain($(this).attr("href"));
    if( url != link ) {
      $(this).attr("target","_blank");
    }
  });
});

30dec/110

Kitörésmentes iFrame használat

Tudom, mindenki elítéli a Frame-ek használatát - sőt én is - de néha nincs mit tenni, használni kell. Esetleg nincs más alternatíva, ha csak statikus tárhellyel rendelkezünk.

Remélem mindenkinek ismeretes a frame-es oldalak problematikája, miszerint könnyedén ki lehet törni a keretes oldalból. Azaz csak egy része töltődik be a weboldalnak. Ez a leggyakrabban a keresőkből érkező fogalomkor történik meg, amikor a kereső csak az egyik keret tartalmát indexeli. Így a hivatkozást oda irányítja. De ekkor a weboldal nem töltődik be a keret köré. A következő szkript ezen szeretne segíteni, ugyanis érzékeli ha egy frame hívódott meg közvetlenül, nem pedig a teljes weboldal. Ha ilyen helyzet állna elő, akkor a frame magára húzza a weboldal teljes vázát!

Nézzük a konkrét példát:

  • index.html (a teljes weboldal)
  • menu.html (egy iFrame keret az index.html-ben)
  • banner.html (egy iFrame keret az index.html-ben)

A weboldal teljesen jól működik ameddig az index.html -ből nézzük, de amint a banner.html vagy menu.html oldalakat töltjük be, csak a keret tartalma jelenik meg, nem pedig a teljes weboldal (ami az index.html lenne)

Megoldás:

Javasolt egy frameprotect.js állomány létrehozása, de akár a központi JS gyűjteménybe is behelyezhető. A lényeg, hogy ezt a kódot csak a Keretekbe ágyazott lapokban (a példában menu.html és banner.html) kell meghívni lehetőleg a <body onload="frameprotect();"> eseményében.

function frameprotect() {
  if( window.location == top.location )
  { top.location.href = "index.html"; }
}

14szept/090

Adatbázis optimalizálása

Azok akik elég nagy táblákkal dolgoznak, sokszor megesik, hogy optimalizálniuk kell az adatbázisukat. Erre most mutatok egy nagyon egyszerű lehetőséget, melyet akár a programba is ágyazhatunk, és magától futhat cron segítségével. vagy egy kézzel készített poor-man-cron megoldással:

function optimize_database($DATABASE_LINK)
{
  $result = mysql_query('SHOW TABLES',$DATABASE_LINK) 
            or die('Cannot get tables');
  while($table = mysql_fetch_row($result)) {
    mysql_query('OPTIMIZE TABLE '.$table[0],$DATABASE_LINK) 
    or die('Cannot optimize '.$table[0]);
  }
}

Értelmi szerzője: David Walsh

Tagged as: , No Comments
14szept/090

xHTML kimenet tömörítése

Mostanában sokat foglalkoztam honlapok optimalizációjával, nem csak SEO értelemben. Így futottam bele az YSlow FrieBug kiegészítése. Nézegettem az ajánlásait, s ezen új szemlélet megismerése kapcsán írok majd néhány scriptet. Nem tudom észrevettétek-e de már voltak hasonló gondolatok itt, csak azok átkerültek az Érdekes oldalak alá. Ott megtalálhatjátok, a JavaScript és CSS kompresszorokat.

Az első nem más, mint hogy hogyan érhetjük el nagyon egyszerűen, hogy a kimeneten fölösleges (whitespace) karakterek ne legyenek. Ezzel "tömörítve" az xHTML kódunkat. A most következő PHP kódunk lényege az, hogy egy kimeneti pufferbe begyűjti a teljes weblapot, majd amikor a kimenetet kiküldi, előtte meghív rá egy függvényt, ami a fölösleges karaktereket eltünteti.

Mivel ez a drágalátos WordPress nem enged mindenféle kódot beleírni egy postba, ezért a megoldást kénytelen vagyok linkelni... Az eredeti cikk ahonnan a forrás jött:

http://davidwalsh.name/compress-xhtml-page-output-php-output-buffers

Tagged as: , No Comments
9szept/090

TinyTable: adatok rendezése, megjelenítése a lehető legkönyebb módon

Régebben találtam egy 2.5Kb!!! méretű kompakt JavaScript kódot, mellyel nagyon gyorsan lehet adatokat rendezni. Egyetlen hátránya talán, hogy táblázat alapú, tehát a tableless szemléltet kicsit el kell dobni miatta, de nagyon sok munkát vesz le a vállunkról. Szerintem nem is pocsékolom tovább az időt, hanem nézzétek meg a demó oldalt, és utána leírom a használatát.

Előnyei:

  • nagyon kicsi javascript file
  • stabil rendezést biztosít akár 3000 rekord esetében is. (tapasztalatok alapján)
  • saját kontrollerekkel könnyen bővíthető
  • AJAX-al is vezérelhető

Ismert hibái:

  • Alapból nem kezeli a 2009-08-21 -es dátumformátumot (de ezt kijavítottam)
  • Alapból csak ASC rendezésben lehet inicializálni (de ezt kijavítottam, hogy DESC legyen)
  • Csak a jQuery legfrissebb (jelenlegi: 1.3.2-es) változatával kompatibilis
  • valamint a jQuery pngFix kiegészítőjének $("img[@src$=png]).pngfix(); metódusát nem hagyja érvényesülni. (csak az [@src$=png] résszel van baja)

De nézzük a használatát:

<!-- Head -->
<link rel="stylesheet" href="tinyTableStyle.css" />
<!-- /Head -->
<!-- body -->
<table cellpadding="0" cellspacing="0" border="0" id="table" class="sortable">
  <thead>
    <tr>
      <th class="nosort"><h3>ID</h3></th>
      <th><h3>Név</h3></th>
      <th><h3>E-mail</h3></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Ezekiel Hart</td>
      <td>(627) 536-4760</td>
    </tr>
  </tbody>
</table>
<div id="controls">
  <div id="perpage">
    <select onchange="sorter.size(this.value)">
      <option value="5">5</option>
      <option value="10">10</option>
      <option value="20" selected="selected">20</option>
      <option value="50">50</option>
      <option value="100">100</option>
    </select>
    <span>Elem oldalanként</span>
  </div>
  <div id="navigation">
    <img src="images/first.gif" width="16" height="16" alt="Első oldal" onclick="sorter.move(-1,true)" />
    <img src="images/previous.gif" width="16" height="16" alt="Előző oldal" onclick="sorter.move(-1)" />
    <img src="images/next.gif" width="16" height="16" alt="Következő oldal" onclick="sorter.move(1)" />
    <img src="images/last.gif" width="16" height="16" alt="Utolsó oldal" onclick="sorter.move(1,true)" />
  </div>
  <div id="text">altuális oldal: <span id="currentpage"></span> / összesen: <span id="pagelimit"></span></div>
</div>
<script type="text/javascript" src="tinyTableScript.js"></script>
<script type="text/javascript">
  var sorter = new TINY.table.sorter("sorter");
  sorter.sortmethod = "desc";
  sorter.head = "head";
  sorter.asc = "asc";
  sorter.desc = "desc";
  sorter.even = "evenrow";
  sorter.odd = "oddrow";
  sorter.evensel = "evenselected";
  sorter.oddsel = "oddselected";
  sorter.paginate = true;
  sorter.currentid = "currentpage";
  sorter.limitid = "pagelimit";
  sorter.init("table",1);
</script>

Magyarázat:

A table thead része lesz fejlécként felhasználva. A h3-as tagekkel van megoldva a címkék igazítása. Igazából kihagyható, csak akkor css-t is szerkeszteni kéne... Engem nem zavart, bent szoktam hagyni. Azon th oszlopok, melyek class-ja be van állítva nosort-ra azokat nem lehet majd rendezni (ez hasznos ha szerkesztő, vagy törlő gombokat helyezel el). A controls div tartalmazza a vezérlőket, (elem / oldal, hányadik oldalon, és lapozó eszközök). FONTOS, hogy a JS kód csak és kizárólag a HTML dokumentum végén szerepelhet, különben az inicializáló nem fog lefutni. De nézzük is meg mit kell megadni a JS-be: sorter.sortmethod = desc sor felelős azért hogy desc legyen a rendezés közvetlenül az init után (ez csak az én módosított kódommal működik). Az összes többi paraméter, csak azért kell, hogyha ezen nevek már használva vannak a projektedben akkor ezen kód ID-it át tudd írni, és azokat közölni lehessen az JS feldolgozóval. Az utolsó sor, az init még kimaradt, erről annyit kell tudni, hogy első paramétere a rendezendő tábla ID-je, a második meg, hogy hányadik oszloppal legyen rendezve automatikusan. És jó programozókhoz mérten az indexelés 0-tól indul :)

Linkek:

Fejlesztő oldala
Eredeti demó oldal
Eredeti kód letöltése
Általam módosított kód letöltése (dátumkezelés, desc init)

9szept/090

Az a fránya vertical-align az őrületbe kerget!!!

Tegnap szerettem volna egy szép megoldást találni arra a problémára, hogy van egy div, amibe szöveget fogok írni. A div mérete adott (35px magas és 200px széles). A probléma az, hogy a beleírt tartalmat szeretném mindenhogy középre igazítani. vízszintesen nincs is semmi gond. Ott van a text-align: center... De mi van ha függőlegesen szeretnénk valamit középre (szabbvány szerint: middle) igazítani? Hát azt értelmesen nem lehet...

Ugyanis valakinek az a nagyon okos ötlete támadt, hogy a vertical-align csak inline elemkre lehessen használni. Így egy blokk elemmel meg vagy lőve. Léteznek különböző css hack-ek, mint pl.: line-heigh értékét beállítjuk akkorára mint amekkora az őt tartalmazó div, de ez használhatatlan azonnal ha több sort kell beleírni. Vagy ott van a játék a display tulajdonsággal, hogy 3 divet használunk, és akkor kívülről befelé a display tulajdonságot table-re, table-row-ra, és végül table-cel-re állítjuk. De ez megint nem megy IE6 alatt... Szóval nem lesz böngészőfüggetlen...

Ha valaki olyan mint én, miszerint tableless megszállott, akkor nem szívesen használ table-t... de sajnos nincs más választásunk... ott van egyedül normálisan valign='middle' megoldva...

VAGY:
jQuery őrült is egyben mint én, és megoldja azzal. Igen tudom ez sem a legjobb megoldás, mert akinek nincs JAVAja... Az kapja be :D

JavaScript kód:

(function ($) {
  $.fn.vAlign = function(container){
    return this.each(function(i){
      if(container == null) {
        container = 'div';
      }
      //írd át ha kell (Ez az extra magassága a szülő objektumnak)
      var paddingPx = 10;
      $(this).html("<" + container + ">" + $(this).html() + "</" + container + ">");
      var el = $(this).children(container + ":first");
      //az új elem magassága
      var elh = $(el).height();
      //a szülő elem magassága
      var ph = $(this).height();
      if(elh > ph) {
        //Ha az új elem magasabb mint a szülő akkor átméretezi
        $(this).height(elh + paddingPx);
        ph = elh + paddingPx;
      }
      var nh = (ph - elh) / 2; 
      //Új margint beállítja
      $(el).css('margin-top', nh);
    });
  };
})(jQuery);

És a használata:

$(document).ready(function(){
  $("p.special").vAlign();
  //A diven belűl létrehoz egy p elemet
  $("div.info").vAlign("p");
  //A diven belűl létrehoz egy span elemet
  $("p.warn").vAlign("span");
  //És használható további fv is utána :)
  $("p.warn").vAlign().css("color","red");
});

Forrás oldal: http://cool-javascripts.com/
Demó oldal: http://demos.cool-javascripts.com/

30aug/090

Ajax és a SEO – Avagy ellenségből barát

Ebben a postomban Verő Boglárka és David Walsh irományát párosítom össze, a magam szájíze szerint.
A kiindulási koncepció ugye az, hogy egy normális tartalmat a kereső robotok minden gond nélkül látják, és fel is tudnak dolgozni. Viszont mi van abban esetben, ha lapunk tele van AJAX kérésekkel? Gondolom sokan tudjátok, hogy a keresők nagy száma nem is törődik a javascriptekkel. Gyakorlatilag figyelmen kívül hagyja, észre sem veszi. Nem hogy lefuttassa őket. (De ebbe most bővebben nem mennék bele részletesebben, mert a Google néhány speciális esetben képes javascriptbe-be ágyazott linkek követésére. Állításom forrása megtalálható Longhard egyik cikkében.) Tehát azon lapok, vagy postok, hozzászólások, vagy képek de végül is legyen bármi, ami AJAX-al töltődik be a botok számára nem is léteznek. De mit tudunk olyan esetben tenni, ha nekünk mégis szükségünk van arra hogy az így betöltött tartalom is elérhető legyen a keresők, és robotok számára? Nem kell hosszasan gondolkozni! Csak nem a beidegződéseket kell követni, hanem kicsit robot fejjel gondolkodni.

Egy hagyományos AJAX request, melyet nem tud értelmezni a keresőrobot:

<a href="javascript:q(2);">
  További hozzászólások megmutatása
</a>

És ennek módosítása mellyel már elboldogul:

<a onclick="javascript:q(2); return false;" href="forum.php?q=2">
  További hozzászólások megmutatása
</a>

Elemezzük is ki, mi ennek az oka. Mint mondottam, a javascriptet figyelmen kívül hagyják. De a második esetben, a href tagot tudja követni a robot, mert az egy számára is értelmezhető url, mely indexelhető tartalmat fog neki adni. De a felhasználó is megkapja a neki szánt élményt, mert at onclick esemény lefut, így meghívódik az AJAX request, de a return false biztosítja majd számunkra, hogy a "normális link" ne működjön. Különben ezzel a megoldással két legyet üt egyszerre a webmester mert nem csak a kereső számára lesz olvasható a tartalom, hanem azon látogatóknak is, akiknek nincs, vagy éppen letiltották a javascript futtatását.

Ezen módosítás után nekünk fejlesztőknek nincs más dolgunk mint megfelelő választ adni az AJAX és normál (GET) kéréseknek. Hiszen egy AJAX kérésnek elég csak kommenteket átadnunk, míg normál kérés esetén a teljes weblapot újra elő kell állítanunk.

Lehet az egyszerű megoldás használni, (a példában használt) forum.php feldolgozza a normál kéréseket, míg a forum.ajax.php kezeli az AJAX kéréseket, ahogy egy jóbarátomtól tanultam. Bár ez a módszer azért nem nyerte el a tetszésemet, mert ha sok-sok AJAX kérés lesz, akkor minden fájlból 2 verzió lesz, és egy idő után már összefolynak a fájlnevek az FTP-n.

Vagy egy paramétert felhasználni csak azért hogy a kérés AJAX-e vagy sem, de így mindig egy változót kell átadni, melyre figyelni kell hogy nehogy elfelejtsük használni. Így ez még mindig nem nyerte el a tetszésemet.

A legjobb megoldás szerintem amit ez a David Walsh gyerek kitalált. A következő PHP kóddal szerveroldalon detektálni lehet hogy AJAX kérés futott-e le vagy normál request.

$ajax = $_SERVER['HTTP_X_REQUESTED_WITH'];
if( !empty($ajax) && strtolower($ajax) == 'xmlhttprequest') {
  //AJAX kérés futott le
} else {
  //normál kérés futott le
}

Hiába nekem ez tetszik a legjobban, ennek is van hátulütője. Nem minden szerver támogatja, így ha használja valaki előbb ellenőrizze, hogy a $_SERVER['HTTP_X_REQUESTED_WITH'] változó számára elérhető-e!

Tagged as: , , No Comments
28aug/090

Link megnyitása új ablakban valid xHTML kód mellett

Mint gondolom sokan észrevettétek, az xHTML 1.x szabványból a W3C kihagyta az anchor tagok target paramétert. Így lehetetlenné vált olyan szabványos xHTML kódot készíteni amiben a linkek új ablakban nyílnak meg. Jelenlegi írásom ezt hivatott kijavítani.

A megoldáshoz jQuery-t használok majd, és így elég gyorsan és könnyen meg lehet oldani.

A javascript amire szükségünk van:

  <script type="text/javascript">
    $(document).ready(function(){
      $('a.out').each(function(){
        $(this).attr({ 
          target: "_blank"
        });
      });
    });
  </script>

Továbbá azon linkeket melyeket új ablakban szeretnénk megnyitni, már csak egy class="out" paraméterrel kell ellátnunk.

  <a href="domain.tld" class="out">domain.tld</a>

Majd a kódunk eredménye látható is az oldal betöltése után:

  <a href="domain.tld" class="out" target="_blank">domain.tld</a>

Ezzel a pici trükkel a böngészők értesülnek arról, hogy azt szeretné a webfejlesztő, hogy a link úja ablakban nyíljon meg, s ennek eleget is tesznek. S a kód is valid lesz, a módosítás utólagos, melyet egyetlen validátor sem ellenőriz, hiszen a javascripteket nem futtatják le.