Blog webdeveloperski Patryk yarpo Jar

Dojo – quick start

Autor wiadomości Czerwiec 15, 2011

Dojo jest potężnym frameworkiem JavaScript, posiadającym nie tylko wsparcie dla mechanizmów JS, ale także zestaw customizowlanych widgetów, skórki, narzędzia do kompresji, wiele łat na JavaScript sprawiających, że jest on "normalniejszy" (w znaczeniu języków podobnych do Javy) czy specjalny mechanizm ładowania plików z odpowiednimi klasami. Tak w dojo występują klasy, o czym kiedyś jeszcze napiszę, a póki co odsyłam do dokumentacji :).

Szybki start

Aby zacząć z dojo należy po prostu załączyć odpowiedni plik z kodem JavaScript i wykorzystywać API frameworka.

<html>
<head>
    <title>Quick start dojo!</title>
    <script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojo/dojo.xd.js"></script>
    <meta http-equiv="content-type" content="text/html;charset=utf-8" />
    <script>
    dojo.addOnLoad(function() {
        alert("dojo działa!");
    });
    </script>
    </head>
<body>
    <p>Szkielet strony wykorzystującej dojo</p>
</body></html>

demo online

Powyższy kod chyba najprostszym kodem dojo, który będzie działał :). Załączamy plik frameworka, a a następnie przypisujemy funkcje obsługi zdarzenia `load' (załadowanie strony strony). Oczywiście, to nadal nie wszystko, na co pozwala dojo.

Operacje na drzewie DOM

Opiszę dwa główne sposoby dostępu do węzłów dom z wykorzystaniem dojo.

dojo.byId

Metoda `dojo.byId' jest skrótem dla 'document.getElementById'. Jako parametr podaje się wartość atrybuty `id' elementu DOM. W wyniku otrzymujemy obiekt węzła DOM.

dojo.addOnLoad(function() {
    var domElemDojo = dojo.byId('example')
    ,   domElemTrad = document.getElementById('example');

    alert(domElemDojo === domElemTrad); // true
});

demo online

dojo.query

Do metody `dojo.query' przekazujemy odpowiedni selektor (zgodny składniowo z tym stosowanym w jQuery). W wyniku otrzymujemy tablicę obiektów.

dojo.addOnLoad(function() {
    // odczyta wszystkie p z dokumentu
    var pElems = dojo.query('p')

    // odczyta wszystkie a zawarte w dowolnym znaczniku p,
    // który znajduje się w elemencie o id = "przyklad"
    ,   sophisticated = dojo.query('#przyklad p a');

    alert(pElems.length);
    alert(sophisticated.length);
});

demo online

Skoro już wiemy jak łapać odpowiednie węzły, czas spróbować z nimi coś zrobić. Najpierw zmienimy styl odpowiedniego węzła:

dojo.addOnLoad(function() {
    // można najpierw złapać odpowiedni węzeł
    var elem = dojo.byId('example');
    // i przypisać do niego style, przekazując obiekt
    dojo.style(elem, {'border': '1px solid red'});
    // albo podać id węzła i następne dwa parametry do metody
    dojo.style('example2', 'border', '1px solid blue');
    // lub id węzła i obiekt ze stylami
    dojo.style('example3', {'border' : '1px solid green', 'color' : 'blue'});
});

demo online

W przypadku korzystania z `dojo.query' musimy przeiterować po wszystkich elementach:

dojo.addOnLoad(function() {
    var elems = dojo.query('p');
    dojo.forEach(elems, function(elem) {
        dojo.style(elem, {'border' : '1px solid red'});
    });
});

demo online

Warto przeczytać:

Animacje

Każdy szanujący się framework JS posiada przyjazne programiście funkcje animujące elementy strony. Nie inaczej jest z dojo.  Poniżej pokażę tylko jeden przykład, po więcej zapraszam do dokumentacji i dojo campus.

var fadeInObj, fadeOutObj;

dojo.addOnLoad(function() {
    // przypisanie obiektów musi nastąpić dopiero po wczytaniu strony
    // stąd ten kod w `addOnLoad'
    fadeOutObj = dojo.fadeOut({ node: "example" });
    fadeInObj = dojo.fadeIn({ node: "example" });
});

function fadeOut() { fadeOutObj.play(); }
function fadeIn() { fadeInObj.play(); }

demo online

Póki co przykład nie zapiera dechu w piersiach. Z pewnością w tym momencie jquerowe fade'y są przyjaźniejsze. Co jednak powiecie na możliwość zdefiniowania specjalnych funkcji, które będą wywoływane w zależności od aktualnego stanu animacji? Istnieje obsługiwanych "zdarzeń":

  • beforeBegin - synchronicznie, przed rozpoczęciem animacji
  • onBegin - asynchronicznie, na rozpoczęcie animacji
  • onEnd - synchronicznie na zakończenie animacji
  • onPlay - synchronicznie, gdy animacja jest odtwarzana
  • onAnimate - uruchamiana na każdym kroku animacji

Przykładowe zastosowanie tych zdarzeń:

dojo.addOnLoad(function() {
    fadeOutObj = dojo.fadeOut({
        node: "example",
        duration : 8000,
        beforeBegin : function(node) { node.innerHTML = "Znikam!"; },
        onBegin : function(value) { this.node.InnerHTML = "No to zaczynam znikać"; },
        onEnd : function(node) { node.innerHTML = ""; },
        onPlay : function(value) { this.node.innerHTML = "Coraz mniej mnie!"; },
        onAnimate : function(value) {  this.node.innerHTML += "."; }
    });
    fadeInObj = dojo.fadeIn({ node: "example" });
});

demo online

Już lepiej , prawda 🙂

Po więcej przykładów i opcji odsyłam do dokumentacji. Warto zapoznać się także z takimi opcjami jak odpowiednie funkcje zanikania: http://docs.dojocampus.org/dojo/fx/easing.

Warto przeczytać:

Obsługa zdarzeń - connect i disconnect

Dojo posiada dwie bardzo przydatne metody pozwalające m. in. na przypisywanie funkcji obsługi zdarzeń.

dojo.connect

Do "związania" funkcji ze zdarzeniem służy metoda `dojo.connect':

dojo.addOnLoad(function() {
    dojo.connect(dojo.byId('example'), 'onclick', function() {
        alert('Kliknięto');
    });
});

demo online

Ogólnie nie wygląda trudno, prawda :). Starczy po prostu jako pierwszy atrybut podać obiekt (tu obiekt węzła DOM), jako drugi podać metodę, na jaką ma zostać wywołana funkcja obsługi zdarzenia (przekazywana jako parametr 3). Metoda `dojo.connect' zwraca odpowiedni handler, za pomocą którego można w późniejszym czasie "rozwiązać" połączenie.

dojo.disconnect

Działa przeciwnie do metody `dojo.connect'. Pozwala wyłączyć funkcję obsługi zdarzenia.

dojo.addOnLoad(function() {
    var handler = dojo.connect(dojo.byId('example'), 'onclick', function() {
        alert('Kliknięto, następne kliknięcie nic nie da');
        dojo.disconnect(handler);
    });
});

demo online

Inne zastosowania

Metoda `dojo.connect' ma prócz wyżej pokazanych sporo ciekawych zastosowań. Można np. powiązać wywołanie metody dowolnego obiektu z funkcją. W ten sposób tworzy się jakby nowe "zdarzenie":

var myObject = {
    a : function() { alert('myObject.a'); }
};
dojo.connect(myObject, 'a', function() {
    alert('Wywołano funckję powiązaną z metodą `myObject.a`');
});
myObject.a();

demo online

Wydaje Ci się ciekawe? 🙂 To co powiesz na możliwość wiązania w ten sposób metod dwóch obiektów?

var MyObject = function() {
    this.b = 'MyObject';
    this.a = function() {
        alert('Wywołano metodę `myObject.a`, wartość `b` = ' + this.b);
    }
};
var YourObject = function() {
    this.b = 'YourObject';
    this.x = function() {
        alert('Wywołano metodę `yourObject.a`, wartość `b` = ' + this.b);
    }
};

var obj1 = new MyObject(),
    obj2 = new YourObject();
dojo.connect(obj1, 'a', obj2, 'x'); // #
obj1.a();

demo online

W wyniku otrzymamy dwa komunikaty:

Wywołano metodę `myObject.a`, wartość `b` = MyObject
Wywołano metodę `yourObject.a`, wartość `b` = YourObject

To nadal nie wszystki możliwości. Stosując powyższy kod, z jedną zmianą [w linii "#"]:

dojo.connect(obj1, 'a', obj1, obj2.x); // #

demo online

Po tej zmianie otrzymujemy:

Wywołano metodę `myObject.a`, wartość `b` = MyObject
Wywołano metodę `yourObject.a`, wartość `b` = MyObject

Ma to związek z możliwością sterowania kontekstem w JavaScript. Szerzej o tym możesz przeczytać w "JavaScript na poważnie", rozdziały 1.4.7 i 1.4.8. Prócz `connect'/`disconnect' w dojo istnieje także mechanizm publisher / subscriber.

Warto przeczytać:

Dijit

Dijit jest biblioteką komponentów UI dojo. Aby skorzystać z jakichkolwiek widgetów wykorzystujemy przestrzeń nazw `dijit' [nie jak wcześniej dojo].

Dijit posiada 2 główne sposoby na umieszczenie elementu na stronie - programistycznie i deklaratywnie (w kodzie HTML z niestandardowymi atrybutami znaczników).

<html>
<head>
    <title>dijit - button deklaratywnie</title>
    <meta http-equiv="content-type" content="text/html;charset=utf-8" />
    <script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojo/dojo.xd.js"
        djConfig="parseOnLoad: true"></script>
    <script type="text/javascript">
        dojo.require("dijit.form.Button");
    </script>
    <link rel="stylesheet" type="text/css"
        href="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dijit/themes/claro/claro.css" />
</head>
<body>
    <button dojoType="dijit.form.Button" type="button">Kliknij mnie!</button>
</body></html>

demo online

Jak już wcześniej powiedziałem, można także osiągnąć ten sam efekt programistycznie:

<html>
<head>
    <title>dijit - button programistycznie</title>
    <meta http-equiv="content-type" content="text/html;charset=utf-8" />
    <script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojo/dojo.xd.js"
       djConfig="parseOnLoad: true"></script>
    <script type="text/javascript">
    dojo.require("dijit.form.Button");
    dojo.addOnLoad(function() {
        var button = new dijit.form.Button({
            label: "Kliknij mnie!!",
            onClick: function() {
                dojo.byId("example").innerHTML += "Kliknąłeś!";
            }
        }, "myButton");
    });
    </script>
    <link rel="stylesheet" type="text/css"
        href="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dijit/themes/claro/claro.css" />
</head>
<body>
     <button id="myButton" type="button"></button>
     <div id="example" />
</body></html>

demo online

W kodzie programistycznym, także dopisałem obsługę zdarzenia `onClick'. Uwaga, zdarzenie `onClick' dijitowego widgetu nie jest tym samym, co zdarzenie `onclick' węzła DOM.

W przypadku stosowania deklaratywnej metody można także przypisywać funkcje obsługi zdarzeń:

...
    <button dojoType="dijit.form.Button" type="button">Kliknij mnie!
    <script type="dojo/method" event="onClick" args="evt">
        dojo.byId("example").innerHTML += "Kliknąłeś! ";
    </script>
    </button>
    <div id="example"/>
...

demo online

Istnieje jeszcze kilka sposobów na powiązanie zdarzenia z funkcją obsługi. Jednym z nich jest wykorzystanie metody `dijit.byId'. Zwraca ona obiekt widgetu o zadanym id.

Oczywiście pokazany tu przycisk jest wierzchołkiem góry lodowej olbrzymiej liczby gotowych komponentów w bibliotece dijit. Zachęcam do poszukania w bardzo przyjaznej dokumentacji.

Warto przeczytać:

Warto przeczytać

Komentarze (5) Trackbacks (0)
  1. Przejrzałem wyrywkowo, ale widzę, że bardzo fajne wprowadzenie 🙂

    Pozdrawiam.

  2. Całkiem fajny framework 🙂

    naprawdę nie wiem, dlaczego w pl tak słabo znany :/

  3. // który znajduje się w elemencie o id = “przyklad”
    sofisticated = dojo.query(‘#przyklad p a’);
    – See more at: http://www.yarpo.pl/2011/06/15/dojo-quick-start/#sthash.7H68h1lE.dpuf

    wstydź się 😉

    Przyznam że jeden z lepszych polskich blogów o JS.
    Co do klas w JS to chyba prototype.js jest najlepszy.
    Jak go poznam lepiej podzielę się opinią.

  4. gdzie, ja widze “sophisticated” 😉 [dzieki 🙂 ]

    Dziekuje za mile slowa. Ostatnio zmienilem prace i niewiele robie w JavaScripcie, wiec raczej nie bedzie sie wiele pojawiac o tym jezyku. Bedzie za to pewnie niedlugo cos o innym nienawidzonym jezyku – PHP, w ktorym przyszlo mi teraz robic calkiem ambitny projekt.

    O JS ostatnio pisalem na blogu nowej firmy:
    http://www.yarpo.pl/2013/12/13/javascript-sterowanie-kontekstem-wywolania-funkcji/

  5. Ja piszę zawodowo w PHP 5 od 1,5 roku. Ogólnie jest to prosty, łatwy język, choć takie rzeczy jak trait juz nie. Owszem ma mniejsze możliwości niż Java, C++ i wiele rzeczy nie jest obiektowe np. zarządzanie plikami, nie ma plimorfizmu ale nie ma co narzekać.


Leave a comment

 

Brak trackbacków.