phpundmysql.de

Archiv der Kategorie ‘JavaScript’

CDN für Vernachlässigte: JavaScript aus dem Content Network

Montag, April 30th, 2012

jQuery gehört zu den Vorzeigeprojekten, die in unzähligen Webseiten zum Einsatz kommen. Viele Webserver binden die Bibliothek aus dem Google CDN (Content Delivery Network) ein. Davon profitieren alle Anwender, denn eine aktuelle Datei befindet sich zumeist schon im Browsercache und muss nicht erneut aus dem Netz geladen werden. Und wenn doch, dann kommt sie von einem Server "in der Nähe". Google hält aber nur eine Hand voll der am meisten benutzten Bibliotheken für den Zugriff parat.
CDNJS möchte diese Lücke füllen und hat eine Sammlung weniger bekannter Libraries zusammengestellt, die auf einem CDN gehostet wird. Wobei "weniger bekannt" schon fast eine Beleidigung ist. Immerhin finden sich auch Yahoos YUI, Modernizr und Twitters Bootstrap darunter. In der zweiten Reihe stehen underscore, zepto, backbone und eine ganze Menge jQuery Plugins.

Die Zusammenstellung der Bibliotheken kommt durch Abstimmung aus der Community zustande. Es besteht eine ständige Diskussion direkt auf der Webseite, wo Vorschläge für potentielle Neuzugänge gesammelt werden und das Votum per Mausklick stattfindet (Authentifizierung erfolgt mit einer Emailadresse oder per Facebook/Google Account). Das Hosting der aktuellen Auswahl übernimmt freundlicherweise Cloudflare, ein Unternehmen aus San Francisco, Kalifornien.

Quick Tipp: Syntax Highlighting mit CodeMirror

Freitag, April 13th, 2012

Für ein Projekt habe ich einen möglichst schlanken, frei verfügbaren JavaScript Syntax Highlighter gebraucht, der mir PHP Code in einem Textfeld on-the-fly einfärbt. Fündig geworden bin ich bei CodeMirror, einen MIT-lizensierten Bibliothek, die sich genau auf diesen Anwendungsfall spezialisiert hat.

Man nehme eine HTML Textarea, spezifiziere in zwei Zeilen Code, wie der Editor aussehen soll und welche Programmiersprache darin eingetippt wird, und schon verwandelt CodeMirror das mehrzeilige Textfeld in einen ansehnlichen Editor. Viel Funktionalität ist nicht enthalten, immerhin ist CodeMirror nicht als WYSIWYG Editor gedacht. Dennoch ist der Editor nicht zu unterschätzen, wie zum Beispiel diese HTML Demo zeigt. Oder der FullScreen-Modus.


Nicht von dem Affen mit dem roten Hintern auf CodeMirror.net ablenken lassen!

CodeMirror unterstützt mehr als 40 Sprachen und Dialekte. Entsprechend wuchtig kommt der Download daher - glücklicherweise kann man sich ein maßgeschneiderten Build selbst zusammenklicken. Für PHP liegt man dann bei etwa 70kb, für MySQL sind es weniger als 60. Das Gros macht jecoch immer der Kern der Library aus.

Um Codemirror zu verwenden, muss wie üblich die JavaScript Datei in die eigene Seite eingebunden werden. Damit das Syntax Highlighting auch sichtbar wird, bedarf es zusätzlich eines Cascading Stylesheets.

<!-- wir befinden uns im Header, das JS kann wahlweise auch vor das /body Tag -->
<link rel="stylesheet" href="codemirror.css">
<script src="codemirror.js"></script>

Die Initialisierung erfolgt über einen weiteren JavaScript Aufruf

var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
        lineNumbers: true,
        mode: "application/x-httpd-php"
      });

Dieses Kommando greift auf die Textarea mit der ID code zu, der Modus ist PHP. Bei der Initialisierung wird das eigentliche textarea Element ausgeblendet und durch eine Struktur aus div Elementen ersetzt. Eine mittelmäßig ausführliche Dokumentation findet sich im Manual der Bibliothek.

P.S.: Das Icon stammt aus dem Flavours Icon Set von Oliver Twardowski.

querySelector: Der native Griff ins DOM

Montag, Februar 6th, 2012

Sizzle ist ein Segen. Die Selector-Engine von jQuery bietet den Zugriff auf eine Menge von DOM-Knoten in einem Einzeiler:

$('h1').css('color', 'red);

Ohne das musste man früher den Umweg über getElementsByTagName() gehen:

for (var i = 0; i &lt; document.getElementsByTagName('h1').length; i++) {
   document.getElementsByTagName('h1')[i].style.color = 'red';
}

Wie umständlich! Doch Rettung naht: querySelector() und querySelectorAll() werden von allen großen Browsern in ihren aktuellen Versionen unterstützt (siehe caniuse.com).

Der Unterschied der beiden Funktionen ist, dass querySelector() nur das jeweils erste Element zurückliefert, querySelectorAll() logischerweise alle betroffenen Elemente. Analog zu Sizzle verstehen diese beiden Funktionen alle vom Browser unterstützten CSS Selektoren, wie auch der Artikel der Blogeintrag vom Mozilla Developer Network zu zeigen versucht:

var el = document.body.querySelector("style[type='text/css'], style:not([type])");

In Anbetracht dessen, dass jQuery mittlerweile mehr als 90 Kilobyte auf die Waage bringt, fragt man sich: muss es denn immer das Framework sein!?

Kartenmaterial mit Leaflet

Dienstag, November 29th, 2011

Leaflet stammt aus dem Hause Cloudmade, seines Zeichens bekannt für lokale Dienste (Location Based Services). Die BSD-lizensierte JavaScript Library greift im Hintergrund auf das Kartenmaterial von OpenStreetMap zurück, wobei sie geschickt mit Layern (wie OpenLayer) umgeht - das erlaubt beispielsweise Blendeffekte, um von Tag- auf Nachtsicht umzuschalten. CloudMade hat übrigens einige ansehnliche TileLayer im Angebot, die sich per API ansprechen lassen.

Neben den üblichen Markern für den aktuellen Standort, Symbolen für Restaurants oder Bushaltestellen lassen sich dank GeoJSON auch farbige Polygone oder Kreise auf die Karten zeichnen, man kann Popups für Marker erstellen und als wäre es selbstverständlich, kann die Library auch mit Events umgehen.

Obwohl die Library schon einen sehr guten Eindruck macht, wird sie scheinbar sehr aktiv weiterentwickelt. Einträge im Github-Repository sind nur wenige Tage alt. Wer die Entwicklung mitverfolgen möchte, kann das beispielsweise via Twitter unter @LeafletJS tun.


PS: Das Blatt-Icon ist nicht das offizielle Logo von Leaflet-JS und entstammt dem 48px web iconset.

Das HTML5 <summary> Tag mit allen Browsern nutzen

Samstag, Oktober 22nd, 2011

Vorweg gesagt: es hat einen guten Grund, warum summary und details Tags weder in gleichem Maß bekannt sind noch genutzt werden wie z.B. header und footer. Bislang sind sie nicht über den Status eines Drafts hinaus gekommen. Es kann sich in der weiteren Spezifikation noch etwas ändern, was auch die Zurückhaltung bei der Umsetzung durch Browserhersteller erklärt.

Eine übersichtliche Einführung zu summary/details findet sich unter QuackIt, aus dem wir für die folgenden Erläuterungen kurzerhand das Beispiel übernehmen:

<details>
	<summary>Name</summary>
	<p>Homer J Simpson</p>
</details>
<a href="http://www.quackit.com/html_5/tags/html_summary_tag.cfm">Quelle: QuackIt</a>

Innerhalb des details Elements gibt es zum einen den Kurztext summary und ein weiteres Element mit beliebig viel Inhalt. Gedacht ist dieses Konstrukt für Webseiten, die beim Laden aus Platz-, Layout- oder sonstigen Gründen nur einen kurzen Anreissertext wie z.B. eine Überschrift anzeigen wollen. Damit der Leser den gesamten Text lesen kann, bedarf es eines Klicks auf den Anreisser. Denkbar wäre das als Ersatz für ein Accordion, z.B. bei der Anzeige der Diskographie einer Band oder bei der Vita eines Blogautors.
Im Unterschied zum Accordion bedarf es in Zukunft keines JavaScripts mehr. Der Browser soll dieses semantisch eindeutige Konstrukt nativ unterstützen - ganz wie neue input Typen.

Wenn Sie obiges Beispiel in eine HTML Datei kopieren und ausführen, werden Sie in vielen Fällen nichts von der beschriebenen Funktionalität zu sehen bekommen. Standardmäßig werden sowohl Inhalt des summary als auch das p Tags angezeigt, beim Klicken auf "Name" geschieht nichts. Gemäß Auflistung unter Can I Use ist Google Chrome ab Version 12 der einzige Mainstream-Browser mit Support, der optisch sofort durch einen Pfeil vor der summary deutlich wird, der so nicht im HTML Code auftaucht.

Um den gleichen Effekt in den übrigen größen Browsern zu erreichen, bedarf es allerdings nur einer kleinen Anpassung am Source-Code. Ziel muss sein, die native Unterstützung des Chrome so zu erhalten wie sie ist. Die folgende Implementierung muss demnach zwei Aufgaben erfüllen:

  • Erkennen, ob Chrome der aktuelle Browser ist
  • Funktionalität nachrüsten, wenn die erste Bedingung nicht zutrifft.

Leider unterstützt modernizr das summary/details noch nicht, so dass wir auf andere Hilfsmittel angewiesen sind. CSS und jQuery reichen dafür theoretisch vollkommen aus. Um komfortabel den Browsertyp auszulesen, nehmen wir noch CSS User Agent hinzu. Wir erweitern unser HTML oberhalb des </body> also um folgendes:

<script type="text/javascript" src="cssua.min.js"></script>
<script type="text/javascript" src="jquery-1.6.1.min.js"></script>

Das gibt uns Zugriff auf das cssua Objekt in JavaScript. Sofern ein Leser mit dem Google Chrome Browser ab Version 12 auf unsere Seite kommt, haben wir nichts zu tun. Dann greift nämlich die native Unterstützung des summary Tags. Andererseits müssen wir per jQuery dafür Sorge tragen, dass das p Tag ein- bzw. ausgeblendet wird. Das erreichen wir mit folgendem JavaScript-Schnipsel:

$(function() {
	if (typeof cssua.userAgent.chrome === "undefined" || cssua.userAgent.chrome < "12") {
 
		$("summary").click(function(){
			$(this).toggleClass("minified");
 
			$(this).siblings("p").fadeToggle("fast", "linear");
 
		});	
	}
 
});

Das toggleClass hat eigentlich wenig mit der Funktionalität zu tun. Wir haben es lediglich eingefügt, um der Optik nachzuhelfen. Mit etwas CSS können wir nämlich in Abhängigkeit davon, ob die Details ein- oder ausgeblendet sind, vor der summary einen Pfeil nach rechts oder unten anzeigen. Der Code sieht wie folgt aus:

html:not(.ua-chrome) summary:before { content:"v "; }
html:not(.ua-chrome) summary.minified:before { content:"> "; }
p { width: 200px; background-color: #cccccc; }

Wannimmer die Details eingeblendet sind, erscheint damit vor der Summary ein Pfeil nach unten, in unserem Beispiel angedeutet durch ein V. Stattdessen ist bei ausgeblendeten Details ein Pfeil nach rechts zu sehen, dargestellt als schließende spitze Klammer (>). Selbstverständlich könnte man diese Zeichen leicht durch hübsche austauschen, das überlassen wir aber den geneigten Programmierer.

Das ganze Beispiel am Stück liest sich wie folgt:

<!DOCTYPE HTML>
<html lang="en-US">
<head>
	<meta charset="UTF-8">
	<title>HTML5 Summary in all Browsers</title>
	<style type="text/css">
		html:not(.ua-chrome) summary:before { content:"v "; }
		html:not(.ua-chrome) summary.minified:before { content:"> "; }
		p { width: 200px; background-color: #cccccc; }
	</style>
</head>
<body>
	<details>
		<summary>Name (eingeklappt)</summary>
		<p>Homer J Simpson</p>
	</details>
	<a href="http://www.quackit.com/html_5/tags/html_summary_tag.cfm">Quelle: QuackIt</a>
<script type="text/javascript" src="cssua.min.js"></script>
<script type="text/javascript" src="jquery-1.6.1.min.js"></script>
<script type="text/javascript">
$(function() {
	if (typeof cssua.userAgent.chrome === "undefined" || cssua.userAgent.chrome < "12") {
 
		$("summary").click(function(){
			$(this).toggleClass("minified");
			$(this).siblings("p").fadeToggle("fast", "linear");
		});
	}
});
</script>
</body>
</html>

Aus PhoneGap wird Apache Callback

Dienstag, Oktober 4th, 2011

Die bekannte mobile Entwicklungsplattform PhoneGap wird an die Apache Foundation übergeben, um auch zukünftig als Open Source Software weiterentwickelt zu werden. Als Zeichen der Neuerung benennt man sich im gleichen Moment um, derzeit präferiert man den Namen Apache Callback. Die Software war gerade erst in der Version 1.0 für Apple iOS, Google Android, RIM BlackBerry, Microsoft Windows Phone 7, HP webOS, Nokia Symbian und Samsung Bada erschienen ist.

Lizenztechnisch wird sich für Anwender und Entwickler wenig ändern. Der Code wird unter die Apache Lizenz gestellt, die der aktuellen MIT/BSD Lizenz ähnelt.

Und der Neuigkeiten nicht genug: Einstimmig ist von Adobe und Nitobi zu hören, man habe sich auf eine Akquisition geeinigt. Ab Ende 2011 soll der Hersteller der mobilen Entwicklungsplattform somit in das Portfolio von Adobe aufgenommen werden. Da man PhoneGap bereits in einigen Produkten unterstütze, sei dies ein logischer Schritt. Dies beeinträchtigt die Entscheidung nicht, das Vorzeigeprodukt von Nitobi an die Apache Foundation zu übergeben. Details über den Deal wurden nicht bekannt. Informationen finden sich im Nitobi Blog.

Modernizr nach dem Baukastenprinzip

Dienstag, Juli 12th, 2011

Die Entwickler von Modernizr machen sich überhaupt nicht mehr die Mühe, vorgefertigte Versionen auf der Webseite zum Download zur Verfügung zu stellen. Stattdessen existiert lediglich eine Art Baukasten zum Zusammenklicken aller nötigen Features, wie man ihn mittlerweile auch von der HTML5 Boilerplate gewohnt ist. Überraschend ist das nicht, immerhin haben bei Framework und Library jeweils dieselben Entwickler die Finger im Spiel.

Als geneigter Anwender kommt man jedoch nicht umhin, sich mit der Materie auszukennen, um sich das passende Build zu erschaffen. Immerhin gilt es, aus über 50 Möglichkeiten aus den Bereichen HTML5, CSS3, Misc (Geolocation API, SVG, WebGL...) und Extras (Modernizr API, Media Queries...) genau das heraus zu finden, was man auf seiner Webseite einzusetzen gedenkt. Das ist zugegeben nicht immer einfach, denn manche Optionen haben auf gewöhnlichen Webseiten Seltenheitscharakter - schon mal SVG Clip Paths oder SMIL eingesetzt?

Allzu akribisch muss man aber nicht werden. Bei einer mittleren Anzahl von Optionen kommt man allerdings schnell unter 10 Kilobyte und hat seine Webseite damit wieder ein Stück bandbreitenschonender gemacht. Gerade die wachsende Gemeinde mobiler Surfer wird einem das danken.

Verzögerte Objekte in jQuery 1.5

Freitag, Februar 25th, 2011

"Wenn nicht jetzt, wann dann?" sangen schon die Höhner. jQuery beantwortet diese Frage ab Version 1.5 mit einem

1
$.when(ajaxCall1(), ajaxCall2(), weitereCalls()).then(successCallback(), errorCallback());

Ajax Aufrufe - in diesem Kontext stellen sie verzögerte Objekte dar - lassen sich demnach gruppieren. jQuery behält ein Auge auf ihre Ausführung und ruft die Callback-Funktionen auf, sobald alle Calls abgearbeitet sind. Abhängig vom Erfolg bzw. Misserfolg der einzelnen Aufrufe werden entweder der successCallback() oder der errorCallback() ausgeführt.

Dass die neuen gemeinsamen Callbacks bestehen, soll jedoch nicht heißen, dass nicht jeder AJAX Aufruf seine eigenen Callbacks definieren kann. Jedes verzögerte Objekt kann selbständig agieren. Eine gängige Referenz ist etwa $.ajax(). Die Callbacks unter .then() werden zusätzlich und abhängig von der Ausführungsdauer der übrigen AJAX Calls gegebenenfalls deutlich später durchlaufen.

Verzögerte Objekte in jQuery 1.5 können allerdings noch deutlich mehr als obiges Beispiel zeigen kann. Der Befehl .then() ist einer unter vielen. Eine vollständige Referenz kann in der jQuery Dokumentation eingesehen werden.

Mit Ajax auf fremde Domains zugreifen

Samstag, November 20th, 2010

Konsequenz der Same Domain Policy war es, dass viele Webseiten den eigenen Server nur als Proxy für Requests auf andere Domains missbrauchen. Die wenig wählerische Serverseite besorgt dabei die Daten von einer fremden Domain, beispielsweise mit einem simplen cURL Aufruf, und leitet sie als Antwort auf den Ajax Call an den Browser durch.

Allerdings ist dieser Umweg nicht immer nötig. Dass man beim Zugriff auf eine fremde Domain häufig von einer Fehlermeldung behelligt wird, der Ajax Request ließe sich nicht ausführen, ist keine Spielverderberei des Browsers. In Wirklichkeit wird der Request vom Browser durchaus an den fremden Server verschickt, nur dieser blockt sie ab. Diesem Missmut auf Serverseite lässt sich in der Regel mit einer simplen XML Datei namens crossdomain.xml abhelfen, die im root-Verzeichnis des Servers abzulegen ist.

Folgendes Beispiel bringt etwa die HTML5 Boilerplate standardmäßig mit:

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM 
    "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<!--
   <allow-access-from domain="*" to-ports="*" />
-->
</cross-domain-policy>

Die XML Datei enthält eine Whitelist. Wer hier auftaucht, darf zugreifen. Der auskommentierte Teil mit dem Element allow-access-from öffnet dabei Tür und Tor für spezielle oder alle Domains. Der Stern (*) in domain und port ist eine Wildcard und erlaubt somit jeden Zugriff. Spezifischer werden Sie, wenn Sie unter domain="" diejenigen Domains eingeben, denen Sie explizit den Zugang erlauben wollen.

Wobei DOMAssistant einem zur Hand geht

Donnerstag, November 18th, 2010

In gewissem Sinne lässt sich jQuery mit Amazon oder Facebook vergleichen: mit dem Erreichen der kritischen Nutzermasse haben sie die Konkurrenz in den Hintegrund verdrängt. Die Wettbewerber sind allerdings nicht vollständig von der Bildfläche verschwunden, sondern arbeiten ungehindert weiter. Mitunter kommen sogar noch neue Alternativen hinzu. DOMAssistant ist so ein Fall.

Das DOMAssistant Core Modul ist im wesentlichen die Selector Engine, die es erlaubt, einzelne oder eine Menge von DOM Elementen auszuwählen und durchzugehen. Sein Funktionsumfang hält keine Überraschungen bereit, legt aber einen soliden Grundstein für die folgenden darauf aufbauenden Module:

  • Content - Einfügen, Ersetzen und löschen von DOM-Inhalten
  • Ajax - Senden von asynchronen Requests und Verarbeitung der Ergebnisse per Callback
  • CSS - Auslesen und Setzen von Stylesheet Eigenschaften
  • Events - Reaktionen auf ablaufende Ereignisse
  • Load - Ausführen von Anweisungen nach dem vollständigen Laden des DOM

Die AJAX Implementierung lässt Wünsche offen. Die beiden Shortcut-Funktionen get() und post() nehmen mindestens die URL des Requests entgegen, hinzu kommt maximal aber eine Callback-Funktion, die nach dem AJAX Call die empfangenen Daten weiterverarbeitet. Die Möglichkeit, den Datentyp der Rückgabewerte oder gar zusätzliche Aufrufparamter festzulegen, fehlen. Letzteres ist über GET-Parameter in der URL realisierbar:

DOMAssistant.AJAX.post("url.php?number=10", callbackFunction);

Was für GET-Requests noch vertretbar erscheint, konterkariert den POST-Request in seiner Sache. Wer mehr Optionen benötigt, muss auf die generische ajax() Funktion zurückgreifen, die dem Gegenstück in jQuery stark ähnelt.

Dass die Implementierung keine synchronen Aufrufe erlaubt, ist vor dem Hintergrund als kleineres Übel zu verschmerzen. Praktisch hingegen ist die Möglichkeit, die AJAX Requests im Kontext eines Elements zu machen, auf den der Callback referenzieren kann. So läd

$("#news").load("url.php");

das eintreffende HTML in das vorhandene Element mit der ID news.

Die Content und CSS Module bieten Lösungen für die gängigen Probleme. Einige Wrapper Funktionen für bereits Mögliches wären schön: So fehlt z.B. ein toggleClass(), was mit einer Kombination von hasClass() und addClass()/removeClass() behoben werden kann. Auch Auskünfte zur Positionierung einzelner Elemente sucht man auf den ersten Blick vergebens. Auffällig ist wiederum, dass es zwar Setter für HTML Attribute gibt, aber keinen passenden Getter. Zur Ehrenrettung der Library sei aber erwähnt, dass man sehr wohl mit der Selector Engine auf Attribute zugreifen kann:

$("#container input[type=text]");

Letztlich hat der DOMAssistant aber noch einige Highlights auf Lager, die positiv hervorzuheben sind. Zum einen unterstützt die Library das liebgewonnene Method Chaining und die ebenso beliebten Closures. Ehrlich gesagt gehören diese Features allerdings bereits zu den Grunderwartungen an eine moderne JavaScript Library. Wem der vorhandene Funktionsumfang nicht ausreicht, kann diese per Plugin erweitern. Im "Repository" auf der DOMAssistant Webseite finden sich aktuell aber nur eine gute Handvoll Plugins. Hier kann man auf Dauer mehr erwarten. Umfassend ist hingegen die Liste der CSS Selektoren, die sich in der Selector Engine adressieren lassen.

Fazit

Der Fokus der JavaScript Library liegt auf der DOM-Manipulation - bei dem Namen ist das auch kein Stück überraschend. Ein jQuery- oder YUI-Ersatz erwächst damit demnach nicht. DOMAssistant kommt dabei eher als Generalist daher. Wo die Platzhirsche dem Programmierer mit Wrappern angenehmen Komfort bieten, sind diese im DOM Assistenten erst noch implementiert werden. Bevor man allerdings an der Komfortschraube dreht, sollte der Fokus auf der Erweiterung der grundlegenden Funktionalität liegen - siehe Getter/Setter.