Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

Autor wpisu: batman, dodany: 23.02.2011 08:00, tagi: jquery

Pluginów jQuery nigdy dosyć. Tym razem natrafiłem na plugin o bardzo wymownej nazwie – Easy Image Zoom, czyli “fajna powiększarka obrazków”. Co jest w niej takiego fajnego? Wyjątkowa prostota użycia i interesujący efekt końcowy.

Opis pluginu znajdziecie na stronie http://cssglobe.com/post/9711/jquery-plugin-easy-image-zoom, a demo pod adresem http://cssglobe.com/lab/easyzoom/easyzoom.html.

Miłej zabawy.

Autor wpisu: batman, dodany: 21.02.2011 08:00, tagi: css

Wokół najnowszej przeglądarki Microsoftu nagromadziło się wiele mitów i legend. Niektórzy powiadają, że jak chłop zainstaluje tę przeglądarkę u siebie na komputerze, to krowy przestaną mu mleko dawać, ptactwo zdechnie, a córka zostanie starą panną. Ponieważ premiera finalnej wersji IE9 jest tuż tuż, warto przyjrzeć się dokładniej możliwościom przez nią oferowanym. Odrobina czasu poświęconego na sprawdzenie co w trawie piszczy, pozwoli nam zaoszczędzić jego wielokrotność w przyszłości.

Najnowsze wydanie Internet Explorera przenosi przeglądarkę ze średniowiecza do czasów współczesnych. Zarówno pod względem wyglądu jak i implementacji obowiązujących standardów. Samo działanie przeglądarki również zostało znacznie usprawnione i w przeciwieństwie do IE8, który sprawiał wrażenie, że dobrze działa, IE9 nie sprawia takiego wrażania. IE9 po prostu dobrze działa.

Czego zatem możemy spodziewać się po IE9? Z najbardziej brakujących funkcjonalności, które zostały wprowadzone, można wymienić:

  • zaokrąglone rogi dzięki CSS
  • obsługa RGBA
  • obsługa przeźroczystości (opacity)
  • transformacje CSS
  • obsługa selektorów CSS3

Na fali rosnącej popularności HTML5, IE9 został uzbrojony w:

  • obsługę znacznika canvas
  • obsługę znaczników audio oraz wideo
  • obsługę SVG
  • obsługę geolokalizacji

Do tego wszystkiego należy dodać jeszcze rewelacyjne narzędzia deweloperskie, które niewiele ustępują liderowi w tej dziedzinie Firebugowi, a czasami nawet go wyprzedzają.

Z “miękkich” dodatków warto znać Pinned Sites, czyli mechanizm pozwalający na przypinanie konkretnych zakładek do paska zadań. Tak przypięta zakładka ma możliwość korzystania z Jump List oraz w ograniczonym zakresie zmieniać ikonę na pasku zadań.

A co z naszą prywatnością i wszędobylskimi reklamami? Tutaj dostaliśmy do dyspozycji narzędzie o wszystko mówiącej nazwie – Ochrona przed śledzeniem. Działa ono na zasadzie list dozwolonych i zablokowanych elementów. Wprawdzie nie jest ono tak wygodne w użyciu jak AdBlock znany z Firefoxa, niemniej zadanie swoje spełnia.

Niestety Internet Explorer 9 nie doczekał się sprawdzania pisowni oraz rozszerzeń. Nie są to może najpoważniejsze wady tej przeglądarki, ale skutecznie zniechęcają do przesiadki. Pozostaje jedynie mieć nadzieję, że w końcu się pojawią.

Jeśli chcielibyście dokładniej zapoznać się ze zmianami, polecam:

Autor wpisu: batman, dodany: 19.02.2011 08:00, tagi: css, javascript, php, jquery

Czym jest cheet sheat raczej tłumaczyć nie trzeba. Niejednokrotnie zerkałem na tablicę korkową/ścianę karton-gips naszpikowaną licznymi zadrukowanymi kartkami w celu znalezienia tej jednej jedynej, zawierającej odpowiedź na moje pytanie. Ściągawki są szybsze nawet od Google – zawsze pod ręką, nie wymagają do działa dostępu do Internetu (bez prądu też doskonale sobie radzą), zazwyczaj wystarczy rzut oka, by znaleźć rozwiązanie problemu.

Kilka dni temu Wookieb podesłał do mnie linka prowadzącego do strony zatytułowanej 100 + Must Have Cheat Sheets and Quick References For Web Designers and Developers. Nazwa mówi sama za siebie. Setka (a nawet więcej) obowiązkowych ściągawek, bez których żywot developera to droga przez mękę.

Nie przejrzałem wszystkich ściągawek, jednak po sprawdzeniu kilku najbardziej mnie interesujących, śmiało mogę napisać, iż tytuł nie został napisany na wyrost.

Co ciekawego znajdziemy na ściągawkach? Oto lista najciekawszych zagadnień:

  • CSS3
  • HTML5
  • WordPress
  • PHP
  • jQuery
  • czcionki
  • Adobe AIR

Miłej lektury.

Autor wpisu: sokzzuka, dodany: 18.02.2011 13:43, tagi: javascript, php

Jedną z największych zalet jak i wad Javascriptu jest jego ogromna elastyczność i prostota. Dlaczego zalet jak i wad ? Dzięki elastyczności możemy więcej. Jednak z drugiej strony, możliwość rozwiązania jakiegoś problemu na kilka sposobów zmniejsza rozumienie kodu. Prostota i unifikacja JS wokół konceptu funkcji z jednej strony umożliwia wykorzystanie jednego mechanizmu enkapsulacji w wielu kontekstach. Natomiast z drugiej jest przez wielu nierozumiana, zwłaszcza przez osoby przyzwyczajone do języków gdzie występuje wiele słów kluczowych, przy pomocy których owy mechanizm jest realizowany. Elastyczność JS pozwala nam na takie zabawy, jak implementację własnego modelu obiektowego w efektywny sposób. Jakie cechy JS wspomagają ten proces ?

  1. Obiekty anonimowe
  2. Funkcja ‘__noSuchMethod__’ (odpowiednik __call w php)
  3. Funkcje anonimowe i domknięcia leksykalne

Tak na prawdę, przy pomocy JS można zaimplementować dowolną odmianę modelu obiektowego, który znajduję się w innych językach. Zarówno modele oparte na klasach, metaklasach, ich wariacje jak i na prototypach – które są wbudowane w JS. W tym artykule, który ma charakter badawczo – eksperymentalny chciałbym po pierwsze przedstawić model obiektowy jaki wymyśliłem, a po drugie jego implementację przy użyciu ww. listy cech języka. Mam nadzieje, że artykuł was zainteresuje oraz zainspiruje do podobnych eksperymentów :) .

Skoro wiemy już jakiś środków użyjemy, należałoby postawić pytanie – co chcemy osiągnąć ?

Model obiektowy, który chciałbym zaimplementować będzie starał naśladować rzeczywistość. Założenia:

  1. Obiekty tworzone są w fabrykach
  2. Fabryki tworzą obiekty poprzez komponowanie ich z różnych elementów wg. planów / foremek
  3. Foremki są z natury niezmienne, ale można komponować z ich elementów nowe wzory wg uznania (można w ten sposób zaimplementować coś o funkcjonalności wielodziedzieczenia)
  4. Każdy obiekt po opuszczeniu fabryki żyje własnym życiem i przez swój cykl istnienia może diametralnie się zmienić w stosunku do swojego wzorca

Myślę, że założenia są dość logiczne i odzwierciedlają cykl jaki przechodzą właściwie wszystkie realnie istniejące obiekty na naszej planecie. Żeby nie być gołosłownym podam najbardziej oczywisty przykład – Samochód.

  1. Samochód jest tworzony w fabryce
  2. Fabryka tworzy samochód poprzez komponowanie go z różnych elementów (silnik, koła, skrzynia etc) wg projektu.
  3. Projekt samochodu jest raczej niezmienny, a jeżeli coś jest zmieniane to nazywa się to nowym modelem
  4. Samochód po opuszczeniu fabryki może trafić w ręce różnych ciekawych ludzi którzy np. poddadzą go wiejskiemu tuningowi, wtedy na 100% nie będzie  wyglądał tak jak go projektant narysował :)

Czas na kod! Na początek – plan/foremka/template:


var fooTemplate = {
    state: {
        foo: {
            value: 1
        }
    },
    behavior: {
        incrementFoo: {
            scope: 'public',
            value: function(self){
                self.state.foo++
                console.log (self.state.foo, 'incrementFoo');
            }
        },
        decrementFoo: {
            scope: 'internal',
            value: function(self){
                self.state.foo--;
                console.log (self.state.foo);
            }
        }
    }
}

Template został zadeklarowany jako anonimowy obiekt przypisany do zmiennej „fooTemplate”. Wewnątrz niego trzymamy metadane dotyczące tego jak skonstruować działające „coś”. Zmienne oznaczone są jako „state”, natomiast metody jako „behavior”. Każdy element z oprócz domyślnej wartości (value) posiada różne adnotacje. Zakładam, że wszystkie zmienne obiektu są prywatne. Natomiast metody, mogą być publiczne, albo prywatne (odpowiednio public i internal). Oczywiście można dodać różne inne adnotacje wzorem tych z Javy albo C#. Każda metoda jako pierwszy argument przyjmuje „self” – wewnętrzną referencję do obiektu, odpowiednik „this”.

Kolejnym rzeczą jaka będzie nam potrzebna to fabryka obiektów, która będzie wiedziała jak z template’u stworzyć obiekt. Dla takiego rodzaju template’u, jak wyżej zaprezentowany stworzyłem fabrykę w postaci funkcji „genericFactory”:


function genericFactory(template){
    var self = {
        state: {},
        behavior: {
            'public': {},
            'internal': {}
        }
    };

    for(var i in template.state){
        self.state[i] = template.state[i].value
    }

    for(var i in template.behavior){
        if(template.behavior[i].scope == 'public'){
            self.behavior['public'][i] = template.behavior[i]['value']
        } else {
            self.behavior['internal'][i] = template.behavior[i]['value']
        }
    }

    function obj(){

        this.__noSuchMethod__ = function __noSuchMethod__(id, args){
            if(self.behavior['public'][id] != undefined){
                args.unshift(self);
                return self.behavior['public'][id].apply(this, args);
            }
            throw 'No such method!'
        }
    }
    return new obj;
}

Przetwarza ona template na konkretną instancję obiektu oraz enkapsuluje go w obiekcie „obj”. Obiekt „obj” posiada jedną metodę „__noSuchMethod__”. Jest ona odpowiednikiem „__call” w PHP. Sprawdza ona, czy metoda, która chcemy wywołać z obiektu jest możliwa do wywołania (jej scope jest „public”). Jeżeli tak, to jest wywoływana i zwracany jest efekt jej działania.

Jak już pisałem, efektem takiego podejścia do tworzenia obiektów jest możliwość zasymulowania wielodziedziczenia. Potrzebne będą nam do tego – jeszcze jeden template, oraz funkcja miksująca:

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: batman, dodany: 18.02.2011 12:00, tagi: css

Wycinaliście kiedyś layout, w którym grafik przesadził z cieniami? Zero przyjemności. Dłubanie się z obrazkami imitującymi cień, stosowanie fixów i hacków JavaScript i efekt końcowy daleki od zamierzonego. Wraz z pojawieniem się na rynku IE9, wreszcie możemy skorzystać z dobrodziejstw CSS, działających na wszystkich nowych(!) przeglądarkach.

Cała tajemnica tkwi w pseudo-elementach zastosowanych na elemencie, do którego chcemy dodać cień oraz transformacjom CSS, umożliwiającym dowolne kształtowanie cienia. Mamy możliwość wygięcia cienia w łuk, stworzenie imitacji perspektywy, czy też dodanie cienia do obróconych elementów.

shadow

Dokładny opis tej techniki wraz z kodem CSS znajdziecie na stronie http://nicolasgallagher.com/css-drop-shadows-without-images/. Obowiązkową pozycją jest również demo.

Miłej zabawy.

Autor wpisu: Śpiechu, dodany: 18.02.2011 00:52, tagi: php

Począwszy od wersji 5.3.0 dostaliśmy nową fajną funkcję do czarowania w PHP. Do tej pory jeżeli chcieliśmy wywoływać funkcję, która nie istnieje, musieliśmy używać __call. Teraz dodano __callStatic. Przyznam się, że jakoś mi umknęła. Jak sama nazwa mówi, służy do wywoływania nieistniejących metod statycznych. Pomyślałem, że warto wymyślić dla niej jakieś sensowne zadanie.

W ilu miejscach kodu sprawdzacie wielokrotnie zmienne czy nie są nulami, czy nie są puste, a jak spełnią te dwa warunki, to czy są liczbami całkowitymi i czy nie są większe niż np. 5? Sprawdzenie tych wszystkich warunków powoduje masę IFów. Nie lepiej byłoby sprawdzać tak

if (Walidator::check_notNull_notEmpty_isInt_gt5($zmienna)) {
// poprawna wartosc
}

Fajne, co? Bez tworzenia obiektów, złożonych funkcji warunkowych itp. Dla setterów jak znalazł :-) Kolejne elementy nazwy zawężają warunek poprawności.

Klasa powstała w ok. 1 godz., dlatego używajcie na własną odpowiedzialność. W ciągu kilku dni wrzucę klasę na githuba i trochę potestuję w kierunku błędów, dorzucę kilka interesujących warunków itp. Może się komuś przyda.

<?php
class Walidator {
  /**
   * Reaguje na funkcje rozpoczynajace sie od 'check_'.
   * Jako separatora uzywac znaku _
   * @param string $name nazwa nieisniejacej funkcji
   * @param array $args podane parametry
   * @return bool
   */
  public static function __callStatic($name, $args) {
    if (stripos($name, 'check_') === 0) {
      // obcinamy poczatek
      $name = substr($name, 6);
      // rozdzielamy skladowe nazwy
      $extractedNames = explode('_', $name);
      // przelatujemy po wszystkich rozdzielonych funkcjach
      foreach($extractedNames as $funcName) {
        // rozpracowujemy nazwe funkcji
        $funcName = self::extractFunction($funcName);
        // sprawdzamy czy rozpracowana funkcja istnieje
        if (!method_exists(__CLASS__, $funcName['funkcja'])) {
          throw new Exception("Funkcja {$funcName} nie istnieje!");
        }
        // sprawdzamy czy w parametrze podano
        // tablice z wartosciami do sprawdzenia
        if (is_array($args[0])) {
          foreach ($args[0] as $arg) {
            // gwozdz programu! wywolujemy
            // rozpracowana funkcje i podajemy ewentualne
            // dodatkowe parametry
            if (self::$funcName['funkcja']($arg, $funcName['args']) == false) {
              return false;
            }
          }
        }
        // jezeli parametr nie jest tablica
        else {
          if (self::$funcName['funkcja']($args[0], $funcName['args']) == false) {
            return false;
          }
        }
      }
      // jezeli dolecialo az tutaj tzn., ze wartosc poprawnie zwalidowana
      return true;
    }
    // wylapie zle skonstruowany poczatek nazwy funkcji
    throw new Exception("Próba wywołania nierozpoznanej funkcji {$name}");
  }
 
  /**
   * Szuka znanych sobie funkcji skladowych do wywolania.
   * @param string $name
   * @return array tablica z nazwa funkcji i parametrami
   */
  protected static function extractFunction($name) {
    // calosc na male litery
    $name = strtolower($name);
    // jezeli zaczyna sie od 'not'
    if (stripos($name, 'not') === 0) {
      // ciachnij 'not'
      $name = substr($name, 3);
      // to co zostalo napisz z duzej litery
      $name = 'not' . ucfirst($name);
      return array(
        'funkcja' => $name,
        'args' => null);
    }
    // to samo jezeli zaczyna sie od 'is'
    elseif (stripos($name, 'is') === 0) {
      $name = substr($name, 2);
      $name = 'is' . ucfirst($name);
      return array(
        'funkcja' => $name,
        'args' => null);
    }
    elseif (stripos($name, 'gt') === 0) {
      return array(
        'funkcja' => 'gt',
        // to co zostalo musi byc parametrem gt
        'args' => substr($name, 2));
    }
    elseif (stripos($name, 'eq') === 0) {
      return array(
        'funkcja' => 'eq',
        'args' => substr($name, 2));
    }
    elseif (stripos($name, 'between') === 0) {
      $name = substr($name, 7);
      return array(
        'funkcja' => 'between',
        // z tego co zostalo
        // rozwalamy wartosci przy 'and'
        'args' => explode('and', $name));
    }
    elseif (stripos($name, 'maxlength') === 0) {
      return array(
        'funkcja' => 'maxLength',
        'args' => substr($name, 9));
    }
    // jezeli doszlo az tutaj to
    // nierozpoznano funkcji i
    // wywalam wyjatek
    else {
      throw new Exception("Nie rozpoznano funkcji {$name}");
    }
  }

Skoro mamy szkielet do rozpoznawania funkcji to wrzucimy sobie trochę funkcji walidujących.

public static function isNull($var) {
  return is_null($var);
}
 
public static function notNull($var) {
  return !is_null($var);
}
 
public static function isEmpty($var) {
  return empty($var);
}
 
public static function notEmpty($var) {
  return !empty($var);
}
 
public static function isInt($var) {
  return is_int($var);
}
 
public static function isString($var) {
  return is_string($var);
}
 
/**
 * Sprawdza czy $var jest wieksze lub rowne $arg.
 * @param numeric $var
 * @param numeric $arg
 * @return bool
 */
public static function gt($var, $arg) {
  if (!is_numeric($var)) throw new Exception("Sprawdzana wartosc {$var} nie jest liczba!");
  if (!is_numeric($arg)) throw new Exception("Warunek {$arg} nie jest liczba!");
  return ($var > $arg);
}
 
/**
 * Sprawdza czy $var jest rowne $arg.
 * @param numeric $var
 * @param numeric $arg
 * @return bool
 */
public static function eq($var, $arg) {
  if (!is_numeric($var)) throw new Exception("Sprawdzana wartosc {$var} nie jest liczba!");
  if (!is_numeric($arg)) throw new Exception("Warunek {$arg} nie jest liczba!");
  return ($var == $arg);
}
 
/**
 * Sprawdza czy $var znajduje sie w przedziale $arg[0] <= $var <= arg[1].
 * @param numeric $var
 * @param array $arg $arg[0] i $arg[1] typu numeric
 * @return bool
 */
public static function between($var, array $arg) {
  if (!is_numeric($var)) throw new Exception("Sprawdzana wartosc {$var} nie jest liczba!");
  if (!is_numeric($arg[0]) || !is_numeric($arg[1])) throw new Exception("Warunek {$arg[0]} lub {$arg[1]} nie jest liczba!");
  return (($var >= $arg[0]) && ($var <= $arg[1]));
}
 
/**
 * Sprawdza max dlugosc ciagu $var.
 * @param string $var
 * @param int $arg
 * @return bool
 */
public static function maxLength($var, $arg) {
  if (!is_string($var)) throw new Exception("Sprawdzana wartosc {$var} nie jest stringiem!");
  if (!is_numeric($arg)) throw new Exception("Warunek {$arg} nie jest liczba calkowita!");
  return (strlen($var) <= (int) $arg);
}

Skoro mamy „klocki”, z których możemy budować sobie warunki walidacji, poniżej kilka testów

if (Walidator::check_notempty_isint_gt5_between1and9($test)) {
  echo 'wartosc poprawna';
}
else {
  echo 'BLAD!';
}

Dla wartości 6.5 funkcja zwróci błąd (isInt), dla tablicy array(6,7,8,9) wartość poprawną, z kolei Walidator::check_maxLength4(array('ala','miala','kota')) zwróci również błąd, bo ‚miala’ ma 5 znaków :-)

Autor wpisu: sokzzuka, dodany: 17.02.2011 15:16, tagi: php

Jak już było wczoraj zapowiedziane. Do ściągnięcia jest najnowsza wersja Release Candidate PHP – 5.3.6RC1. Jest to Release Candidate, a więc nie należy jej używać na produkcji. Kolejny RC albo finalna wersja pojawi się prawdopodobnie za około dwa tygodnie.

Źródło: http://news.php.net/php.internals/51453

Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.