Advertisement
  1. Code
  2. Web Development

Javascript und das DOM: Lektion 2

by
Read Time:19 minsLanguages:

German (Deutsch) translation by Federicco Ancie (you can also view the original English article)

Hallo und willkommen zurück zur "JavaScript and the DOM" -Serie. Beim letzten Mal haben wir einige JavaScript-Grundlagen und verschiedene Aspekte des Dokumentobjektmodells besprechen, einschließlich des Zugriffs auf Knoten und des Durchlaufens des DOM. Heute werden wir uns mit der Bearbeitung von Elementen im DOM befassen und das Browser-Ereignismodell diskutieren.

Elemente manipulieren

In der letzten Lektion haben wir die Schritte behandelt, die beim Zugriff auf eine Sammlung von DOM-Knoten oder einen einzelnen DOM-Knoten erforderlich sind. Die wahre Magie entsteht, wenn Sie dann bestimmte Eigenschaften manipulieren, was zu dem führt, was allgemein als "Verhalten" bekannt ist.

Jeder einzelne DOM-Knoten verfügt über eine Sammlung von Eigenschaften. Die meisten dieser Eigenschaften bieten Abstraktionen für bestimmte Funktionen. Wenn Sie ein Absatzelement mit der ID 'intro' haben, können Sie die Farbe dieses Elements ganz einfach über die DOM-API ändern:

Um die Objekt-/Eigenschaftsnatur dieser API zu veranschaulichen, ist es einfacher zu verstehen, wenn wir sie aufteilen, indem wir jedes Objekt einer Variablen zuweisen:

Nachdem wir nun einen Verweis auf das 'style'-Objekt des Absatzes haben, können wir weitere CSS-Stile hinzufügen:

Wir verwenden hier nur grundlegende CSS-Eigenschaftsnamen. Der einzige Unterschied besteht darin, dass dort, wo Sie normalerweise einen Bindestrich ('-') finden würden, der Text in Kamelform geschrieben ist. Statt 'margin-top', verwenden wir also 'marginTop'. Folgendes würde nicht funktionieren und einen Syntaxfehler erzeugen:

Auf Eigenschaften kann auf Array-ähnliche Weise zugegriffen werden. Mit diesem Wissen könnten wir also eine kleine Funktion erstellen, um jeden Stil eines bestimmten Elements zu ändern:

Dies ist nur ein Beispiel - es ist keine sehr nützliche Funktion, da es syntaktisch schneller ist, die zuvor gezeigten herkömmlichen Mittel zu verwenden (z.B. elem.style.color = 'red').

Neben der Eigenschaft 'style' gibt es viele andere, mit denen Sie bestimmte Aspekte eines Knotens/Elements bearbeiten können. Wenn Sie Firebug installiert haben, sollten Sie versuchen, ein Element zu überprüfen, und dann auf die Registerkarte "DOM" (normalerweise rechts oder unterhalb des Elementanzeigefelds) klicken, um alle Eigenschaften anzuzeigen:

DOM Element properties, in the Firebug addon for FirefoxDOM Element properties, in the Firebug addon for FirefoxDOM Element properties, in the Firebug addon for Firefox
DOM-Elementeigenschaften in Firebug

Auf alle Eigenschaften kann unter Verwendung der herkömmlichen Punktnotation (z. B. Element.tabIndex) zugegriffen werden. Nicht alle Eigenschaften sind primitive Datentypen (Zeichenfolgen, Zahlen, Boolesche Werte usw.). Die Eigenschaft 'style' zum Beispiel, die wir zuvor besprochen haben, ist ein Objekt, das seine eigenen Eigenschaften enthält. Viele Eigenschaften eines Elements sind nur lesbar. Damit meine ich, dass Sie ihren Wert nicht ändern können. Beispielsweise können Sie die Eigenschaft 'parentNode' eines Knotens nicht direkt ändern. Der Browser gibt normalerweise einen Fehler aus, wenn Sie versuchen, eine dieser schreibgeschützten Eigenschaften zu ändern: z.B. ERROR: "Festlegen einer Eigenschaft, die nur einen Getter hat". Es ist nur etwas zu beachten...

Eine häufige Anforderung besteht darin, den Inhalt innerhalb eines Elements zu ändern. Es gibt verschiedene Möglichkeiten, dies zu tun. Der mit Abstand einfachste Weg ist die Verwendung der Eigenschaft 'innerHTML' wie folgt:

Das einzige Problem bei dieser Methode ist, dass sie in keinem Standard angegeben ist und nicht in der DOM-Spezifikation enthalten ist. Wenn Sie sich nicht darum kümmern, fahren Sie fort und verwenden Sie es. Es ist normalerweise sowieso viel schneller als herkömmliche DOM-Methoden, auf die wir als nächstes eingehen werden.

Nodes

Wenn Sie Inhalte über die DOM-API erstellen, müssen Sie zwei verschiedene Knotentypen kennen, einen Elementknoten und einen Textknoten. Es gibt viele andere Knotentypen, aber diese beiden sind derzeit die einzigen wichtigen.

Um ein Element zu erstellen, verwenden Sie die Methode 'createElement' und um einen Textknoten zu erstellen, verwenden Sie die Methode 'createTextNode'. Beide werden unten gezeigt:

Hier verwenden wir die Methode 'appendChild', um unseren neuen Textknoten zum Absatz hinzuzufügen. Dies dauert etwas länger als die nicht standardmäßige innerHTML-Methode, aber es ist immer noch wichtig, beide Möglichkeiten zu kennen, damit Sie die richtige Entscheidung treffen können. Hier ist ein erweitertes Beispiel mit DOM-Methoden:

Es gibt auch eine 'insertBefore'-DOM-Methode, die selbsterklärend ist. Mit diesen beiden Methoden ('insertBefore' & 'appendChild') können wir unsere eigene 'insertAfter'-Funktion erstellen:

Die obige Funktion prüft, ob das nächste Geschwister des Ziels im DOM vorhanden ist. Wenn es vorhanden ist, wird der Aufzählungsknoten vor dem nächsten Geschwister des Ziels eingefügt. Andernfalls wird davon ausgegangen, dass das Ziel das letzte untergeordnete Element eines Elements ist Es ist in Ordnung, die Kugel als Kind des Elternteils anzuhängen. Die DOM-API gibt uns keine 'insertAfter'-Methode, da keine Notwendigkeit besteht - wir können sie selbst erstellen.

Es gibt noch einiges mehr über das Bearbeiten von Elementen im DOM zu lernen, aber das oben Genannte sollte eine ausreichende Grundlage sein, auf der Sie aufbauen können.

Veranstaltungen

Browserereignisse bilden den Kern jeder Webanwendung und der meisten JavaScript-Verbesserungen. Durch diese Ereignisse definieren wir, wann etwas passieren wird. Wenn Ihr Dokument eine Schaltfläche enthält und Sie beim Klicken eine Formularüberprüfung benötigen, verwenden Sie das Ereignis "click". Unten finden Sie eine Übersicht über die meisten Standard-Browserereignisse:

Hinweis: Wie bereits beim letzten Mal erläutert, sind das DOM und die JavaScript-Sprache zwei separate Einheiten. Browserereignisse sind Teil der DOM-API, sie sind nicht Teil von JavaScript.

Mausereignisse

  • 'mousedown' - Das Mousedown-Ereignis wird ausgelöst, wenn das Zeigegerät (normalerweise eine Maus) über ein Element nach unten gedrückt wird.
  • 'mouseup' - Das mouseup-Ereignis wird ausgelöst, wenn das Zeigegerät (normalerweise eine Maus) über einem Element losgelassen wird.
  • 'click' - Das Klickereignis wird als Mousedown gefolgt von einem Mouseup an genau derselben Position definiert.
  • 'dblclick' - Dieses Ereignis wird ausgelöst, wenn ein Element zweimal schnell hintereinander an derselben Position angeklickt wird.
  • 'mouseover' - Das Mouseover-Ereignis wird ausgelöst, wenn das Zeigegerät über ein Element bewegt wird.
  • 'mouseout' - Das mouseout-Ereignis wird ausgelöst, wenn das Zeigegerät aus einem Element herausbewegt wird. (weg von einem Element)
  • 'mousemove' - Das Mausbewegungsereignis wird ausgelöst, wenn das Zeigegerät bewegt wird, während Sie mit der Maus über ein Element fahren.

Tastaturereignisse

  • 'keypress' - Dieses Ereignis wird ausgelöst, wenn eine Taste auf der Tastatur gedrückt wird.
  • 'keydown' - Dieses Ereignis wird auch ausgelöst, wenn eine Taste gedrückt wird. Es wird vor dem 'keypress'-Ereignis ausgeführt.
  • 'keyup' - Dieses Ereignis wird ausgelöst, wenn eine Taste nach den Ereignissen 'keydown' und 'keypress' losgelassen wird.

Formereignisse

  • 'select' - Dieses Ereignis wird ausgelöst, wenn Text in einem Textfeld (Eingabe, Textbereich usw.) ausgewählt ist.
  • 'change' - Dieses Ereignis wird ausgelöst, wenn ein Steuerelement den Eingabefokus verliert und/oder der Wert seit dem Erhalt des Fokus geändert wurde.
  • 'submit' - Dieses Ereignis wird ausgelöst, wenn ein Formular gesendet wird.
  • 'reset' - Dieses Ereignis wird ausgelöst, wenn ein Formular zurückgesetzt wird.
  • 'focus' - Dieses Ereignis wird ausgelöst, wenn ein Element den Fokus erhält, normalerweise von einem Zeigegerät.
  • 'blur' - Dieses Ereignis wird ausgelöst, wenn ein Element den Fokus verliert, normalerweise von einem Zeigegerät.

Andere Ereignisse

  • 'load' - Dieses Ereignis wird ausgelöst, wenn der Benutzeragent den gesamten Inhalt eines Dokuments geladen hat, einschließlich Inhalt, Bilder, Rahmen und Objekte. Bei Elementen wie "IMG" wird es ausgelöst, wenn der betreffende Inhalt vollständig geladen wurde.
  • 'resize' - Dieses Ereignis wird ausgelöst, wenn die Größe der Dokumentansicht geändert wird. (d. h. wenn die Größe des Browsers geändert wird.)
  • 'scroll' - Dieses Ereignis wird ausgelöst, wenn das Dokument gescrollt wird.
  • 'unload' - Dieses Ereignis wird ausgelöst, wenn der Benutzeragent den gesamten Inhalt aus einem Fenster oder Frame entfernt, d. h. wenn Sie eine Seite verlassen.

Es gibt viele weitere Veranstaltungen zur Auswahl. Die oben gezeigten sind die wichtigsten, auf die Sie im JavaScript-Code häufig stoßen. Beachten Sie, dass einige von ihnen subtile Unterschiede zwischen den Browsern aufweisen. Beachten Sie auch, dass viele Browser proprietäre Ereignisse implementieren, z. B. gibt es einige Gecko-spezifische Ereignisse wie "DOMContentLoaded" oder "DOMMouseScroll". Weitere Informationen hierzu finden Sie hier: https://developer.mozilla.org/de/Gecko-spezifische_DOM_Events

Handhabung des Events

Wir haben die tatsächlichen Ereignisse behandelt, aber wir müssen noch den Prozess des Anhängens einer Funktion an ein Ereignis erörtern. Hier geschieht die Magie. Die oben aufgeführten Ereignisse treten alle auf, unabhängig davon, ob Sie JavaScript geschrieben haben oder nicht. Um ihre Leistung zu nutzen, müssen Sie "Ereignishandler" registrieren. Dies ist ein ausgefallener Begriff, um eine Funktion zu beschreiben, die zur Behandlung eines Ereignisses verwendet wird. Hier ist ein einfaches Beispiel mit dem grundlegenden Ereignisregistrierungsmodell (auch als "traditionelle Ereignisregistrierung" bezeichnet):

Grundlegende Eventregistrierung:

Wir haben eine HTML-Schaltfläche mit der ID 'my-button' und haben mit dem Befehl 'document.getElementById' darauf zugegriffen. Dann erstellen wir eine neue Funktion, die später der DOM-Eigenschaft 'onclick' der Schaltfläche zugewiesen wird. Das ist alles dazu!

Das Modell der "grundlegenden Ereignisregistrierung" ist so einfach wie es nur geht. Sie stellen dem Ereignis, nach dem Sie suchen, 'on' voran und greifen als Eigenschaft des Elements, mit dem Sie arbeiten, darauf zu. Dies ist im Wesentlichen die unauffällige Version von so etwas (was ich nicht empfehle):

Die Inline-Ereignisbehandlung (unter Verwendung von HTML-Attributen) ist sehr aufdringlich und erschwert die Wartung Ihrer Website erheblich. Es ist besser, unauffälliges JavaScript zu verwenden und alles in den entsprechenden '.js'-Dateien zu enthalten, die bei Bedarf in das Dokument aufgenommen werden können. Während wir uns mit unauffälligem JavaScript befassen, möchte ich das verbreitete Missverständnis korrigieren, dass Bibliotheken wie jQuery es "möglich machen, unauffällig zu codieren" - dies ist nicht wahr. Wenn Sie jQuery verwenden, ist es genauso einfach, Dinge falsch zu machen. Der Grund, warum Sie die Inline-Ereignisbehandlung nicht verwenden sollten, ist genau der gleiche wie der Grund, warum Sie keine Inline-CSS-Stile anwenden sollten (mit style="").

Erweiterte Eventregistrierung:

Lassen Sie sich von diesem Namen nicht irreführen, nur weil er "fortgeschritten" heißt, heißt das nicht, dass es besser ist, ihn zu verwenden. Tatsächlich ist die oben diskutierte Technik ("Basisereignisregistrierung") die meiste Zeit perfekt geeignet. Die Verwendung der Basistechnik weist jedoch eine wesentliche Einschränkung auf. Sie können nicht mehr als eine Funktion an ein Ereignis binden. Das ist eigentlich nicht so schlimm, weil Sie einfach eine beliebige Anzahl anderer Funktionen innerhalb dieser einzelnen Funktion aufrufen können. Wenn Sie jedoch mehr Kontrolle benötigen, gibt es eine andere Möglichkeit, Handler zu registrieren. Geben Sie das "erweiterte Ereignisregistrierungsmodell" ein.

Mit diesem Modell können Sie mehrere Handler an ein einzelnes Ereignis binden. Dies bedeutet, dass beim Auftreten eines Ereignisses mehrere Funktionen ausgeführt werden. Darüber hinaus können Sie mit diesem Modell problemlos alle gebundenen Ereignishandler entfernen.

Genau genommen gibt es in dieser Kategorie zwei verschiedene Modelle. die W3Cs und Microsoft. Das W3C-Modell wird von allen modernen Browsern außer dem IE unterstützt, und das Microsoft-Modell wird nur vom IE unterstützt. So würden Sie das W3C-Modell verwenden:

Und hier ist das gleiche, aber für IE (Microsoft-Modell):

Und hier ist die 'introClick'-Funktion:

Aufgrund der Tatsache, dass keines der Modelle in allen Browsern funktioniert, ist es eine gute Idee, beide in einer benutzerdefinierten Funktion zu kombinieren. Hier ist eine sehr grundlegende 'addEvent'-Funktion, die browserübergreifend funktioniert:

Die Funktion sucht nach den Eigenschaften 'attachEvent' und 'addEventListener' und verwendet dann eines der von diesem Test abhängigen Modelle. Beide Modelle ermöglichen das Entfernen von Ereignishandlern, wie in dieser Funktion 'removeEvent' gezeigt:

Sie würden die Funktionen wie folgt verwenden:

Beachten Sie, dass wir als dritten Parameter eine namenlose Funktion übergeben haben. Mit JavaScript können wir Funktionen definieren und ausführen, ohne sie zu benennen. Funktionen dieses Typs werden als "anonyme Funktionen" bezeichnet und können sehr nützlich sein, insbesondere wenn Sie eine Funktion als Parameter an eine andere Funktion übergeben müssen. Wir hätten einfach unsere 'introClick'-Funktion (früher definiert) als dritten Parameter setzen können, aber manchmal ist es bequemer, dies mit einer anonymen Funktion zu tun.

Wenn Sie möchten, dass eine Aktion für ein Ereignis nur beim ersten Klicken ausgeführt wird, können Sie Folgendes tun:

Wir entfernen den Handler, sobald das Ereignis zum ersten Mal ausgelöst wird. Wir konnten im obigen Beispiel keine anonyme Funktion verwenden, da wir einen Verweis auf die Funktion ('oneClickOnly') beibehalten mussten, damit wir sie später entfernen konnten. Das heißt, es ist tatsächlich möglich, mit einer unbenannten (anonymen) Funktion zu erreichen:

Wir sind hier ziemlich frech, wenn wir auf die Eigenschaft 'callee' des Objekts 'arguments' verweisen. Das Objekt 'Argumente' enthält alle übergebenen Parameter der Funktion ANY sowie einen Verweis auf die Funktion selbst ('callee'). Auf diese Weise entfällt die Notwendigkeit, eine benannte Funktion zu definieren (z.B. die zuvor gezeigte Funktion 'oneClickOnly').

Abgesehen von den offensichtlichen syntaktischen Unterschieden zwischen der W3C- und der Microsoft-Implementierung gibt es einige andere bemerkenswerte Unterschiede. Wenn Sie eine Funktion an ein Ereignis binden, sollte die Funktion im Kontext des Elements ausgeführt werden. Daher sollte das Schlüsselwort 'this' in der Funktion auf das Element verweisen. Wenn Sie entweder das grundlegende Ereignisregistrierungsmodell oder das erweiterte W3C-Modell verwenden, funktioniert dies fehlerfrei. Die Implementierung von Microsoft schlägt jedoch fehl. Hier ist ein Beispiel dafür, was Sie in den Funktionen zur Ereignisbehandlung tun sollten:

Es gibt verschiedene Möglichkeiten, um dieses Problem zu vermeiden/zu beheben. Die mit Abstand einfachste Option ist die Verwendung des Basismodells. Bei Verwendung dieses Modells treten fast keine browserübergreifenden Inkonsistenzen auf. Wenn Sie jedoch das erweiterte Modell verwenden möchten und das Schlüsselwort 'this' benötigen, um das Element korrekt zu referenzieren, sollten Sie sich einige der weiter verbreiteten 'addEvent'-Funktionen ansehen, insbesondere die von John Resig oder Dean Edward (seine nicht) Ich benutze nicht einmal das fortschrittliche Modell, großartig!).

Das Ereignisobjekt

Ein wichtiger Aspekt der Ereignisbehandlung, den wir noch nicht besprochen haben, ist das sogenannte "Ereignisobjekt". Immer wenn Sie eine Funktion an ein Ereignis binden, d. H. Wenn Sie einen Ereignishandler erstellen, wird der Funktion ein Objekt übergeben. Dies geschieht nativ, sodass Sie keine Maßnahmen ergreifen müssen, um dies zu induzieren. Dieses Ereignisobjekt enthält eine Vielzahl von Informationen zu dem gerade aufgetretenen Ereignis. Es enthält auch ausführbare Methoden, die verschiedene Verhaltenseffekte auf das Ereignis haben. Es überrascht jedoch nicht, dass Microsoft seinen eigenen Weg gewählt hat, um diese "Funktion" zu implementieren. IE-Browser übergeben dieses Ereignisobjekt nicht, sondern müssen als Eigenschaft des globalen Fensterobjekts darauf zugreifen. Das ist nicht wirklich ein Problem, es ist nur ein Ärgernis:

Um die Existenz des 'e'-Objekts (des "Ereignisobjekts") zu überprüfen, verwenden wir einen ODER-Operator (logisch), der im Wesentlichen Folgendes vorschreibt: Wenn' e 'ein "falscher" Wert ist (null, undefiniert, 0) usw.) dann 'window.event' 'e' zuweisen; Andernfalls verwenden Sie einfach 'e'. Dies ist eine schnelle und einfache Möglichkeit, das reale Ereignisobjekt in einer browserübergreifenden Umgebung abzurufen. Wenn Sie mit der Verwendung logischer Operatoren außerhalb einer IF-Anweisung nicht vertraut sind, eignet sich dieses Konstrukt möglicherweise besser für Sie:

Einige der nützlichsten Befehle und Eigenschaften dieses Ereignisobjekts sind leider in allen Browsern inkonsistent implementiert (d.h. IE im Vergleich zu allen anderen). Das Abbrechen der Standardaktion eines Ereignisses kann beispielsweise mit der Methode 'preventDefault()' des Ereignisobjekts erreicht werden, im IE jedoch nur mit der Eigenschaft 'returnValue' des Objekts. Also müssen wir wieder beide verwenden, um alle Browser unterzubringen:

Die Standardaktion eines Ereignisses ist das, was normalerweise als Ergebnis des Auslösens dieses Ereignisses geschieht. Wenn Sie auf einen Ankerlink klicken, navigiert der Browser standardmäßig zu dem im Attribut 'href' dieses Links angegebenen Speicherort. Manchmal möchten Sie diese Standardaktion jedoch deaktivieren.

Der Ärger 'returnValue'/'preventDefault' ist nicht von alleine. Viele andere Eigenschaften des Ereignisobjekts sind inkonsistent implementiert, sodass dies erforderlich ist, if/else/or das Überprüfungsmodell erforderlich ist.

Viele der heutigen JavaScript-Bibliotheken normalisieren das Ereignisobjekt, was bedeutet, dass Befehle wie 'e.preventDefault' im IE verfügbar sind. Beachten Sie jedoch, dass hinter den Kulissen die Eigenschaft 'returnValue' weiterhin verwendet wird.

Ereignis bubbling

Ereignisblasen, auch als "Ereignisausbreitung" bekannt, treten auf, wenn ein Ereignis ausgelöst wird und dieses Ereignis dann durch das DOM "bubbling". Das erste, was zu beachten ist, ist, dass nicht alle Ereignisse sprudeln, aber für diejenigen, die dies tun, funktioniert es folgendermaßen:

Das Ereignis wird auf das Zielelement ausgelöst. Das Ereignis wird dann auf jeden Vorfahren dieses Elements ausgelöst - das Ereignis sprudelt durch das DOM, bis es das oberste Element erreicht:

Event bubbling graphicEvent bubbling graphicEvent bubbling graphic
Ereignis bubbling, illustriert

Wie in der obigen Grafik gezeigt, wird beim Klicken auf einen Anker innerhalb eines Absatzes zuerst das Klickereignis des Ankers ausgelöst, und anschließend wird das Klickereignis für Absätze usw. ausgelöst, bis das Körperelement erreicht ist (der Körper ist das höchste DOM-Element das hat ein Klickereignis).

Diese Ereignisse werden in dieser Reihenfolge ausgelöst, sie treten nicht alle gleichzeitig auf.

Die Idee des Ereignisblasens mag zunächst nicht viel Sinn machen, aber schließlich wird klar, dass dies ein grundlegender Teil dessen ist, was wir als "normales Verhalten" betrachten. Wenn Sie einen Handler an das Klickereignis des Absatzes binden, erwarten Sie, dass er ausgelöst wird, wenn auf den Absatz geklickt wird, oder? Genau das stellt "Event Bubbling" sicher - wenn der Absatz mehrere untergeordnete Elemente hat (<span>s, <anchor>s, <em>s), sprudelt selbst wenn sie auf das Ereignis geklickt werden, bis zum Absatz.

Dieses Blasenverhalten kann zu JEDER Zeit während des Prozesses gestoppt werden. Wenn Sie also möchten, dass das Ereignis nur bis zum Absatz, aber nicht weiter (nicht bis zum Hauptknoten) sprudelt, können Sie eine andere nützliche Methode verwenden, die im Ereignisobjekt "stopPropagation" enthalten ist:

Ereignisdelegation

Angenommen, Sie haben eine massive Tabelle mit vielen Datenzeilen. Das Binden eines Click-Event-Handlers an jeden einzelnen <tr> kann ein gefährliches Unterfangen sein, vor allem aufgrund der negativen Auswirkungen auf die Leistung. Ein üblicher Weg, um dieses Problem zu bekämpfen, ist die Verwendung der "Ereignisdelegation". Die Ereignisdelegierung beschreibt den Vorgang, bei dem ein Ereignishandler auf ein Containerelement angewendet und anschließend als Grundlage für alle untergeordneten Elemente verwendet wird. Durch Testen der Eigenschaft 'target' ('srcElement' im IE) des Ereignisobjekts können wir das tatsächlich angeklickte Element bestimmen.

Die Ereignisdelegation basiert auf dem Sprudeln von Ereignissen. Der obige Code würde nicht funktionieren, wenn das Sprudeln gestoppt würde, bevor der 'table'-Knoten erreicht wird.

Das war alles für heute!

Wir haben uns mit der Manipulation von DOM-Elementen befasst und das Browser-Ereignismodell ausführlich erörtert. Ich hoffe du hast heute etwas gelernt! Wenn Sie Fragen haben, zögern Sie bitte nicht, diese zu stellen.

  • Abonnieren Sie den NETTUTS RSS Feed für weitere tägliche Webentwicklungs-Tuts und Artikel.


Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.