Mootools für die Massen, Teil 5: Programmieren im Mootools-Stil

Achtung: dieser Beitrag ist alt! Es kann gut sein, dass seine Inhalte nicht mehr aktuell sind.

Nachdem wir in den ersten vier Teilen dieser Artikelserie die einzelnen Funktionen und Prinzipien von Mootools kennengelernt haben stellt sich nur noch die Frage: was kann man damit anstellen? Objekte, Klassen, Events und Dollarfunktionen schön und gut – doch was hat man im Programmieralltag davon? Diese Frage soll dieser letzte Teil der Serie anhand eines Beispiels aus dem Mootools-Core und einem Tutorial für ein selbstgebautes Plugin beantworten.

Was Klassen leisten können

Das Klassensystem von Mootools ermöglicht es, bestehende Funktionen zu verändern, ohne ihren Code anrühren zu müssen. Die Scripts bleiben sauber, modular und vor allem klein – ein Prinzip, das auch im gesamten Kerncode von Mootools seine Anwendung findet.

In Teil 3 der Artikelserie haben wir uns ja unter anderem die Request-Klasse angesehen, mit der sich bequem Ajax aus dem Ärmel schütteln lässt. Mootools hat mit Request.JSON auch eine abgewandelte Form dieser Request-Funktion dabei, die statt purem Text JSON verarbeitet. Dank des Klassensystems ist Request.JSON eine Sache von nicht mal 20 Zeilen Code:

Request.JSON = new Class({
    Extends: Request,
    options: {
        secure: true
    },

    initialize: function(options){
        this.parent(options);
        this.headers.extend({'Accept': 'application/json', 'X-Request': 'JSON'});
    },

    success: function(text){
        this.response.json = JSON.decode(text, this.options.secure);
        this.onSuccess(this.response.json, text);
    }

});

Einfach die Ursprungsklasse um zwei Funktionen erweitern, fertig! Ganz ohne irgendwelchen Code zu hacken oder zu duplizieren – elegant und kompakt. Dieses Prinzip kann (und sollte man) auf fast jedes seiner Mootools-Scripts anwenden.

Ein Beispiel

Setzen wir uns doch mal folgende Beispielaufgabe: ein Script soll beim Klick auf einen Link ein Fenster ähnlich dem Popup der alert()-Funktion anzeigen. Spontan würde es sich anbieten, das Fenster einfach zusammenzusetzen, indem man ein entsprechendes HTML-Element erstellt und in das Dokument einfügt:

$('link').addEvent('click', function(e){
    e.stop();
    var container = $('container');
    var popup = new Element('div', {
        'class': 'popup',
        'text': 'Das hier ist der Text unseres Popup-Fensters'
    });
    popup.inject(container);
});

Das ist ganz nett und funktioniert. Aber nehmen wir doch mal an, wir würden die gleiche Funktion in eine Klasse verpacken …

Popups mit Klasse

… dann könnte das in einem ersten Schritt so aussehen:

var Popup = new Class({
    popup: null,

    // Initialisierung
    initialize: function(popupText){
        this.popup = new Element('div', {
            'class': 'popup',
            'text': popupText
        });
    },

    // Popup anzeigen
    display: function(container){
        var container = $(container);
        this.popup.inject(container);
    }
});

// Unser schönes neues Popup-Fenster
$('link').addEvent('click', function(e){
    e.stop();
    var meinPopup = new Popup('Das hier ist der Text unseres Popup-Fensters');
    meinPopup.display('container');
});

Was ist damit gewonnen außer dass die ganze Geschichte mehr Zeilen in Anspruch nimmt? Ganz einfach: Portabilität. Wollten wir unser Popup-System in eine andere Website verwenden, könnten wir jetzt die Klasse in einer JS-Datei ablegen, diese in anderen Projekten einbinden und dann am Fließband neue Popups produzieren – pro Fenster reicht dann eine einzige Code-Zeile mit new Popup('Text').display('container'). Das Ergebnis sieht am Ende gleich aus, aber ohne Klasse müssten wir jeweils den gesamten Code aufs neue einfügen.

Wo wir schon mal eine Klasse an der Hand haben bietet es sich auch an, das Popup-Fenster gleich etwas flexibler und konfigurierbarer zu gestalten:

var Popup = new Class({

    Implements: Options,
    options: {
        'className': 'popup',
        'popupText': 'Hier fehlt Text! Bitte ändern!',
        'container': document.body
    },
    popup: null,

    // Initialisierung
    initialize: function(options){
        this.setOptions(options); (unter anderem <code>document.body</code> als Container)
        this.popup = new Element('div', {
            'class': this.options.className,
            'text': this.options.popupText
        });
    },

    // Popup anzeigen
    display: function(){
        this.popup.inject(this.options.container);
    }

});

// Unser schönes neues Popup-Fenster
$('link').addEvent('click', function(e){
    e.stop();
    var meinPopup = new Popup({
        'popupText': 'Das hier ist der Text unseres Popup-Fensters'
    }).display();
});

Jetzt ist der Code noch länger, aber dafür ist das Plugin einfacher zu verwenden, bei immer noch gleichem Ergebnis. Es kann das aus Mootools bekannte Options-Objekt verwendet werden, so dass man Klasse des Popups und auch den Text einfach an einer Stelle ändern kann. Außerdem haben wir unter options Standardwerte für alle Werte notiert, so dass man bei Bedarf auch einfach new Popup.display() schreiben und trotzdem ein funktionierendes Ergebnis bekommen könnte.

Jetzt kann man die Popup-Klasse bequem in jedem Mootools-Projekt einsetzen, in dem man Popups braucht. Der Code ist portabel und flexibel. Nun könnte man sowas ähnliches vielleicht auch mit einfachen Funktionen hinbekommen, aber Mootools kann ja noch mehr.

Pimp my Popup

Unterschiedliche Websites brauchen ähnliche, aber nie ganz identische Funktionen. Deswegen ist Otto Normalwebworker oft damit beschäftigt, alten Code aus Website A in Website B zu kopieren und anzupassen. An genau dieser Stelle kann Mootools auftrumpfen – denn wir können ja unsere Klassen erweitern, ohne irgendwelchen alten Code hacken zu müssen.

Nehmen wir mal an, wir bräuchten für eine andere Website Popups mit Titelleisten und einem OK-Button um das Popup zu schließen. Die können wir ganz einfach kriegen, indem wir entsprechende Methoden in unser bewährtes Popup implementieren:

Popup.implement({

    // Eine zusätzliche Titelleiste
    addTitle: function(text){
        var titleBar = new Element('div', {
            'class': 'popupTitle',
            'text': text
        });
        titleBar.inject(this.popup, 'top');
    },

    // Und ein OK-Button
    addButton: function(text){
        var button = new Element('div', {
            'class': 'popupButton',
            'text': text
        });
        Popup.implement(Events);
        button.addEvent('click', function(){
            this.popup.destroy();
        }.bind(this));
        button.inject(this.popup, 'bottom');
    }

});

// Unser schönes neues Popup-Fenster
$('link').addEvent('click', function(e){
    e.stop();
    var meinPopup = new Popup({
        'popupText': 'Das hier ist der Text unseres Popup-Fensters'
    });
    meinPopup.addTitle('Wichtige Meldung');
    meinPopup.addButton('OK');
    meinPopup.display();
});

Damit ist unser kleines Popup ganz schön aufgemotzt – ohne dass wir ein Byte an unserer Ursprungsklasse verändern mussten. Und wenn wir wollten, könnten wir immer noch die ursprünglichen Popups ohne Extras erzeugen.

Popups der nächsten Generation

Ein verbessertes Popup-Fenster

Wenn man Erweiterungen einbaut, von denen man glaubt dass man sie später bei anderen Projekten nochmal gebrauchen kann, bietet es sich natürlich an, die Erweiterungen ihrerseits in eine Klasse zu packen, die die normale Popup-Klasse erweitert. Drag & Drop, Lightbox-Effekt und Minimieren-Button – das kann man alles umsetzen, ohne die Ursprungsklasse zu verändern.

var FancyPopup = new Class({
    Extends: Popup,
    // Code für die zusätzlichen Funktionen
});

var meinPopup = new FancyPopup({
    'popupText': 'Das hier ist der Text unseres Popup-Fensters'
});
meinPopup.addTitle('Wichtige Meldung');
meinPopup.addButton('OK');
meinPopup.addOverlay();
meinPopup.display();

Und die Erweiterungen selbst sind wieder in einer handlichen Klasse zusammengefasst, die man ihrerseits in andere Projekte portieren und dort noch mehr erweitern kann.

The Art of Moo

Die Kunst des Mootools-Programmierens liegt also einfach darin, Scripts so zu gestalten, dass sie entweder erweiterbar sind oder ihrerseits auf vorhandenen Scripts aufbauen. Das Klassensystem von Mootools macht dieses Vorhaben in der Sache einfach – man muss nur ein gewisses Maß an planerischer Weitsicht aufbringen.

Wenn man immer fleißig Klassen anlegt, baut man sich in kurzer Zeit einen Fundus an Plugins auf, die portabel und im Bedarfsfall einfach erweiterbar sind, wobei die Erweiterungen ihrerseits wiederum portabel und erweiterbar sind. Die Klassen sind zwar von der Codemenge her alle etwas länger als wenn man einfach ständig $().foo().bar() schreiben würde, aber bereits bei der ersten Portierung in ein anderes Projekt macht sich das bezahlt. Und bei der ersten Erweiterung mit einem einfachen Extend erst recht.

Und als Bonus kommt eben noch hinzu, dass man nicht alles in Klassen verpacken muss. Man kann das tun und sollte es in 90% der Fälle sicher auch tun, aber wenn man nur eben mal schnell etwas zusammenhauen möchte, geht das auch: $('foo').fade('out'); funktioniert in Mootools genau so wie bei jQuery und Konsorten. Mootools macht die einfachen Dinge einfach, hat aber auch (und vor allem) für die komplexeren Dinge alle nötigen Funktionen auf Lager. Und genau das ist der Grund, warum dieses schöne kleine Javascript-Framework unsere Aufmerksamkeit verdient.

Kommentare (25)

  1. Webstandard-Team (Heiko)

    6. August 2009, 09:30 Uhr

    Klasse Abschluss der Mootools-Serie. Hast du mal überlegt diese Serie als PDF zum Download anzubieten?

  2. Schepp

    6. August 2009, 12:12 Uhr

    Danke für die interessanten Artikel! Käme jetzt ein Kunde mit der Anforderung Mootools um die Ecke, hätte ich keinerlei Bedenken oder Fragezeichen, ob ich damit im Sinne des Kunden hantieren kann. Definitiv ein cooles Framework.

    In Sachen Objektorientierung: Obwohl ich gehofft habe, dass es bei mir endlich mal *click* macht, bin und bleibe ich wohl weiterhin der Funktions-Typ und weniger der Klassen-Typ. Sowohl in JS wie auch in PHP. Denn ich kann ja dort auch Funktionsaufrufe in Funktionen verpacken und habe dann ja auch einen zuständigen Code und eine Art "Vererbung". Sehe da keine Nachteile, wenn man die richtige Herangehensweise hat.
    Oder hab ich einen Knoten im Gehirngang was OO angeht?

  3. Peter

    6. August 2009, 14:27 Uhr

    Zitat Webstandard-Team (Heiko):

    Klasse Abschluss der Mootools-Serie. Hast du mal überlegt diese Serie als PDF zum Download anzubieten?

    Ja, das müsste ich eigentlich mal mit all meinen Artikelserien machen. Ich müsste mich nur mal aufraffen :)

    Zitat Schepp:

    Oder hab ich einen Knoten im Gehirngang was OO angeht?

    So würde ich das nicht nennen - objektorientierte Programmierung ist von Natur aus eine recht abstrakte Angelegenheit und damit nicht ganz so einfach zu kapieren. Mein Tipp für die Klick-Erleuchtung wäre ganz einfach learning by doing. Durch bloßes lesen habe ich es damals auch nicht verstanden, ich brauchte Feldversuche.

  4. Codaweb

    16. August 2009, 20:58 Uhr

    Von Mootools halte ich nicht viel. Ich finde jQuery um längen besser und intuitiver.

  5. muhkuh

    16. August 2009, 21:24 Uhr

    Mei, immer diese Pimmelvergleiche... Soll doch jeder das benutzen, was er für besser hält; Dann doch bitte mit sachlichen Argumenten unterstreichen. Die Alternativen runter zu machen, um sich seine Wahl vor sich selbst weiter zu rechtfertigen - so habe ich deinen Kommentar interpretieren müssen Codaweb - macht doch keinen Spaß.

    Ich jedenfalls benutze zwar auch jQuery, aber vor allem nur, weil ich das bisher am meisten genutzt habe und das Framework dadurch besser verstehe als z.B. Mootools. Die Serie fand ich auf jeden Fall sehr interessant. Allein schon der Blick über den eigenen Tellerrand macht es Wett sich die Alternativen einmal näher anzusehen.

  6. Maldoror

    22. August 2009, 21:17 Uhr

    Sehr schöne MooTools Serie, Peter!

    @Codaweb
    Ich wundere mich sehr, dass Du Deinen unqualifizierten Kommentar ausgerechnet nach diesem Tutorial einstellst. Gerade hier wurde doch sehr schön gezeigt, dass MooTools etwas grundsätzlich anderes ist als jQuery. Offensichtich sind Deine Javascript-Kenntnisse (bzw. überhaupt Deine Programmier-Kenntnisse) nicht ausreichend, um den Unterschied zu verstehen. Bitte beschäftige Dich mal mit OO Programmierung und lerne danach noch mal richtig Javascript. Und dann liest Du Dir auch mal das hier durch: http://jqueryvsmootools.com/ Ich hoffe, das wird Dir auf die Sprünge helfen und uns in Zukunft vor solch peinlichen Kommentaren bewahren.

  7. Rainer Programmierer

    20. September 2009, 08:33 Uhr

    Merkwürdig...
    Also ich nutze einen nicht gerade häufig gebrauchten Browser der Familie Mozilla... (zumindest glaube ich, dass Seamonkey so ein Browser ist.) und bei mir gehen diese Bsp. alle nicht.

    Statt in einem Popup wird der Content im selben Fensterle geöfftnet... o.O

    Noscript und mein nettes ANTI-Werbetool sind deaktiv. ;)

    Also müsste es quasi gehen... Aber vielleicht liegts ja auch an MOOHOtoolz... *augenroll*
    Man kann zwar nicht immer alle Browser bedienen, aber hey das Ding gehört zu Mozilla und verhält sich wie Firefox (mit kleinen Abweichungen)...

    Wieso gehen dann diese Beispiele im Seamonkey nicht?

    MfG Rainer Programmierer

  8. Peter

    20. September 2009, 08:49 Uhr

    So soll es sein. Das ist ja eigentlich kein Popup, sondern Modalcontent.

  9. Rainer Programmierer

    20. September 2009, 09:05 Uhr

    Ja schon klar. Aber im Absatz "Popups der nächsten Generation" ist son schickes kleines Bild, welches im Prinzip alert() gegen eine divBox "tauscht" (mal blöde ausgedrückt). Aber das kommt ja auch nich.

    Stattdessen lädt sich diese Seite neu mit Lorum ipsum Text!!!

    Ist das Absicht? Was ich aber nicht denke.
    Ich bin irgendwie mit Mootools schonmal angeeckt... Obwohl es ein echt nettes Tool ist! Aber ich will ja nun deswegen nicht meinen Browser wechseln müssen... o.O

    MfG der Rainer

  10. Rainer Programmierer

    20. September 2009, 09:15 Uhr

    Man, bin ich blöd...
    Ich seh jetz erst den Link im Text...

    Hier scheint die Sonne so derbe rein... ;)

    Schönen Sonntag noch...

  11. M0ses

    2. November 2009, 09:07 Uhr

    Hallo,

    ein toller Artikel! Hab mir einiges abkucken können und möchte meine Erfahrungen mit IE6 kurz erläutern.

    Problem:
    Das overlay-div fürs fancy-popup war nicht richtig zu sehen.

    Grund:
    Internet Explorer 6 kennt "position:fixed" nicht und kann auch nicht mit den Angaben top,right,left,bottom richtig umgehen

    Lösung:
    CSS umbauen (evtl. mit browser-weiche)

    body {
    height:100%;
    width:100%;
    padding:0px;
    margin:0px;
    }
    .popupOverlay {
    ....
    position:absolute;
    height:100%
    width:100%
    }

    Sofern keine anderen styles der umformattierung des bodys entgegenstehen

  12. Christian

    10. Dezember 2009, 09:52 Uhr

    Sehr schöner Artikel!
    Ich finde es super, wenn die Community von Mootools durch qualifizierte Artikel gestärkt wird. Wir haben früher auch jQuery benutzt, allerdings stößt man hier schnell an seine Grenzen. Mit Mootools hat man den Vorteil komplexe Sachverhalte zu programmieren und gleichzeitig vereint es die Einfachheit von jQuery. Ich denke mal, Mootools ohne jegliche Erfahrung in Javascript zu lernen ist relativ schwer, da lässt sich die große Community bei jQuery schon gut erklären.

    lg christian

  13. Tobias

    17. Februar 2010, 20:21 Uhr

    Kann mir jemand verraten, wie ich im dem FancyPopup html als Inhalt anzeigen kann?

  14. Peter

    17. Februar 2010, 21:18 Uhr

    In der Popup-Klasse das hier …

    'text': this.options.popupText

    … durch das hier ersetzen:

    'html': this.options.popupText
  15. Tobias

    17. Februar 2010, 21:48 Uhr

    Oh man, wie einfach.

    Danke dir!

    PS: Und wenn es ein Buch wird, kaufe ich es auch!

  16. Peter Mattes

    19. Februar 2010, 10:34 Uhr

    Obwohl ich schon einige Zeit mit Mootools experimentiere, konnte ich anhand dieser Tutorialserie wieder einiges lernen bzw. machte die Sicht auf manche Dinge klarer. Die Vorteile der Objektorientierten Programmierung sind mir schon länger bekannt und ich versuche es auch immer wieder zu verwenden. Die Aussage, dass sich mit "gewohnter" Funktion orientierter Programmierweise schneller Aufgaben realisieren lassen aber die wiederverwendbarkeit aber auch das refactoring ist bei OO-Programierweise um einiges höher. Zur Zeit Versuche ich meinen Ansatz um einen Level zu erweitern: MVC.
    Jan Kassens hat hierzu ein tolles Konzept vorgelegt: http://github.com/kassens/mootools-mvc. Generell at Jan Kassens auf github ganz tolle Snippets und Beispiele veröffentlicht.

  17. Tobias

    23. Februar 2010, 09:54 Uhr

    Hallo zusammen,

    ich probiere schon einige Zeit mit MooTools herum, und auch das Window-Popup Beispiel aus diesem Artikel hat es mir sehr angetan.

    Nun würde ich aber gerne, dass sich das Fenster auch öffnet wenn man auf ein Bild klickt.
    Ich hatte gehofft das es geht, wenn ich das id="link" einfach in das img-Tag einfüge:

    Das geht aber nicht. :-(
    Kann mir jemand helfen?

  18. Tobias

    22. März 2010, 21:43 Uhr

    Ich bin's noch mal. :-)

    Ich habe festgestellt, dass das FancyPopup Beispiel nicht im IE (8) läuft.
    http://www.peterkroener.de/test/mootoolstut/5/5.html

    Dort bekomme ich folgende mir nix sagende Fehlermeldung:

    Benutzer-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; Embedded Web Browser from: http://bsalsa.com/; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 1.1.4322; Creative AutoUpdate v1.10.10)
    Zeitstempel: Mon, 22 Mar 2010 21:42:47 UTC

    Meldung: Das Objekt unterstützt diese Eigenschaft oder Methode nicht.
    Zeile: 129
    Zeichen: 7
    Code: 0
    URI: http://www.peterkroener.de/test/mootoolstut/5/5.html

    Kann damit jemand etwas anfangen?
    Vielleicht du, Peter? :-)

    Vielen Dank,
    Tobias

  19. Peter

    23. März 2010, 10:02 Uhr

    Scheint an der Zeile 'height': this.options.container.getSize().y zu liegen … könnte sein dass es für das Element da im IE kein getSize() gibt oder this könnte falsch sein. IE halt.

  20. Tobias

    23. März 2010, 19:59 Uhr

    Hallo Peter!

    Vielen Dank, genau das war das Problem.
    Ich habe die entsprechende Zeile durch folgende ersetzt, und nun geht es auch im IE:

    'height': document.documentElement.clientHeight

    Tobias

  21. Mahmut

    25. Juli 2010, 13:29 Uhr

    Dank Dir für diesen Artikel.

    Ich hab ne Frage zu Options. Ist Options eine Klasse von Moo? Welche Vorteile bringt diese Klasse? Ich hab es nicht verstanden. Bei Huhn hast Du extents und bei Option implements geschrieben. Soll Options ein Interface definieren? So wie bei Java und kann man von mehreren Klassen erben? Nur ne Frage, sollte man natürlich nicht machen.

    Und im 4. Teil hast Du bind benutzt. Anscheinend liefert Event ein Objekt. Aber wozu bind?

    Nochmal vielen dank für das Tutorium.

    PS Objekt Orientierung: Ob Funktional oder OO, man muß, das was man machen möchte, im kleinsten Programmieren. OO hat aber den Vorteil, dass man nicht mit globalen Variablen arbeiten muß. Und man sich nicht jedesmal neue Variablennamen ausdenken muß, wie fenster1, fenster2. Es ist ein Behäter wo, Informationen und Funktionen "versteckt" werden. Mehr ist das nicht. So merk ich mir das. Als Geschenk bekommt man dac die Wiederverwendbarkeit.

    bye

  22. cpojer

    25. Juli 2010, 16:36 Uhr

    @Mahmut:

    Options ist ein "Mixin". Mixins in MooTools werden über Implements eingebunden. Neben Options ist zB auch Events ein Mixin. Der Unterschied zwischen Extends und Implements ist, dass jede Klasse nur von einer anderen Klasse abstammen kann (Extends), aber viele Mixins einbinden kann. Ein call auf "this.parent()" ruft also nur die parent methode der Mutterklasse auf, nicht aber die der Mixins.

    Options im speziellen bietet die Methode "setOptions" an (siehe MooTools Dokumentation). Vereinfacht das verwenden von default parametern.

    .bind wird verwendet, um die Referenz auf die "this" in einer Funktion verweist, zu manipulieren. Wenn man einem DOM-Element ein event hinzufügt, zeigt das "this" innerhalb des listeners auf das DOM-Element (siehe JavaScript function binding + scope) - innerhalb von Klassen will man das meist nicht und mittels .bind(object) kann man das manipulieren (siehe MooTools Dokumentation).

  23. Oliver

    28. September 2010, 23:38 Uhr

    hat sich irgendwas verändert, mit der neusten mootools version?
    ich kann schon das einfachste beispiel des "popups" nicht testen.. FF

    Meldung: Fehler: l is null
    Quelldatei: ....mootools-core.js Zeile: 137

    gruss Oliver

  24. Erwin

    22. Oktober 2010, 16:58 Uhr

    Hallo zusammen,
    ich klinge mich hier einfach mal ganz frech ein ;)
    Ich bin gerade dabei meine erste Webseite mithilfe eines CMS zu realiseren. Das CMS läd Mootools mit, und nu dachte ich mir, könnte man damit ja ein wenig machen. Ich muss gestehen: Ich hab noch nie eine Webseite erstellt, nie irgendwas mit php, javascript und dergleichen zutun gehabt....

    Wäre vielleicht jemand so freundlich, und könnte mir etwas mit Mootools realiseren? Ist für Euch sicherlich ein Kinderspiel.

    Es geht um folgendes:

    Eine rechteckige Box mit abgerundeten Ecken (per css stylebar?)
    in der einmal ein fester Text steht, und darunter ein Text der sich nach Zeitinterval X automatisch verändert.

    Also so:

    Hier steht eine Frage? <- das ist immer so und soll nicht verändert werden.

    Hier steht ein von vielen Antworten. <- das soll sich verändern, vorgeben möchte ich ca. 10 möglich Antworten, welche nacheinander "abgespielt" werden sollen.

    Wäre schön, wenn mir jemand helfen könnte.

  25. Peter

    24. Oktober 2010, 09:37 Uhr

    So ganz ohne Ahnung wird das schwierig. Vielleicht hilft mein altes Plugin für rotierenden HTML-Content: http://www.peterkroener.de/wiki/doku.php?id=javascript:mootools:htmlslideshow

Die Kommentarfunktion ist seit Juli 2014 deaktiviert, weil sie zu sehr von Suchmaschinenoptimierern für manuellen Spam mißbraucht wurde. Wenn du Anmerkungen oder Fragen zum Artikel hast, schreib mir eine E-Mail oder melde dich via Twitter.

Folgt mir!

Kauft mein Zeug!

Cover der HTML5-DVD
Infos auf html5-dvd.de, kaufen bei Amazon

Cover des HTML5-Buchs
Infos auf html5-buch.de, kaufen bei Amazon

Cover des CSS3-Buchs
Infos auf css3-buch.de, kaufen bei Amazon