<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Emanuel Kluge &#187; jQuery</title>
	<atom:link href="http://www.emanuel-kluge.de/category/jquery/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.emanuel-kluge.de</link>
	<description>Zeitgenössisches Web-Design aus Hannover</description>
	<lastBuildDate>Wed, 18 Jan 2012 07:06:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Daten sukzessive, asynchron laden mit dem Pub-Sub-Pattern</title>
		<link>http://www.emanuel-kluge.de/html-css/daten-sukzessive-asynchron-laden-mit-dem-pub-sub-pattern/</link>
		<comments>http://www.emanuel-kluge.de/html-css/daten-sukzessive-asynchron-laden-mit-dem-pub-sub-pattern/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 16:31:33 +0000</pubDate>
		<dc:creator>Emanuel</dc:creator>
				<category><![CDATA[HTML/CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.emanuel-kluge.de/?p=1500</guid>
		<description><![CDATA[Derzeit bin ich mit dem Bau einer Web-App beschäftigt, die initial einen Haufen Daten asynchron laden soll. Dafür könnte ich zwar ganz einfach ein paar $.ajax-Funktionen nacheinander aufrufen, doch hat diese Methode ihre Nachteile: Es bestehen Abhängigkeiteen zwischen den zu ladenden Daten, so dass sicher gestellt sein muss, dass die Daten vom Typ A fertig [...]]]></description>
			<content:encoded><![CDATA[<p>Derzeit bin ich mit dem Bau einer Web-App beschäftigt, die initial einen Haufen Daten asynchron laden soll. Dafür könnte ich zwar ganz einfach ein paar $.ajax-Funktionen nacheinander aufrufen, doch hat diese Methode ihre Nachteile:</p>
<ol>
<li>Es bestehen Abhängigkeiteen zwischen den zu ladenden Daten, so dass sicher gestellt sein muss, dass die Daten vom Typ A fertig geladen sind, bevor das Laden der Daten vom Typ B startet <abbr title="beziehungsweise">bzw.</abbr> starten kann.</li>
<li>Der Fortschritt des Ladevorgangs soll visualisiert werden, heißt, ist ein Ladevorgang abgeschlossen und es beginnt der nächste, soll ein Ladebalken vorwärts schreiten.</li>
</ol>
<p>Es wird ersichtlich, dass es nicht damit getan ist, die AJAX-Calls hintereinander aufzurufen. Vielmehr braucht es eine ordnende Instanz, die dafür sorgt, dass die Aufrufe sauber von einander getrennt ablaufen und zwischendurch Callback-Funktionen aufgerufen werden können. Um das zu erreichen, greife ich auf <a href="http://msdn.microsoft.com/en-us/scriptjunkie/hh201955.aspx">das Pub-Sub-Pattern von Addy Osmani</a> zurück und kombiniere es mit einer <em>InitialDataloader</em>-Funktion. Die AJAX-Funktionalitäten hole ich mir von jQuery.</p>
<p>Im folgenden das Pub-Sub-Pattern:</p>
<pre class="prettyprint">
<dfn>JavaScript</dfn>
<code class="block">
var mediator = (function () {

	function subscribe(channel, fn) {

		if ( !mediator.channels[channel] ) {
			mediator.channels[channel] = [];
		}

		mediator.channels[channel].push({
			context : this,
			callback : fn
		});

		return this;

	}

	function publish(channel, context) {

		var i = 0,
			len,
			args,
			subscription;

		if ( !mediator.channels[channel] ) {
			return false;
		}

		args = Array.prototype.slice.call(arguments, 2);
		len = mediator.channels[channel].length;

		for ( ; i&lt;len; i += 1 ) {
			subscription = mediator.channels[channel][i];
			subscription.callback.apply((context || subscription.context), args);
		}

		return this;

	}

	return {
		channels : {},
		publish : publish,
		subscribe : subscribe,
		installTo : function (obj) {
			obj.subscribe = subscribe;
			obj.publish = publish;
		}
	}

})();
</code>
</pre>
<p>Auf das Pub-Sub-Pattern möchte ich gar nicht weiter eingehen. Lediglich der Hinweis, dass ich die <em>Publish</em>-Funktion um die Möglichkeit ergänzt habe, einen eigenen Kontext zu übergeben.</p>
<p>Kommen wir als nächstes zur <em>InitialDataloader</em>-Funktion:</p>
<pre class="prettyprint">
<dfn>JavaScript</dfn>
<code class="block">
var InitialDataloader = function (args) {
	this.args = args;
	this.result = [];

	this.init();
};

InitialDataloader.prototype.init = function () {

	var i = 0,
		len = this.args.length;

	if ( !len ) {
		return;
	}

	for ( ; i&lt;len; i+=1 ) {
		mediator.subscribe(this.args[i], this.load);
	}

	mediator.publish(this.args[0], this, {path : this.args[0], next : 1});

};

InitialDataloader.prototype.load = function (obj) {

	var that = this,
		deferred = $.ajax({url : obj.path});

	deferred.success(function (resp) {
		that.result.push(&#x27;Data&#x27; + obj.next + &#x27; loaded&#x27;);
	});

	deferred.then( function (resp) {
		if ( obj.next === that.args.length ) {
			console.log(that.result);
		} else {
			mediator.publish(that.args[obj.next], that, {path : that.args[obj.next], next : obj.next+1});
		}
	});

};
</code>
</pre>
<p>in der Konstruktor-Funktion werden die Argumente entgegen genommen und der Prozess via der <em>init</em>-Funktion gestartet. Das args-Argument stellt dabei einen Array dar, der die Pfade zu den Daten enthält.</p>
<p>In der <em>init</em>-Funktion wiederum wird für jeden Pfad des args-Array eine Funktion im Pub-Sub-Pattern angemeldet. Anschließend wird das erste Element des Pub-Sub-Patterns &ldquo;veröffentlicht&rdquo;, sprich die  <em>load</em>-Funktion mit dem ersten Pfad aufgerufen und der Zähler zum nächsten Element des Pfad-Arrays mit übergeben.</p>
<p>Innerhalb der <em>load</em>-Funktion wird ein AJAX-Call auf den übergebenen Pfad gemacht und an ein <em>deferred</em>-Objekt übergeben. Dies wird anschließend genutzt, um eine <em>Callback</em>-Funktion zu starten, wenn der Ladevorgang abgeschlossen ist, und anschließend entweder das nächste Element des Pfad-Array im Pub-Sub-System zu &ldquo;veröffentlichen&rdquo; oder &ndash; wenn alle AJAX-Calls gemacht sind &ndash; eine finale Funktion aufzurufen (<em>console.log(that.result);</em>).</p>
<p>Anschließend noch der Aufruf der Funktion:</p>
<pre class="prettyprint">
<dfn>JavaScript</dfn>
<code class="block">
var initialDataLoad = new InitialDataloader([
	&#x27;http://apple.com/&#x27;,
	&#x27;https://twitter.com/&#x27;,
	&#x27;http://www.spiegel.de/&#x27;,
	&#x27;http://www.flickr.com/&#x27;
]);
</code>
</pre>
<p>Die Adressen sind willkürlich gewählt.</p>
<p>Wenn man den Code in ein Skript packt und im Browser laufen lässt, sieht man in der Konsole nacheinander die AJAX-Calls und abschließend die Ausgabe des <em>this.result</em>-Array, der die einzelnen, zu ladenden Elemente mitgezählt hat.</p>
<p>Das war es auch schon. Sollte es Fragen oder Anregungen, nutzt bitte die Kommentar-Funktion. Ich freue mich immer über Feedback!</p>
<hr /><p>Verwandte Beitr&auml;ge:<ul>
<li><a href='http://www.emanuel-kluge.de/tutorial/animierte-image-caption-mit-jquery-unter-wordpress/' rel='bookmark' title='Animierte Image-Caption mit jQuery unter WordPress'>Animierte Image-Caption mit jQuery unter WordPress</a></li>
<li><a href='http://www.emanuel-kluge.de/tutorial/backbone-js-tutorial-die-merkliste/' rel='bookmark' title='Backbone.js-Tutorial: Die Merkliste'>Backbone.js-Tutorial: Die Merkliste</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.emanuel-kluge.de/html-css/daten-sukzessive-asynchron-laden-mit-dem-pub-sub-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Studie &#8220;Backboned&#8221;: AJAX-powered WordPress-Theme mit Backbone.js</title>
		<link>http://www.emanuel-kluge.de/html-css/ajax-wordpress-theme-backbone-js/</link>
		<comments>http://www.emanuel-kluge.de/html-css/ajax-wordpress-theme-backbone-js/#comments</comments>
		<pubDate>Thu, 14 Jul 2011 10:16:32 +0000</pubDate>
		<dc:creator>Emanuel</dc:creator>
				<category><![CDATA[HTML/CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[Theme]]></category>

		<guid isPermaLink="false">http://www.emanuel-kluge.de/?p=1317</guid>
		<description><![CDATA[Demo &#124; Download Um mir gelegentlich etwas Zerstreuung vom Lernen zu geben, habe ich einen lange gehegten Plan in die Tat umgesetzt: Ein AJAX-betriebenes WordPress-Theme mit Backbone.js zu bauen. Und zwar keine auf &#8220;Graceful Degradation&#8221; setzende Kompromisslösung. Alle Inhalte werden asynchron geladen und sind per Hashbang URIs ansteuerbar. Ein Blick in den Quellcode offenbart, was [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.emanuel-kluge.de/wp-content/uploads/2011/07/backboned-screenshot.gif" alt="&quot;Backboned&quot; &middot; AJAX-powered WordPress-Theme &middot; Screenshot" title="&quot;Backboned&quot; &middot; AJAX-powered WordPress-Theme &middot; Screenshot" width="480" height="207" class="aligncenter size-full wp-image-1333" /></p>
<div class="dedo"><a href="http://emanuel.kodingen.com/wordpress/" title="Demo &mdash; &quot;Backboned&quot;" rel="nofollow">Demo</a> | <a href="http://www.emanuel-kluge.de/wp-content/uploads/2011/07/backboned.zip" title="Download &mdash; &quot;Backboned&quot;" lang="en">Download</a></div>
<p>Um mir gelegentlich etwas Zerstreuung vom Lernen zu geben, habe ich einen lange gehegten Plan in die Tat umgesetzt: Ein <abbr title="Asynchronuos JavaScript And XML">AJAX</abbr>-betriebenes WordPress-Theme mit <a href="http://documentcloud.github.com/backbone/">Backbone.js</a> zu bauen. Und zwar keine auf &ldquo;Graceful Degradation&rdquo; setzende Kompromisslösung. Alle Inhalte werden asynchron geladen und sind per Hashbang <abbr title="Uniform Resource Identifier">URI</abbr>s ansteuerbar. Ein Blick in den Quellcode offenbart, was ich meine: Ein <abbr title="JavaScript Object Notation">JSON</abbr>-Objekt mit allen grundlegenden Daten, eine Handvoll jQuery-Templates und das <abbr title="Hypertext Markup Language">HTML</abbr>-Grundgerüst. Das war es an statischem Content - die Darstellung des Inhalts geschieht über Backbone.js.</p>
<p>Damit Suchmaschinen nicht außen vor bleiben und man sich nicht die Mühe machen muss, einen &ldquo;Headless Browser&rdquo; &agrave; la HtmlUnit auf seinem Server zum laufen bringen zu müssen, werden grundsätzlich alle Inhalte als GET-Anfrage mit dem Parameter &ldquo;_escaped_fragment_&rdquo; abgehandelt - die Ausgabe variiert dann je nachdem zwischen statischem <abbr title="Hypertext Markup Language">HTML</abbr> oder einem nackten <abbr title="JavaScript Object Notation">JSON</abbr>-Objekt. So ist sichergestellt, dass die Inhalte trotzdem indiziert werden können. Die einzigen, die in die Röhre schauen, sind Besucher ohne JavaScript.</p>
<p>Um diesen Workaround zu realisieren, war jedoch ein hohes Maß an Improvisation vonnöten. Mit WordPress-Bordmitteln habe ich es nicht geschafft, das Frontend-seitige <abbr title="Uniform Resource Locator">URL</abbr>-Routing von Backbone.js server-seitig abzubilden und entsprechend zu bearbeiten. Ich habe deshalb auf ein simples <abbr title="Model View Controller">MVC</abbr>-Pattern zurück gegriffen und in das eigentliche Theme eine Art Child-Theme integriert. Das ist insgesamt kein Ansatz der mir - besonders in meiner Umsetzung - gefällt. Des weiteren muss man für einen störungsfreien Betrieb des Themes das <abbr title="Uniform Resource Locator">URL</abbr>-Rewriting in den WordPress-Einstellungen deaktivieren.</p>
<p>Darüber hinaus bleibt anzumerken, dass das Theme insgesamt eher rudimentär ist. Ich würde von einem Produktiveinsatz abraten. Allerdings bin ich grundsätzlich von der Idee des Themes überzeugt und freue mich natürlich, wenn jemand sich ebenfalls dafür begeistern kann und daran weiterarbeitet. Gerne auch in Kollaboration mit mir. Zu tun gibt es unter anderem noch:</p>
<ol>
<li>die grundsätzliche Verbesserung des PHP-Codes (sicherer machen, besser in das WordPress-Environment integrieren,&hellip;)</li>
<li>den Funktionsumfang erhöhen (Neueste Kommentare, Tags, Suchfunktion, Sidebar-Widgets(?),&hellip;)</li>
<li>das JavaScript straffen (Performance, geschmeidigere <abbr title="Graphical User Interface">GUI</abbr>-Abläufe,&hellip;)</li>
</ol>
<p>&hellip;um ein paar Aspekte zu nennen.</p>
<p>Ansonsten freue ich mich wie immer über Anregungen und Verbesserungsvorschläge - gerade bei einem Vorhaben dieser Größenordnung hat man als Entwickler nicht wirklich einen umfassenden Überblick.</p>
<p><del datetime="2011-07-15T09:15:57+00:00">PS: Wahrscheinlich werde ich das Teil zeitnah bei GitHub reinladen. Muss mich da aber erst noch anschlauen.</del></p>
<p><ins datetime="2011-07-15T09:15:57+00:00"><strong>Update:</strong> Okay, die Geschichte ist jetzt auch auf GitHub - <a href="https://github.com/herschel666/Backboned" title="&ldquo;Backboned&rdquo; auf GitHub">https://github.com/herschel666/Backboned</a>. Viel Spaß.</ins></p>
<hr /><p>Verwandte Beitr&auml;ge:<ul>
<li><a href='http://www.emanuel-kluge.de/wordpress/free-wordpress-theme-blue-and-grey/' rel='bookmark' title='Free WordPress-Theme: &#8220;Blue and Grey&#8221;'>Free WordPress-Theme: &#8220;Blue and Grey&#8221;</a></li>
<li><a href='http://www.emanuel-kluge.de/tutorial/backbone-js-tutorial-die-merkliste/' rel='bookmark' title='Backbone.js-Tutorial: Die Merkliste'>Backbone.js-Tutorial: Die Merkliste</a></li>
<li><a href='http://www.emanuel-kluge.de/tutorial/semi-transparente-navigation-in-wordpress-mit-css/' rel='bookmark' title='Semi-transparente Navigation in WordPress mit CSS'>Semi-transparente Navigation in WordPress mit CSS</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.emanuel-kluge.de/html-css/ajax-wordpress-theme-backbone-js/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Backbone.js-Tutorial: Die Merkliste</title>
		<link>http://www.emanuel-kluge.de/tutorial/backbone-js-tutorial-die-merkliste/</link>
		<comments>http://www.emanuel-kluge.de/tutorial/backbone-js-tutorial-die-merkliste/#comments</comments>
		<pubDate>Mon, 30 May 2011 15:45:42 +0000</pubDate>
		<dc:creator>Emanuel</dc:creator>
				<category><![CDATA[HTML/CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Local Storage]]></category>
		<category><![CDATA[MVC]]></category>

		<guid isPermaLink="false">http://www.emanuel-kluge.de/?p=1288</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.emanuel-kluge.de/wp-content/uploads/2011/05/backbone.png" alt=""Backbone.js-Tutorial" title="Backbone.js-Tutorial" width="385" height="126" class="aligncenter size-full wp-image-1289" /></p>
<div class="dedo"><a href="http://www.emanuel-kluge.de/demo/backbone-js-merkliste/" title="Demo &mdash; Backbone.js-Tutorial: Die Merkliste" rel="nofollow">Demo</a> | <a href="http://www.emanuel-kluge.de/wp-content/uploads/2011/05/backbone-js-merkliste.zip" title="Download &mdash; Backbone.js-Tutorial: Die Merkliste" lang="en">Download</a></div>
<p><a href="http://documentcloud.github.com/backbone/">Backbone.js</a> ist ein interessantes JavaScript-<abbr title="Model - View - Controller">MVC</abbr>, mit welchem ich mich seit etwa zwei Wochen beschäftige. Und nun möchte ich ein kleines Tutorial dazu präsentieren - wir bauen uns ein Merkliste. Das Konzept sieht wie folgt aus: Ständig laufen einem tolle Filme, Bücher und Spiele über den Weg, die man unbedingt noch sehen/lesen/spielen möchte, aber man merkt sie sich nie. Das ist der Punkt, wo die Merkliste ins Spiel kommt.</p>
<p>Bei der Programmierung habe ich mich stark an der <a href="http://documentcloud.github.com/backbone/examples/todos/index.html">Todo List Application</a> orientiert, allerdings ist die Merkliste vom Funktionsumfang her schmaler, beinhaltet dafür aber einen Controller für das <abbr title="Uniform Resource Locator">URL</abbr>-Routing.</p>
<p>Aber nun zur Sache:</p>
<p>Als erstes benötigen wir den <abbr title="Hypertext Markup Language">HTML</abbr>-Teil.</p>
<pre class="prettyprint">
<dfn>HTML</dfn>
<code class="block">
&lt;!doctype html&gt;
&lt;html lang=&quot;de&quot;&gt;
&lt;head&gt;
	&lt;meta charset=&quot;utf-8&quot;&gt;
	&lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge,chrome=1&quot;&gt;

	&lt;title&gt;Backbone.js-Tutorial - Merkliste&lt;/title&gt;
	&lt;link rel=&quot;stylesheet&quot; href=&quot;style.css&quot; /&gt;

&lt;/head&gt;

&lt;body&gt;

	&lt;ul id=&quot;nav&quot;&gt;&lt;/ul&gt;
	&lt;input type=&quot;text&quot; placeholder=&quot;Gib einen Titel ein&amp;hellip;&quot; id=&quot;list_input&quot; /&gt;
	&lt;ul id=&quot;list&quot;&gt;&lt;/ul&gt;

	&lt;script src=&quot;https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js&quot;&gt;&lt;/script&gt;
	&lt;script src=&quot;http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.6/underscore-min.js&quot;&gt;&lt;/script&gt;
	&lt;script src=&quot;http://ajax.cdnjs.com/ajax/libs/backbone.js/0.3.3/backbone-min.js&quot;&gt;&lt;/script&gt;
	&lt;script src=&quot;js/backbone-localstorage.js&quot;&gt;&lt;/script&gt;
	&lt;script src=&quot;js/list.min.js&quot;&gt;&lt;/script&gt;

	&lt;script type=&quot;text/template&quot; id=&quot;list-item-template&quot;&gt;
		&lt;strong&gt;&lt;%= title %&gt;&lt;/strong&gt;
		&lt;span class=&quot;delete_item&quot;&gt;x&lt;/span&gt;
	&lt;/script&gt;

	&lt;script type=&quot;text/template&quot; id=&quot;nav-template&quot;&gt;
		&lt;a href=&quot;#/category/&lt;%= title %&gt;&quot;&gt;&lt;%= title %&gt;&lt;/a&gt;
	&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;
</code>
</pre>
<p>Für die Merklisten-App benötigen wir <a href="http://jquery.com/">jQuery</a>, <a href="http://documentcloud.github.com/underscore/">Underscore.js</a>, <a href="http://documentcloud.github.com/backbone/">Backbone.js</a> und die Backbone-Erweiterung <a href="http://documentcloud.github.com/backbone/docs/backbone-localstorage.html">Local-Storage</a>, damit die Einträge im Browser gespeichert werden können. Des weiteren werden die Container für die Navigation und die Listeneinträge, sowie das Eingabefeld angelegt. Schlussendlich brauchen wir noch zwei Templates - eins für die Navigation, eins für die Liste.</p>
<p>Kommen wir nun zum JavaScript-Teil. Als erstes benötigen wir hier unser Model:</p>
<pre class="prettyprint">
<dfn>JavaScript</dfn>
<code class="block">
window.List = Backbone.Model.extend();
</code>
</pre>
<p>Als nächstes erstellen wir zwei Collections, eine für die Navigation, eine für die Listeneinträge:</p>
<pre class="prettyprint">
<dfn>JavaScript</dfn>
<code class="block">
window.NavCollection = Backbone.Collection.extend({
	model : List
});

window.ListCollection = Backbone.Collection.extend({				

	model : List,				

	localStorage : new Store('List'),

	getByCategory : function ( category )
	{
		return this.filter( function (item)
		{
			return item.get('category') == category;
		});
	}
});
</code>
</pre>
<p>In der Collection für die Listen-Einträge wird der <em>Local Storage</em> angemeldet und eine Funktion eingefügt, die es ermöglicht, die Einträge der Collection nach ihrer Kategorie zu filtern.</p>
<p>Kommen wir nun zum Controller der App:</p>
<pre class="prettyprint">
<dfn>JavaScript</dfn>
<code class="block">
window.ListController = Backbone.Controller.extend({

	_navModel : new NavCollection([
		{title : 'Filme'},
		{title : 'Buecher'},
		{title : 'Spiele'}
	]),
	_navViews : [],
	_categoryModel : new ListCollection,
	_inputView : null,

	routes : {
		'' : 'init',
		'/category/:category' : 'getItems',
	},

	initialize : function ()
	{
		this._navModel.each( function ( item, i )
		{
			this._navViews[i] = new NavigationView({
				model : item
			});
		}, this);

		Backbone.history.start();
	},

	init : function ()
	{
		window.location.hash = '/category/Filme';
	},

	getItems : function ( category )
	{
		for ( view in this._navViews )
		{
			this._navViews[view]
				.render()
				.setClass();
		};

		if ( this._inputView == null )
		{
			this._inputView = new ListInputView({
				model : this._categoryModel,
				category : category
			});
		}
		else
		{
			this._inputView.options.category = category;
			this._inputView.model.trigger('refresh');
		}
	}

});
</code>
</pre>
<p>Als erstes werden - jeweils für die Navigation und die Liste - neue Instanzen der zugehörigen Collection erstellt und Platzhalter für die jeweiligen Views angemeldet. Danach werden die relevanten Pfade mit Funktionen verknüpft. In diesem Fall wird die Funktion <code class="inline">init()</code> ausgeführt, wenn kein <em>Hash</em> vorhanden ist, und die Funktion <code class="inline">getItems()</code>, wenn ein Kategorie-<em>Hash</em> vorhanden ist.</p>
<p>Als nächstes folgt die <code class="inline">initialize</code>-Funktion, welche als erstes beim Aufrufen des Controllers ausgeführt wird. Dabei wird das Navigation-Model mit den nötigen Einträgen versehen, danach für jeden Eintrag der Navigation-Collection eine View-Instanz erstellt und im _navView-Array gespeichert, sowie die <code class="inline">Backbone.history</code>-Funktion gestartet.</p>
<p>Als nächstes wird die <code class="inline">init</code>-Funktion definiert. Diese sorgt einfach nur dafür, dass die Kategorie "Filme" gewählt wird, indem der entsprechende Kategorie-<em>Hash</em> gesetzt wird. Die Kategorie ist hierbei willkürlich von mir gewählt.</p>
<p>Danach folgt die Definition der <code class="inline">getItems</code>-Funktion. In dieser werden als erstes die Views für die Navigationspunkte ge-rendert. Daraufhin folgt entweder die Initialisierung des Views für die Listeneinträge, oder - falls dies schon geschehen ist - das Überschreiben der aktuellen, dem View übergebenen Kategorie und das Neu-Aufbauen der Liste mit den entsprechenden Einträgen. Dabei kommt die Filter-Funktion der Listen-Collection zum Einsatz.</p>
<p>Nachdem nun Model, Collection und Controller vorhanden sind, geht es an die Views. Davon benötigen wir drei - einen für das Eingabefeld, einen für die Liste und einen für die Navigation. Fangen wir mit dem Eingabefeld an:</p>
<pre class="prettyprint">
<dfn>JavaScript</dfn>
<code class="block">
window.ListInputView = Backbone.View.extend({

	el : $('#list_input'),

	list : $('#list'),

	events : {
		'keypress' : 'createListItem'
	},

	initialize : function ()
	{
		_.bindAll(this, 'addListItem', 'addAllListItems');

		this.model.bind('add', this.addListItem);
		this.model.bind('refresh', this.addAllListItems);

		this.model.fetch();
	},

	createListItem : function (e)
	{
		if ( e.keyCode == 13 )
		{
			this.model.create({
				category : this.options.category,
				title : this.el.val()
			});

			this.el.val('');
			this.el.blur();
		}
	},

	addListItem : function ( item )
	{
		var view = new ListItemView({model : item});

		!view.model.length &#038;& this.list.append( view.render().el );
	},

	addAllListItems : function ()
	{
		this.list.empty();

		_.each(this.model.getByCategory(this.options.category), function(item)
		{
			this.addListItem(item);
		}, this);
	}

});
</code>
</pre>
<p>Der ListInputView nimmt die Eingabe entgegen, erstellt eine neue Instanz des Listen-Eintrag-View und fügt füllt die Liste mit Einträgen. Die Funktion <code class="inline">createListItem()</code> erstellt einen neuen Eintrag in der Collection, wenn das Eingabefeld abgefeuert wurde. Über die Angabe <code class="inline">this.model.bind('add', this.addListItem);</code> in der <code class="inline">initialize</code>-Funktion wird gesorgt, dass daraufhin die Funktion <code class="inline">addListItem()</code> aufgerufen wird, die für den neuen Eintrag in der Collection eine Instant des Listen-Eintrag-View erstellt und diesem den Befehl <code class="inline">render()</code> mit auf den Weg gibt. Über die Funktion <code class="inline">addAllListItems()</code> wird einerseits sichergestellt, dass die Liste geleert wird, bevor neue Einträge nach einem Kategorie-Wechsel reingladen werden, und andererseits, bei Übergabe einer Collection mit mehreren einträgen, für jeden Eintrag die Funktion <code class="inline">addListItem()</code> ausgeführt wird.</p>
<p>Als nächstes kommen wir zum Listen-Eintrag-View:</p>
<pre class="prettyprint">
<dfn>JavaScript</dfn>
<code class="block">
window.ListItemView = Backbone.View.extend({

	tagName : 'li',

	className : 'list_item',

	tmpl : _.template( $('#list-item-template').html() ),

	events : {
		'click .delete_item' : 'removeItem'
	},

	render : function ()
	{
		$(this.el).html( this.tmpl( this.model.toJSON() ));

		return this;
	},

	removeItem : function ()
	{
		this.model.destroy();
		$(this.el).fadeOut( function()
		{
			$(this).remove();
		});
	}

});
</code>
</pre>
<p>Hier wird das Element vom Standard (<code class="inline">div</code>) auf <code class="inline">li</code> gesetzt, die gewünschte <abbr title="Cascading Stylesheets">CSS</abbr>-Klasse gesetzt, das Template für den Eintrag angemeldet, ein Klick-Event mit der Funktion <code class="inline">removeItem()</code> verknüpft und anschließend die Funktionen <code class="inline">render()</code> und <code class="inline">removeItem()</code> definiert. Erstere fügt die Daten des Collection-Eintrags in das Template ein, letztere löscht den View und den dazugehörigen Collection-Eintrag.</p>
<p>Schlussendlich benötigen wir noch einen View für die Navigation:</p>
<pre class="prettyprint">
<dfn>JavaScript</dfn>
<code class="block">
window.NavigationView = Backbone.View.extend({

	tagName : 'li',

	tmpl : _.template( $('#nav-template').html() ),

	hash : function ()
	{
		return window.location.hash.replace('#/category/', '');
	},

	render : function ()
	{
		$('#nav').append($(this.el).html( this.tmpl( this.model.toJSON() ) ));

		return this;
	},

	setClass : function ()
	{
		var curHash = this.hash();

		this.el.className = ( curHash == $(this.el).find('a').text() ) ? 'current' : '';
	}

});
</code>
</pre>
<p>Neu und interessant ist hier die Funktion <code class="inline">setClass()</code>. Diese sorgt nach dem Rendern der Navigation, dass der aktuelle Reiter die Klasse "current" bekommt.</p>
<p>Um die Listen-App nun zum Laufen zu bringen, erstellen wir eine neue Instanz des Controllers:</p>
<pre class="prettyprint">
<dfn>JavaScript</dfn>
<code class="block">
var listApp = new ListController();
</code>
</pre>
<p>Der ganze Spaß wird in eine anonyme jQuery-Funktion geschrieben, damit die App gestartet wird, sobald das <abbr title="Document Object Model">DOM</abbr> geladen ist.</p>
<p>Das war es auch schon. Ich hoffe, meine Erklärungen sind einigermaßen nachvollziehbar. Falls nicht, nutzt auf jeden Fall die Kommentar-Funktion. Des weiteren würde ich mich natürlich über Anregungen und Verbesserungsvorschläge freuen, da ich ja doch ein Neuling in Sachen Backbone.js bin. Ansonsten noch der Hinweis, dass bei Gefallen natürlich gerne regen Gebrauch von den unten stehenden Social-Media-Buttons gemacht werden kann.</p>
<p>Vielen Dank!</p>
<hr /><p>Verwandte Beitr&auml;ge:<ul>
<li><a href='http://www.emanuel-kluge.de/html-css/ajax-wordpress-theme-backbone-js/' rel='bookmark' title='Studie &ldquo;Backboned&rdquo;: AJAX-powered WordPress-Theme mit Backbone.js'>Studie &ldquo;Backboned&rdquo;: AJAX-powered WordPress-Theme mit Backbone.js</a></li>
<li><a href='http://www.emanuel-kluge.de/tutorial/animierte-image-caption-mit-jquery-unter-wordpress/' rel='bookmark' title='Animierte Image-Caption mit jQuery unter WordPress'>Animierte Image-Caption mit jQuery unter WordPress</a></li>
<li><a href='http://www.emanuel-kluge.de/tutorial/social-icon-bar-mit-jquery/' rel='bookmark' title='&quot;Social Icon Bar&quot; mit jQuery'>&quot;Social Icon Bar&quot; mit jQuery</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.emanuel-kluge.de/tutorial/backbone-js-tutorial-die-merkliste/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Email Obfuscation: jQuery-PlugIn zur Verschleierung von Email-Adressen</title>
		<link>http://www.emanuel-kluge.de/jquery/email-obfuscation-jquery-plugin-zur-verschleierung-von-email-adressen/</link>
		<comments>http://www.emanuel-kluge.de/jquery/email-obfuscation-jquery-plugin-zur-verschleierung-von-email-adressen/#comments</comments>
		<pubDate>Sun, 27 Mar 2011 14:49:09 +0000</pubDate>
		<dc:creator>Emanuel</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Email]]></category>
		<category><![CDATA[PlugIn]]></category>

		<guid isPermaLink="false">http://www.emanuel-kluge.de/?p=1250</guid>
		<description><![CDATA[Anmerkung: Die Überschrift ist genau genommen etwas irreführend, da das PlugIn die Email-Adresse vielmehr entschleiert. Das aber nur am Rande erwähnt. Ein altes Problem, für welches es mittlerweile zugegebenermaßen schon viele Lösungen gibt, ist das Veröffentlichen von Email-Adressen auf Websites. Schreibt man die richtige Adresse in den Quelltext, macht man seinen Besuchern das Leben leichter. [...]]]></description>
			<content:encoded><![CDATA[<p><ins datetime="2011-03-27T18:23:33+00:00"><strong>Anmerkung:</strong> Die Überschrift ist genau genommen etwas irreführend, da das PlugIn die Email-Adresse vielmehr entschleiert. Das aber nur am Rande erwähnt.</ins></p>
<p>Ein altes Problem, für welches es mittlerweile zugegebenermaßen schon viele Lösungen gibt, ist das Veröffentlichen von Email-Adressen auf Websites. Schreibt man die richtige Adresse in den Quelltext, macht man seinen Besuchern das Leben leichter. Aber man arbeitet auch den Email-Spammern in die Hände, die das Netz nach Adressen durchforsten.</p>
<p>Verschleiert man seine Email-Adresse, indem man <abbr title="beispielsweise">bspw</abbr>. das @-Zeichen durch &quot;(at)&quot; ersetzt, hat man das Problem nicht. Nur müssen Besucher die Zeichen erst umständlich ersetzen, wenn sie eine Email an die Adresse schreiben wollen.</p>
<p>Meine Lösung des Problems ist eine Kombination aus Verschleierung der Adresse im Quelltext und ein Re-Build der Adresse per Javascript mithilfe eines jQuery-Plugins:</p>
<pre class="prettyprint"><dfn>Javascript</dfn><code class="block">
(function($){
     $.fn.obfuscateEmail = function(at, point, addClass)
    {
        /* Regular Expressions fuer @ und . definieren
	 * falls die Argumente gesetzt sind
	 **/

        var at = at &amp;&amp; new RegExp(at, 'g') || false,
            point = point &amp;&amp; new RegExp(point, 'g') || false;

	/* Plugin-Funktion ausfuehren, falls
	 * Regular Expressions fuer @ und . definiert
	 * sind.
	 * Ansonsten nur 'this' zurueck geben.
	 **/

        return at &amp;&amp; point &amp;&amp; this.each(
		function()
		{
			/* Wenn 'addClass' auf 'true' gesetzt ist,
			 * dem Element die Klasse 'js' anhaengen
			 **/

			this.className = this.className + ( addClass &amp;&amp; ' js' || '');

			/* Verschleierte Adresse anhand der Leer-
			 * zeichen in Array aufsplitten
			 **/

			var mailTo = this.innerHTML.split(' '),
			    i, mailToLen = mailTo.length,
			    address = [];

			/* Anhand der uebergebene @- und .-Werte
			 * jedes Element des mailTo-Arrays pruefen
			 * und ggf. Zeichen ersetzen.
			 * mailTo-Elemente in address-Array speichern.
			 **/

			for ( i=0; i&lt;mailToLen; i++ )
			{
				address.push( point.test(mailTo[i]) ?
				'.' :
				at.test(mailTo[i]) ?
				'@' :
				mailTo[i] );
			}

			/* Inhalt des Elements mit mailto-Link
			 * und der unverschleieerten Adresse aus
			 * dem address-Array befuellen
			 **/

			this.innerHTML = '&lt;a href="mailto:' + address.join('') + '"&gt;' + address.join('') + '&lt;/a&gt;';
		}
        ) || this;
    };
})(jQuery);
</code></pre>
<p>Angewendet wird das PlugIn folgendermaßen:</p>
<pre class="prettyprint"><dfn>Javascript</dfn><code class="block">
$(document).ready( function() {
	$('span.email').obfuscateEmail('(at)', '(punkt)', true);
});
</code></pre>
<p>Die ersten beiden Argumente der Funktion definieren, mit welchen Ausdrücken das @- und .-Zeichen der Email-Adressen verschleiert ist. Das dritte Argument ist ein Boolean-Wert und gibt an, ob den Adressen die Klasse 'js' angehängt werden soll, um sie unterschiedlich stylen zu können, je nachdem, ob der Besucher JavaScript aktiviert hat oder nicht. Das PlugIn arbeitet sich dann durch alle Adressen der Seite, hängt im Bedarfsfall die Klasse 'js' an und ersetzt die verschleierte Adresse durch die korrekte, inklusive mailto-Hyperlink zum einfachen Versenden im Email-Client bei Klicken der Adresse.</p>
<p>Die Adressen können folgendermaßen aussehen:</p>
<pre class="prettyprint"><dfn><abbr title="Hypertext Markup Language" lang="en">HTML</abbr></dfn><code class="block">
&lt;span class=&quot;email&quot;&gt;hansmustermann (at) domain (punkt) com&lt;/span&gt;
&lt;p class=&quot;email&quot;&gt;foo &lt;em&gt;(punkt)&lt;/em&gt; bar &lt;em&gt;(at)&lt;/em&gt; domain &lt;em&gt;(punkt)&lt;/em&gt; com&lt;/p&gt;
</code></pre>
<p>Wichtig bei den Adressen ist, dass die einzelnen Elemente durch ein Leerzeichen getrennt sind, sonst funktioniert es nicht. Wie man in der zweiten Zeile sieht, können die verschleierten Symbole beliebig in <abbr title="Hypertext Markup Language" lang="en">HTML</abbr> gefasst werden, um die Adresse für Besucher ohne JavaScript besser lesbar zu machen. Der Funktionalität des PlugIns tut dies kein Abbruch, solange die Leerzeichen vorhanden sind.</p>
<p>So einfach ist. Fragen, Anregungen, Verbesserungsvorschläge bitte in die Kommentare. Vielen Dank.</p>
<hr /><p>Verwandte Beitr&auml;ge:<ul>
<li><a href='http://www.emanuel-kluge.de/tutorial/hover-und-spotlight-effekt-in-bildergalerie-mit-jquery/' rel='bookmark' title='Hover- und Spotlight-Effekt in Bildergalerie mit jQuery'>Hover- und Spotlight-Effekt in Bildergalerie mit jQuery</a></li>
<li><a href='http://www.emanuel-kluge.de/tips-und-tricks/lightbox-in-aperture-bildergalerie-einbauen-mit-jquery/' rel='bookmark' title='Lightbox in Aperture-Bildergalerie einbauen mit jQuery'>Lightbox in Aperture-Bildergalerie einbauen mit jQuery</a></li>
<li><a href='http://www.emanuel-kluge.de/tutorial/social-icon-bar-mit-jquery/' rel='bookmark' title='&quot;Social Icon Bar&quot; mit jQuery'>&quot;Social Icon Bar&quot; mit jQuery</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.emanuel-kluge.de/jquery/email-obfuscation-jquery-plugin-zur-verschleierung-von-email-adressen/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>8Bit-Style-Navigation mit Fly-Out-Menus</title>
		<link>http://www.emanuel-kluge.de/tutorial/8bit-style-navigation-mit-fly-out-menus/</link>
		<comments>http://www.emanuel-kluge.de/tutorial/8bit-style-navigation-mit-fly-out-menus/#comments</comments>
		<pubDate>Thu, 15 Jul 2010 09:30:28 +0000</pubDate>
		<dc:creator>Emanuel</dc:creator>
				<category><![CDATA[HTML/CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[8Bit]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Data URI]]></category>
		<category><![CDATA[HTML]]></category>

		<guid isPermaLink="false">http://www.emanuel-kluge.de/?p=1154</guid>
		<description><![CDATA[Heute möchte ich kurz zeigen, wie man mit etwas HTML, CSS und ein paar kleinen GIF-Grafiken eine pixelige Seiten-Navigation im 8Bit-Stil baut. Außerdem benutzen wir etwas jQuery-Magic, um der Navigation noch Fly-Out-Menus zu spendieren. Demo &#124; Download Beginnen wir wie gewohnt mit dem HTML-Teil: HTML &#60;div id=&#34;nav&#34;&#62; &#60;ul&#62; &#60;li class=&#34;top&#34;&#62; &#60;a href=&#34;index.html&#34;&#62; &#60;strong&#62;Home&#60;/strong&#62; &#60;/a&#62; &#60;div [...]]]></description>
			<content:encoded><![CDATA[<p>Heute möchte ich kurz zeigen, wie man mit etwas <strong><abbr title="Hypertext Markup Language" lang="en">HTML</abbr></strong>, <strong><abbr title="Cascading Stylesheets" lang="en">CSS</abbr></strong> und ein paar kleinen <abbr title="Graphics Interchange Format" lang="en">GIF</abbr>-Grafiken eine pixelige Seiten-Navigation im 8Bit-Stil baut. Außerdem benutzen wir etwas <strong lang="en">jQuery</strong>-<span lang="en">Magic</span>, um der Navigation noch <span lang="en">Fly-Out-Menus</span> zu spendieren.</p>
<p><img src="http://www.emanuel-kluge.de/wp-content/uploads/2010/07/8bit-style-navigation-mit-fly-out-menus.gif" alt="8Bit-Style-Navigation mit Fly-Out-Menus" title="8Bit-Style-Navigation mit Fly-Out-Menus" width="480" height="120" class="aligncenter size-full wp-image-1155" /></p>
<div class="dedo"><a href="http://www.emanuel-kluge.de/demo/8bit-style-navigation-mit-fly-out-menus/" title="Demo &mdash; 8Bit-Style-Navigation mit Fly-Out-Menus" rel="nofollow">Demo</a> | <a href="http://www.emanuel-kluge.de/wp-content/uploads/2010/07/8bit-style-navigation-mit-fly-out-menus.zip" title="Download &mdash; 8Bit-Style-Navigation mit Fly-Out-Menus" lang="en">Download</a></div>
<p>Beginnen wir wie gewohnt mit dem <abbr title="Hypertext Markup Language" lang="en">HTML</abbr>-Teil:</p>
<pre>
<dfn><abbr title="Hypertext Markup Language" lang="en">HTML</abbr></dfn>
<code class="block">&lt;div id=&quot;nav&quot;&gt;
  &lt;ul&gt;
    &lt;li class=&quot;top&quot;&gt;
      &lt;a href=&quot;index.html&quot;&gt;
        &lt;strong&gt;Home&lt;/strong&gt;
      &lt;/a&gt;
      &lt;div class=&quot;sub&quot;&gt;
        &lt;div&gt;
          &lt;ul&gt;
            &lt;li&gt;
              &lt;a href=&quot;#&quot;&gt;Sub-Item 1&lt;/a&gt;
            &lt;/li&gt;
            &lt;li&gt;
              &lt;a href=&quot;#&quot;&gt;Sub-Item 2&lt;/a&gt;
            &lt;/li&gt;
            &lt;li&gt;
              &lt;a href=&quot;#&quot;&gt;Sub-Item 3&lt;/a&gt;
            &lt;/li&gt;
            &lt;li&gt;
              &lt;a href=&quot;#&quot;&gt;Sub-Item 4&lt;/a&gt;
            &lt;/li&gt;
            &lt;li&gt;
              &lt;a href=&quot;#&quot;&gt;Sub-Item 5&lt;/a&gt;
            &lt;/li&gt;
          &lt;/ul&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/li&gt;
    &lt;li class=&quot;top&quot;&gt;
      &lt;a href=&quot;#&quot;&gt;
        &lt;strong&gt;About&lt;/strong&gt;
      &lt;/a&gt;
      &lt;div class=&quot;sub&quot;&gt;
        &lt;div&gt;
          &lt;ul&gt;
            &lt;li&gt;
              &lt;a href=&quot;#&quot;&gt;One Sub-Item&lt;/a&gt;
            &lt;/li&gt;
            &lt;li&gt;
              &lt;a href=&quot;#&quot;&gt;Another Sub-Item&lt;/a&gt;
            &lt;/li&gt;
            &lt;li&gt;
              &lt;a href=&quot;#&quot;&gt;Still a Sub-Item&lt;/a&gt;
            &lt;/li&gt;
          &lt;/ul&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/li&gt;
    &lt;li&gt;
      &lt;a href=&quot;#&quot;&gt;
        &lt;strong&gt;Contact&lt;/strong&gt;
      &lt;/a&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;
</code>
</pre>
<p>Wie gewohnt eine ungeordnete Liste für die Haupt-Navigation und jeweils eine für die Sub-Navigationen. Um die charakteristischen Ecken hinzubekommen, müssen zwei Elemente ineinander verschachtelt und gegeneinander verschoben werden. Das macht den Quelltext <span lang="en">Tag</span>-intensiver. In meinen Augen jedoch noch in einem vertretbaren Rahmen und weit entfernt von klassischer "Diveritis".</p>
<p>Als nächstes kommen wir zum <abbr title="Cascading Stylesheets" lang="en">CSS</abbr>:</p>
<pre>
<dfn><abbr title="Cascading Stylesheets" lang="en">CSS</abbr></dfn>
<code class="block">@font-face {
  font-family: 'SilkscreenNormal';
  src: url('slkscr-webfont.eot');
  src: local('☺'), url('slkscr-webfont.woff') format('woff'), url('slkscr-webfont.ttf') format('truetype'), url('slkscr-webfont.svg#webfontUx1SMfhe') format('svg');
  font-weight: normal;
  font-style: normal;
}

ul {
  list-style: none;
}

body {
  background-color: #FFF;
  color: #333;
  font: normal 13px SilkscreenNormal, sans-serif;
}

#nav,
#nav > ul,
#nav > ul > li {
  float: left;
  display: inline;
}

#nav,
#nav > ul {
  width: auto;
  _width: 1%; /* IE6 Hack */
  height: 32px;
}

#nav {
  margin: 50px;
  position: relative;
  border-width: 2px 0;
  border-style: solid;
  border-color: #666;
}

#nav > ul {
  position: relative;
  left: -2px;
  margin-right: -4px;
  padding: 0 10px;
  border-width: 0 2px;
  border-style: solid;
  border-color: #666;
  background: url('data:image/gif;base64,R0lGODlhBAAEAIAAAP///73n/yH5BAAAAAAALAAAAAAEAAQAAAIGTACGqBkFADs=') 0 0 repeat;
  *background: url('img/tile1.gif') 0 0 repeat; /* IE6 and IE7 can't handle data uris */
}

#nav > ul > li {
  _width: 1%; /* IE6 Hack */
  margin: 3px 5px;
  position: relative;
}

#nav > ul > li > a {
  display: block;
  position: relative;
  width: auto;
  height: 22px;
  border-width: 2px 0;
  border-style: solid;
  border-color: #999;
  background-color: #FFF;
}

#nav > ul > li > a:link,
#nav > ul > li > a:visited {
  color: #999;
  text-decoration: none;
  background: url('data:image/gif;base64,R0lGODlhBAAEAIAAAP/////fvSH5BAAAAAAALAAAAAAEAAQAAAIGTACGqBkFADs=') 0 0 repeat;
  *background: url('img/tile2.gif') 0 0 repeat; /* IE6 and IE7 can't handle data uris */
}

#nav > ul > li > a:hover,
#nav > ul > li > a:focus,
#nav > ul > li > a:active {
  color: #666;
  background-image: url('data:image/gif;base64,R0lGODlhBAAEAIAAAP/////MmSH5BAAAAAAALAAAAAAEAAQAAAIGTACGqBkFADs=');
  *background-image: url('img/tile3.gif'); /* IE6 and IE7 can't handle data uris */
				}

#nav > ul > li > a strong {
  display: block;
  position: relative;
  width: auto;
  height: 22px;
  padding: 0 10px;
  line-height: 22px;
  left: -2px;
  margin-right: -4px;
  border-width: 0 2px;
  border-style: solid;
  border-color: #999;
}

#nav > ul > li.top > a > strong {
  padding-left: 21px;
  background: url('data:image/gif;base64,R0lGODlhBgAEAIABAJmZmf///yH5BAEAAAEALAAAAAAGAAQAAAIHhI8WocuwCgA7') 5px center no-repeat;
  *background: url('img/arrow.gif') 5px center no-repeat; /* IE6 and IE7 can't handle data uris */
}

#nav > ul > li > a:hover,
#nav > ul > li > a:hover strong,
#nav > ul > li > a:focus,
#nav > ul > li > a:focus strong {
  border-color: #666;
}

#nav > ul > li.top > a:hover strong,
#nav > ul > li.top > a:focus strong {
  background-image: url('data:image/gif;base64,R0lGODlhBgAEAIABAGZmZv///yH5BAEAAAEALAAAAAAGAAQAAAIHhI8WocuwCgA7');
  *background-image: url('img/arrow_hv.gif'); /* IE6 and IE7 can't handle data uris */
}

#nav > ul > li > a:active {
  top: 1px;
}

.sub {
  position: absolute;
  width: auto;
  top: 24px;
  left: 0;
  padding-top: 9px;
  display: none;
}

.sub div {
  position: relative;
  border-top: 2px solid #666;
  border-bottom: 2px solid #666;
}

.sub div ul {
  position: relative;
  left: -2px;
  margin-right: -4px;
  border-left: 2px solid #666;
  border-right: 2px solid #666;
  background: url('data:image/gif;base64,R0lGODlhBAAEAIAAAP///+7u7iH5BAAAAAAALAAAAAAEAAQAAAIGTACGqBkFADs=') 0 0 repeat;
  *background: url('img/tile4.gif') 0 0 repeat; /* IE6 and IE7 can't handle data uris */
}

.sub div ul li {
 border-top: 2px solid #666;
}

.sub div ul li:first-child {
  border-top: none;
}

.sub div ul li a {
  display: block;
  padding: 0 10px;
  line-height: 22px;
  font-size: 12px;
  white-space: nowrap;
}

.sub div ul li a:link,
.sub div ul li a:visited {
  color: #666;
}

.sub div ul li a:hover,´
.sub div ul li a:focus {
  background: url('data:image/gif;base64,R0lGODlhBAAEAIAAAP///93d3SH5BAAAAAAALAAAAAAEAAQAAAIGTACGqBkFADs=') 0 0 repeat;
  *background: url('img/tile5.gif') 0 0 repeat; /* IE6 and IE7 can't handle data uris */
}

.sub div ul li a:active {
  background: url('data:image/gif;base64,R0lGODlhBAAEAIAAAP///8zMzCH5BAAAAAAALAAAAAAEAAQAAAIGTACGqBkFADs=') 0 0 repeat;
  *background: url('img/tile6.gif') 0 0 repeat; /* IE6 and IE7 can't handle data uris */
}
</code>
</pre>
<p>Als erstes binde ich den Pixel-Font "<span lang="en">SilkScreen</span> von <a href="http://www.kottke.org/plus/type/silkscreen/index.html" title="Silkscreen is a small free font for your Web graphics" hreflang="en" lang="en">Jason Kottke</a> ein. Danach folgen die Angaben für die Navigation.</p>
<p>Interessant ist dabei, dass selbst das äußere Element <code class="inline">&lt;div id="nav"&gt;</code> die Angabe <code class="inline" lang="en">float: left</code> hat, damit es sich der Breite des Inhalts anpasst. Das kann zu <span lang="en">Layout</span>-Problemen führen, weshalb man im praktischen Einsatz darauf achten muss, das Element direkt unterhalb der Navigation mit einem <code class="inline" lang="en">clear: left</code> zu versehen.</p>
<p>Des weiteren kann man sehen, wie die charakteristischen Ecken zustande kommen: Das äußere Element hat jeweils unten und oben eine zwei-Pixel-starke <code class="inline" lang="en">border</code> und das innere jeweils links und rechts. Das innere Element wird dann per <code class="inline" lang="en">left: -2px</code> und <code class="inline" lang="en">margin-righ: -4px</code> um jeweils zwei Pixel nach links und rechts aus dem umgebenden Element hinaus gezogen. Schon ist der gewünschte Effekt da.</p>
<p>Ebenfalls erwähnenswert sind die Grafiken. Da diese nur 4x4 Pixel <abbr title="beziehungsweise">bzw.</abbr> 4x6 Pixel groß sind, lohnt es sich, sie in Form von Data <abbr title="Uniform Resource Identifier" lang="en">URI</abbr>s einzubinden und so unnötige <span lang="en"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Requests</span> zu sparen. Blöderweise können <abbr title="Internet Explorer" lang="en">IE</abbr>6 und <abbr title="Internet Explorer" lang="en">IE</abbr>7 damit nicht umgehen, weshalb die richtigen Grafiken ebenfalls eingebunden werden müssen. Diese werden dann mithilfe des <strong lang="en">Star-Hack</strong> den beiden <span lang="en">Browser</span>n zugewiesen.</p>
<p><a href="http://websemantics.co.uk/online_tools/image_to_data_uri_convertor/" title="Image To Data URI Convertor - webSemantics" hreflang="en">Bilder in  Data <abbr title="Uniform Resource Identifier" lang="en">URI</abbr>s umwandeln könnt ihr übrigens mit diesem <span lang="en">Online-Tool</span></a>.</p>
<p>Zum Schluss noch etwas <span lang="en">jQuery</span> um die <span lang="en">Fly-Out-Menu</span>-Funktionalität zu realisieren:</p>
<pre>
<dfn lang="en">JavaScript</dfn>
<code class="block">$(document).ready( function() {
  $(&#x27;#nav li.top&#x27;).hover( function() {
    $(this).find(&#x27;div&#x27;).stop(true, true).fadeIn(&#x27;slow&#x27;);
  }, function() {
    $(this).find(&#x27;div&#x27;).stop(true, true).fadeOut(&#x27;slow&#x27;);
  });
});
</code>
</pre>
<p>Ich denke, das ist die spartanischste Lösung und bedarf keiner weiteren Erläuterung.</p>
<p>Das war es auch schon. Die Navigation ist beliebig per <span lang="en">Copy&amp;Paste</span> erweiterbar, denkt nur daran, den <code class="inline" lang="en">li</code>-Elementen, die eine Sub-Navigation beinhalten, die Klasse <code class="inline" lang="en">top</code> zu verpassen, damit die <span lang="en">Fly-Out-Menu</span>-Funktionalität gewährleistet ist.</p>
<p>Ansonsten wünsche ich viel Spaß mit der Navigation. Bei Fragen bitte wie immer die Kommentar-Funktion nutzen. Und bei Gefallen fleißig via <span lang="en">Twitter</span> und <span lang="en">Facebook</span> verbreiten. Vielen Dank <img src='http://www.emanuel-kluge.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<hr /><p>Verwandte Beitr&auml;ge:<ul>
<li><a href='http://www.emanuel-kluge.de/tutorial/navigation-im-googlemail-style-mit-jquery/' rel='bookmark' title='Navigation im Googlemail-Style mit jQuery'>Navigation im Googlemail-Style mit jQuery</a></li>
<li><a href='http://www.emanuel-kluge.de/tutorial/hover-und-spotlight-effekt-in-bildergalerie-mit-jquery/' rel='bookmark' title='Hover- und Spotlight-Effekt in Bildergalerie mit jQuery'>Hover- und Spotlight-Effekt in Bildergalerie mit jQuery</a></li>
<li><a href='http://www.emanuel-kluge.de/tutorial/semi-transparente-navigation-in-wordpress-mit-css/' rel='bookmark' title='Semi-transparente Navigation in WordPress mit CSS'>Semi-transparente Navigation in WordPress mit CSS</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.emanuel-kluge.de/tutorial/8bit-style-navigation-mit-fly-out-menus/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8220;Rising Curtain&#8221;-Effekt bei Input-Feldern mit jQuery</title>
		<link>http://www.emanuel-kluge.de/tutorial/rising-curtain-effekt-bei-input-feldern-mit-jquery/</link>
		<comments>http://www.emanuel-kluge.de/tutorial/rising-curtain-effekt-bei-input-feldern-mit-jquery/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 16:30:12 +0000</pubDate>
		<dc:creator>Emanuel</dc:creator>
				<category><![CDATA[HTML/CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Input]]></category>

		<guid isPermaLink="false">http://www.emanuel-kluge.de/?p=1039</guid>
		<description><![CDATA[Demo &#124; Download Hinweis: Die CSS-Eigenschaft background-position-x bzw. background-position-y ist eine Erfindung von Microsoft und funktioniert leider nur im Internet Explorer und in Webkit-Browsern. Deshalb gibt es im jQuery-Skript eine Browser-Weiche. Im Firefox und im Opera verschwindet die Grafik einfach nur, der "Rising Curtain"-Effekt findet also nicht statt. Kommen wir aber zum eigentlichen Tutorial: Heute [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.emanuel-kluge.de/wp-content/uploads/2010/03/rising-curtain-effekt-bei-input-feldern-mit-jquery.jpg" alt="&quot;Rising Curtain&quot;-Effekt bei Input-Feldern mit jQuery" title="&quot;Rising Curtain&quot;-Effekt bei Input-Feldern mit jQuery" width="480" height="150" class="aligncenter size-full wp-image-1041" /></p>
<div class="dedo"><a href="http://www.emanuel-kluge.de/demo/rising-curtain-effekt-bei-input-feldern-mit-jquery/" title="Demo &mdash; &quot;Rising Curtain&quot;-Effekt bei Input-Feldern mit jQuery" rel="nofollow">Demo</a> | <a href="http://www.emanuel-kluge.de/wp-content/uploads/2010/03/rising-curtain-effekt-bei-input-feldern-mit-jquery.zip" title="Download &mdash; &quot;Rising Curtain&quot;-Effekt bei Input-Feldern mit jQuery">Download</a></div>
<p><strong>Hinweis:</strong></p>
<p>Die <abbr title="Cascading Stylesheet" lang="en">CSS</abbr>-Eigenschaft <code class="inline" lang="en">background-position-x</code> <abbr title="beziehungsweise">bzw.</abbr> <code class="inline" lang="en">background-position-y</code> ist eine Erfindung von <span lang="en">Microsoft</span> und funktioniert leider nur im <span lang="en">Internet Explorer</span> und in <span lang="en">Webkit-Browsern</span>. Deshalb gibt es im <span lang="en">jQuery</span>-Skript eine <span lang="en">Browser</span>-Weiche. Im <span lang="en">Firefox</span> und im <span lang="en">Opera</span> verschwindet die Grafik einfach nur, der <span lang="en">"Rising Curtain"</span>-Effekt findet also nicht statt.</ins></p>
<p>Kommen wir aber zum eigentlichen Tutorial:</p>
<p>Heute möchte ich zeigen, wie man <code class="inline" lang="en">input</code>-Felder in Formularen mithilfe des <span lang="en">"Rising Curtain"</span>-Effekts und <span lang="en">jQuery</span> interessanter gestalten kann, wenn der Fokus auf ihnen liegt. Alles was man dafür braucht, ist eine kleine Hintergrundgrafik mit einem Farbverlauf und ein paar Zeilen <span lang="en">jQuery</span>. Als erstes aber wenden wir uns dem <abbr title="Hypertext Markup Language" lang="en">HTML</abbr>-Teil zu:</p>
<pre>
<dfn><abbr title="Hypertext Markup Language" lang="en">HTML</abbr></dfn>
<code class="block">&lt;div&gt;
   &lt;span&gt;
      &lt;input type=&quot;text&quot; id=&quot;input1&quot; /&gt;
   &lt;/span&gt;
   &lt;label for=&quot;input1&quot;&gt;Input 1&lt;/label&gt;
&lt;/div&gt;
</code>
</pre>
<p>Dieser bedarf wohl keiner großen Erklärung. Es gibt ein <code class="inline" lang="en">input</code>-Feld plus dem dazugehörigen Label. Das <code class="inline" lang="en">input</code>-Feld ist in <code class="inline" lang="en">span</code>-<span lang="en">Tags</span> eingefasst, welche für den Rand sorgen.</p>
<p>Als nächstes der <abbr title="Cascading Stylesheet" lang="en">CSS</abbr>-Teil:</p>
<pre>
<dfn><abbr title="Cascading Stylesheet" lang="en">CSS</abbr></dfn>
<code class="block">div {
   height: 24px;
   margin-bottom: 10px;
   clear: left;
}

   span {
      height: 24px;
      float: left;
      display: inline;
      margin-right: 10px;
      border: 1px solid #999;
}

   span.active {
      border-color: #063050;
   }

      input {
         display: block;
         width: 200px;
         height: 18px;
         padding: 2px 4px;
         line-height: 18px;
         background: #FFF url('img/gradient.jpg') 0 0 repeat-x;
         border: 1px solid #FFF;
         color: #063050;
      }

   label {
      height: 24px;
      float: left;
      display: inline;
      line-height: 24px;
      cursor: pointer;
   }
</code>
</pre>
<p><code class="inline" lang="en">span</code> und <code class="inline" lang="en">label</code> werden mit <code class="inline" lang="en">float: left</code> nebeneinander angeordnet. Das <code class="inline" lang="en">input</code>-Feld bekommt einen weißen Rand, damit der dunkle Hintergrund nicht an den dunklen Rand des <code class="inline" lang="en">span</code>-Elements klatscht. Der Hintergrund wiederum stellt einen Farbverlauf von dunkelblau zu weiß dar, der mehr als doppelt so hoch wie das <code class="inline" lang="en">input</code>-Feld ist.</p>
<p>Kommen wir nun zum <span lang="en">jQuery</span>-Teil:</p>
<pre>
<dfn lang="en">JavaScript</dfn>
<code class="block">jQuery(document).ready(function($) {
   $(&#x27;input&#x27;).focus( function() {
      $(this).parent().addClass(&#x27;active&#x27;);
      if ( jQuery.browser.webkit || jQuery.browser.msie ) {
         $(this).animate({&#x27;background-position-y&#x27; : &#x27;-28px&#x27;}, 500, &#x27;linear&#x27;);
      } else {
         $(this).animate({&#x27;background-position&#x27; : &#x27;0 -28px&#x27;}, 0, &#x27;linear&#x27;);
      }
   });
   $(&#x27;input&#x27;).blur( function() {
      $(this).parent().removeClass(&#x27;active&#x27;);
      if ( jQuery.browser.webkit || jQuery.browser.msie ) {
         $(this).animate({&#x27;background-position-y&#x27; : &#x27;0&#x27;}, 500, &#x27;linear&#x27;);
      } else {
         $(this).animate({&#x27;background-position&#x27; : &#x27;0 0&#x27;}, 0, &#x27;linear&#x27;);
      }
   });
});
</code>
</pre>
<p>Liegt der Fokus auf einem <code class="inline" lang="en">input</code>-Feld, bekommt das umschließende <code class="inline" lang="en">span</code>-Element die Klasse &quot;<code class="inline" lang="en">active</code>&quot; zugewiesen und der Rand wird dunkelblau. Außerdem verschiebt sich der Hintergrund des <code class="inline" lang="en">input</code>-Feldes nach oben mithilfe der <code class="inline" lang="en">animate()</code>-Funktion von <span lang="en">jQuery</span>. Das ist der so genannte <span lang="en">"Rising Curtain"</span>-Effekt, durch den der Hintergrund des <code class="inline" lang="en">input</code>-Feldes heller wird. Gesteuert wird das ganze über die  <abbr title="Cascading Stylesheet" lang="en">CSS</abbr>-Eigenschaft <code class="inline" lang="en">background-position-y</code>.</p>
<p>So einfach ist das. Das ganze lässt sich natürlich auch bei einer <code class="inline" lang="en">textarea</code> anwenden. Denkt aber daran, dass die Hintergrund-Grafik entsprechend groß sein muss. Auch ist es denkbar, die Hintergrund-Grafik ganz aus dem sichtbaren Bereich fahren zu lassen, so dass das <code class="inline" lang="en">input</code>-Feld weiß wird. Der Kreativität sind kaum Grenzen gesetzt.</p>
<p>Das war es auch schon. <span lang="en">Bookmark</span> setzen oder dieses <span lang="en">Tutorial</span> via <span lang="en">twitter</span> durch den Äther jagen, wird wie immer gern gesehen. Bei Fragen und Anregungen steht die Kommentar-Funktion zur Verfügung. Nichts neues also.</p>
<hr /><p>Verwandte Beitr&auml;ge:<ul>
<li><a href='http://www.emanuel-kluge.de/tutorial/hover-und-spotlight-effekt-in-bildergalerie-mit-jquery/' rel='bookmark' title='Hover- und Spotlight-Effekt in Bildergalerie mit jQuery'>Hover- und Spotlight-Effekt in Bildergalerie mit jQuery</a></li>
<li><a href='http://www.emanuel-kluge.de/tutorial/social-icon-bar-mit-jquery/' rel='bookmark' title='&quot;Social Icon Bar&quot; mit jQuery'>&quot;Social Icon Bar&quot; mit jQuery</a></li>
<li><a href='http://www.emanuel-kluge.de/tutorial/animierte-image-caption-mit-jquery-unter-wordpress/' rel='bookmark' title='Animierte Image-Caption mit jQuery unter WordPress'>Animierte Image-Caption mit jQuery unter WordPress</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.emanuel-kluge.de/tutorial/rising-curtain-effekt-bei-input-feldern-mit-jquery/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Hover- und Spotlight-Effekt in Bildergalerie mit jQuery</title>
		<link>http://www.emanuel-kluge.de/tutorial/hover-und-spotlight-effekt-in-bildergalerie-mit-jquery/</link>
		<comments>http://www.emanuel-kluge.de/tutorial/hover-und-spotlight-effekt-in-bildergalerie-mit-jquery/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 18:11:37 +0000</pubDate>
		<dc:creator>Emanuel</dc:creator>
				<category><![CDATA[HTML/CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Fotos]]></category>
		<category><![CDATA[Galerie]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Spotlight-Effekt]]></category>

		<guid isPermaLink="false">http://www.emanuel-kluge.de/?p=897</guid>
		<description><![CDATA[Demo &#124; Download Jede Bildergalerie gewinnt, wenn das Thumbnail-Bild unter dem Cursor durch einen Hover-Effekt hervorgehoben wird und der Nutzer weiß, was gerade Sache ist. Wenn die umliegenden Thumbnails dann auch noch durch einen Spotlight-Effekt abgedunkelt werden, ist es noch leichter für den Nutzer, sich auf das aktuelle Bild zu konzentrieren. Wie man das mit [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.emanuel-kluge.de/wp-content/uploads/2010/01/hover-und-spotlight-effekt.jpg" alt="Hover-und-Spotlight-Effekt in Bildergalerie mit jQuery" title="Hover-und-Spotlight-Effekt in Bildergalerie mit jQuery" width="480" height="202" class="aligncenter size-full wp-image-898" /></p>
<div class="dedo"><a href="http://www.emanuel-kluge.de/demo/hover-und-spotlight-effekt-in-bildergalerie-mit-jquery/" title="Demo &mdash; &quot;Hover- und Spotlight-Effekt in Bildergalerie mit jQuery" rel="nofollow">Demo</a> | <a href="http://www.emanuel-kluge.de/wp-content/uploads/2010/01/hover-und-spotlight-effekt-in-bildergalerie-mit-jquery.zip" title="Download &mdash; &quot;Hover- und Spotlight-Effekt in Bildergalerie mit jQuery">Download</a></div>
<p>Jede <strong>Bildergalerie</strong> gewinnt, wenn das <span lang="en">Thumbnail</span>-Bild unter dem <span lang="en">Cursor</span> durch einen <strong><span lang="en">Hover</span>-Effekt</strong> hervorgehoben wird und der Nutzer weiß, was gerade Sache ist. Wenn die umliegenden <span lang="en">Thumbnails</span> dann auch noch durch einen <strong><span lang="en">Spotlight</span>-Effekt</strong> abgedunkelt werden, ist es noch leichter für den Nutzer, sich auf das aktuelle Bild zu konzentrieren. Wie man das mit <strong lang="en">jQuery</strong> realisiert, zeige ich jetzt.</p>
<p>Als erstes der <abbr title="Hypertext Markup Language" lang="en">HTML</abbr>-Teil:</p>
<pre>
<dfn><abbr title="Hypertext Markup Language" lang="en">HTML</abbr></dfn>
<code class="block">&lt;body class=&quot;js&quot;&gt;
	&lt;div class=&quot;wrap&quot;&gt;
		&lt;a href=&quot;path/to/image.html&quot; class=&quot;image&quot;&gt;
			&lt;img src=&quot;path/to/image.jpg&quot; alt=&quot;&quot; /&gt;
		&lt;/a&gt;
		&lt;a href=&quot;path/to/image.html&quot; class=&quot;image&quot;&gt;
			&lt;img src=&quot;path/to/image.jpg&quot; alt=&quot;&quot; /&gt;
		&lt;/a&gt;
		&lt;a href=&quot;path/to/image.html&quot; class=&quot;image&quot;&gt;
			&lt;img src=&quot;path/to/image.jpg&quot; alt=&quot;&quot; /&gt;
		&lt;/a&gt;
	&lt;/div&gt;
&lt;/body&gt;
</code>
</pre>
<p>Als nächstes der <abbr title="Cascading Stylesheet" lang="en">CSS</abbr>-Teil:</p>
<pre>
<dfn><abbr title="Cascading Stylesheet" lang="en">CSS</abbr></dfn>
<code class="block">.wrap {
	width: 321px;
	height: 321px;
	padding: 20px 0 0 20px;
	margin: 30px auto;
	clear: left;
}

	.image {
		width: 77px;
		height: 77px;
		padding: 5px;
		margin: 0 20px 20px 0;
		float: left;
		display: inline;
		position: relative;
		z-index: 10;
		background-color: #CCC;
	}

	.js .image:hover {
		background-color: #36F;
	}

		.image img {
			position: relative;
			z-index: 30;
			border-width: 1px;
			border-style: solid;
			border-color: #666 #999 #999 #666;
		}

		.layer1, .layer2 {
			display: block;
			position: absolute;
		}

		.layer1 {
			width: 87px;
			height: 87px;
			top: 0;
			left: 0;
			z-index: 20;
			background-color: #36F;
		}

		.layer2 {
			width: 77px;
			height: 77px;
			top: 5px;
			left: 5px;
			z-index: 40;
			background-color: #000;
		}
</code>
</pre>
<p>Kleine Anmerkung dazu: Wenn <span lang="en">JavaScript</span> im <span lang="en">Browser</span> aktiviert ist, wird die Klasse <abbr title="JavaScript" lang="en">js</abbr> vom <code class="inline" lang="en">body</code>-<span lang="en">Tag</span> entfernt. Geschieht dies nicht, bekommt das <code class="inline">a</code>-<span lang="en">Tag</span> um die <span lang="en">Thumbnails</span> einen <code class="inline" lang="en">:hover</code>-Effekt.</p>
<p>Schlussendlich der <span lang="en">jQuery</span>-Teil:</p>
<pre>
<dfn lang="en">JavaScript</dfn>
<code class="block">jQuery(document).ready(function($) {
	$(&#x27;body&#x27;).removeClass(&#x27;js&#x27;);
	var image = $(&#x27;a.image&#x27;);
	var html = &#x27;&lt;span class=\&quot;layer1\&quot;&gt;&lt;/span&gt;&lt;span class=\&quot;layer2\&quot;&gt;&lt;/span&gt;&#x27;;
	image.append(html).find(&#x27;span&#x27;).css(&#x27;opacity&#x27;, &#x27;0&#x27;);
	image.each( function() {
		$(this).hover( function() {
			$(&#x27;span.layer1&#x27;, this).stop().fadeTo(800, 1);
			$(this).siblings().find(&#x27;span.layer2&#x27;).stop().fadeTo(800, 0.5);
		}, function() {
			$(&#x27;span.layer1&#x27;, this).stop().fadeTo(800, 0);
			$(this).siblings().find(&#x27;span.layer2&#x27;).stop().fadeTo(800, 0);
		});
	});
});
</code>
</pre>
<p>Als erstes wird die Klasse <abbr title="JavaScript" lang="en">js</abbr> vom <code class="inline" lang="en">body</code>-<span lang="en">Tag</span> entfernt. Danach werden die beiden <code class="inline">span</code>-<span lang="en">Tags</span> eingefügt, die für den <span lang="en">Hover</span>- und den <span lang="en">Spotlight</span>-Effekt zuständig sind. Danach wird in einer <code class="inline" lang="en">each()</code>-Schleife festgelegt, dass bei einem <span lang="en">Hover</span> die <code class="inline">span</code>-<span lang="en">Tags</span> erscheinen und entsprechend wieder verschwinden.</p>
<p>Das war es auch schon. Falls es Fragen oder Probleme gibt, möchte ich euch wie immer die Kommentar-Funktion nahe legen. Ansonsten freue ich mich natürlich, wenn ihr den Artikel <span lang="en">bookmark</span>'t oder auf <span lang="en">twitter</span> verbreitet.</p>
<hr /><p>Verwandte Beitr&auml;ge:<ul>
<li><a href='http://www.emanuel-kluge.de/tutorial/rising-curtain-effekt-bei-input-feldern-mit-jquery/' rel='bookmark' title='&#8220;Rising Curtain&#8221;-Effekt bei Input-Feldern mit jQuery'>&#8220;Rising Curtain&#8221;-Effekt bei Input-Feldern mit jQuery</a></li>
<li><a href='http://www.emanuel-kluge.de/tutorial/animierte-image-caption-mit-jquery-unter-wordpress/' rel='bookmark' title='Animierte Image-Caption mit jQuery unter WordPress'>Animierte Image-Caption mit jQuery unter WordPress</a></li>
<li><a href='http://www.emanuel-kluge.de/tutorial/social-icon-bar-mit-jquery/' rel='bookmark' title='&quot;Social Icon Bar&quot; mit jQuery'>&quot;Social Icon Bar&quot; mit jQuery</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.emanuel-kluge.de/tutorial/hover-und-spotlight-effekt-in-bildergalerie-mit-jquery/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Lightbox in Aperture-Bildergalerie einbauen mit jQuery</title>
		<link>http://www.emanuel-kluge.de/tips-und-tricks/lightbox-in-aperture-bildergalerie-einbauen-mit-jquery/</link>
		<comments>http://www.emanuel-kluge.de/tips-und-tricks/lightbox-in-aperture-bildergalerie-einbauen-mit-jquery/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 15:46:10 +0000</pubDate>
		<dc:creator>Emanuel</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Fotografie]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Tips und Tricks]]></category>
		<category><![CDATA[Aperture]]></category>
		<category><![CDATA[Lightbox]]></category>

		<guid isPermaLink="false">http://www.emanuel-kluge.de/?p=879</guid>
		<description><![CDATA[Aperture ist eine Photo-Editing-Software von Apple&#8482;, welche die Möglichkeit bietet, Galerien zu erstellen und im HTML-Format zu exportieren. Diese Funktion kann ich aufgrund des generierten Quelltextes nicht empfehlen, nichtsdestominder ist sie sehr praktisch für Leute, die schnell eine Galerie veröffentlichen wollen, jedoch kein HTML können. Ein weiteres Manko ist der Umstand, dass jedes Foto eine [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.emanuel-kluge.de/wp-content/uploads/2010/01/aperture-screenshot.jpg" alt="Aperture - Screenshot" title="Aperture - Screenshot" width="480" height="264" class="aligncenter size-full wp-image-881" /></p>
<p><a href="http://www.apple.com/aperture/" title="Apple Aperture" lang="en" hreflang="en"> Aperture</a> ist eine <span lang="en">Photo-Editing-Software</span> von <span lang="en">Apple</span>&trade;, welche die Möglichkeit bietet, Galerien zu erstellen und im <abbr title="Hypertext Markup Language" lang="en">HTML</abbr>-Format zu exportieren. Diese Funktion kann ich aufgrund des generierten Quelltextes nicht empfehlen, nichtsdestominder ist sie sehr praktisch für Leute, die schnell eine Galerie veröffentlichen wollen, jedoch kein <abbr title="Hypertext Markup Language" lang="en">HTML</abbr> können.</p>
<p>Ein weiteres Manko ist der Umstand, dass jedes Foto eine eigene Unterseite bekommt und man sich an diesen entlang hangelt. Heutzutage allerdings - möchte ich behaupten - ist eine <strong lang="en">Lightbox</strong> Standard, wenn es um das Betrachten von Fotos im <span lang="en">Browser</span> geht. Deshalb möchte ich zeigen, wie man mithilfe von <strong lang="en">jQuery</strong> und einem <strong lang="en">PlugIn</strong> diese Funktionalität relativ schnell nachrüsten kann.</p>
<p>Als erstes benötigen wir das <span lang="en">PlugIn</span> <a href="http://leandrovieira.com/projects/jquery/lightbox/" title="jQuery lightBox plugIn" lang="en" hreflang="en">jQuery lightBox</a>. Wir entpacken das <span lang="en">Zip-File</span> und legen den <abbr title="Javascript" lang="en">js</abbr>-Ordner, den <abbr title="Cascading Stylesheet" lang="en">css</abbr>-Ordner und den <span lang="en">images</span>-Ordner aus dem <span lang="en">jquery-lightbox-0.5</span>-Ordner in dem aus <span lang="en">Aperture</span> exportierten Galerie-Ordner ab.</p>
<p>Nun muss das <span lang="en">PlugIn</span> eingebunden werden und zwar innerhalb der <code class="inline" lang="en">&lt;head&gt;</code>-<span lang="en">Tags</span> der index.html der Galerie. Als erstes die beiden <span lang="en">JavaScript</span>-Dateien und das <span lang="en">Stylesheet</span>:</p>
<pre>
<dfn><abbr title="Hypertext Markup Language" lang="en">HTML</abbr></dfn>
<code class="block">&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/jquery.lightbox-0.5.css&quot; media=&quot;screen&quot; /&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;js/jquery.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;js/jquery.lightbox-0.5.pack.js&quot;&gt;&lt;/script&gt;
</code>
</pre>
<p>Mit folgendem <span lang="en"> JavaScript-Code</span> aktivieren wir die <span lang="en">Lightbox</span>:</p>
<pre>
<dfn lang="en">JavaScript</dfn>
<code class="block">$(document).ready( function() {
	$(&#x27;dd.imagecell a&#x27;).lightBox();
});
</code>
</pre>
<p>Nun ergibt sich allerdings das Problem, dass das <span lang="en">Lightbox-PlugIn</span> darauf angewiesen ist, dass die <span lang="en">Links</span> um die <span lang="en">Thumbnails</span> der Fotos auf die große Version der selben verweisen. Dies tun sie in der <span lang="en">Aperture</span>-Galerie allerdings nicht. Vielmehr verweist der <span lang="en">Link</span> auf die Unterseite, auf der die große Version des Fotos eingebunden ist. Die <span lang="en">Links</span> müssen also erst noch manipuliert werden, bevor die <span lang="en">Lightbox funktioniert</span>:</p>
<pre>
<dfn lang="en">JavaScript</dfn>
<code class="block">$(document).ready( function() {
   var link = $(&#x27;dd.imagecell a&#x27;);
   link.each( function(i) {
      i += 1;
      $(this).attr(&#x27;href&#x27;, &#x27;pictures/picture-&#x27; + i + &#x27;.jpg&#x27;);
   });
});
</code>
</pre>
<p>Mit diesem <span lang="en"> JavaScript-Code</span> werden die Verweise auf den <span lang="en">Thumbnails</span> auf die großen Versionen der jeweiligen Fotos umgelenkt. Alles in allem muss man also folgendes in den <code class="inline" lang="en">&lt;head&gt;</code>-Bereich der index.html schreiben:</p>
<pre>
<dfn><abbr title="Hypertext Markup Language" lang="en">HTML</abbr>/<span lang="en">JavaScript</span></dfn>
<code class="block">&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/jquery.lightbox-0.5.css&quot; media=&quot;screen&quot; /&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;js/jquery.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;js/jquery.lightbox-0.5.pack.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
   $(document).ready( function() {
      var link = $(&#x27;dd.imagecell a&#x27;);
      link.each( function(i) {
         i += 1;
         $(this).attr(&#x27;href&#x27;, &#x27;pictures/picture-&#x27; + i + &#x27;.jpg&#x27;);
      });
      link.lightBox();
   });
&lt;/script&gt;
</code>
</pre>
<p>Schon habt ihr mit etwas <span lang="en">jQuery</span> eine moderne <span lang="en">Lightbox</span> in eure <span lang="en">Aperture</span>-Galerie eingebaut.</p>
<p>Noch ein Hinweis am Rande: Die Pfade zum Warte-Bild, den Pfeilen und dem <span lang="en">Close-Button</span> sind in der <span lang="en">lightbox.js</span> festgelegt. Wenn ihr den <span lang="en">images</span>-Ordner also nicht im Galerie-Ordner ablegt, sondern <abbr title="beispielsweise">bspw.</abbr> darunter, müsst ihr diese Pfad-Angaben ändern, sonst wird die <span lang="en">Lightbox</span> nicht richtig angezeigt.</p>
<p>Ansonsten gilt wie immer: Wenn es Fragen gibt, nutzt die Kommentar-Funktion!</p>
<p>Weiterführende Links:</p>
<ul>
<li><a <a href="http://leandrovieira.com/projects/jquery/lightbox/" title="jQuery lightBox plugIn" lang="en" hreflang="en">jQuery lightBox</a></li>
<li><a href="http://jquery.com/" title="jQuery: The Write Less, Do More, JavaScript Library" hreflang="en">Offizielle <span lang="en">jQuery</span>-Seite</a></li>
</ul>
<hr /><p>Verwandte Beitr&auml;ge:<ul>
<li><a href='http://www.emanuel-kluge.de/tutorial/hover-und-spotlight-effekt-in-bildergalerie-mit-jquery/' rel='bookmark' title='Hover- und Spotlight-Effekt in Bildergalerie mit jQuery'>Hover- und Spotlight-Effekt in Bildergalerie mit jQuery</a></li>
<li><a href='http://www.emanuel-kluge.de/tutorial/animierte-image-caption-mit-jquery-unter-wordpress/' rel='bookmark' title='Animierte Image-Caption mit jQuery unter WordPress'>Animierte Image-Caption mit jQuery unter WordPress</a></li>
<li><a href='http://www.emanuel-kluge.de/tutorial/animierte-navigation-mit-jquery/' rel='bookmark' title='Animierte Navigation mit jQuery'>Animierte Navigation mit jQuery</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.emanuel-kluge.de/tips-und-tricks/lightbox-in-aperture-bildergalerie-einbauen-mit-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&quot;Social Icon Bar&quot; mit jQuery</title>
		<link>http://www.emanuel-kluge.de/tutorial/social-icon-bar-mit-jquery/</link>
		<comments>http://www.emanuel-kluge.de/tutorial/social-icon-bar-mit-jquery/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 13:13:12 +0000</pubDate>
		<dc:creator>Emanuel</dc:creator>
				<category><![CDATA[HTML/CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Button]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Social Media]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.emanuel-kluge.de/?p=719</guid>
		<description><![CDATA[Demo &#124; Download Um meine Besucher auf meine diversen Profile in Social Communities aufmerksam zu machen, habe ich rechts in der Sidebar eine Social Icon Bar installiert, deren Icons bspw. auf Flickr und Xing verweisen. Und damit das nicht so langweilig ist, habe ich den Spaß noch ein wenig mit jQuery befeuert. Jetzt möchte ich [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.emanuel-kluge.de/wp-content/uploads/2009/10/social-icon-bar-mit-jquery.jpg" alt="Social Icon-Bar mit jQuery" title="Social Icon-Bar mit jQuery" width="480" height="192" class="aligncenter size-full wp-image-751" /></p>
<div class="dedo"><a href="http://www.emanuel-kluge.de/demo/social-icon-bar-mit-jquery/" title="Demo &mdash; &quot;Social Icon Bar&quot; mit jQuery" rel="nofollow">Demo</a> | <a href="http://www.emanuel-kluge.de/wp-content/uploads/2009/09/social-icon-bar-mit-jquery.zip" title="Download &mdash; &quot;Social Icon Bar&quot; mit jQuery">Download</a></div>
<p>Um meine Besucher auf meine diversen Profile in <span lang="en">Social Communities</span> aufmerksam zu machen, habe ich rechts in der <span lang="en">Sidebar</span> eine <span lang="en">Social Icon Bar</span> installiert, deren <span lang="en">Icons</span> <abbr title="beispielsweise">bspw.</abbr> auf <span lang="en">Flickr</span> und Xing verweisen. Und damit das nicht so langweilig ist, habe ich den Spaß noch ein wenig mit <a href="http://jquery.com/" title="jQuery: The Write Less, Do More, JavaScript Library" lang="en" hreflang="en">jQuery</a> befeuert.</p>
<p>Jetzt möchte ich kurz erläutern, wie das geht. Als erstes brauchen wir ein passendes <span lang="en">Icon-Set</span>. Ich habe für dieses <span lang="en">Tutorial</span> auf die <a href="http://webtreats.mysitemyway.com/154-matte-black-social-media-icons/" title="154 Matte Black Social Media Icons" lang="en" hreflang="en">Matte Black Social Media Icons</a> zurückgegriffen, da diese Sammlung <abbr title="unter anderem">u.a.</abbr> auch ein Xing-<span lang="en">Icon</span> beinhaltet. Die <span lang="en">Icons</span> bringen wir nun in einem Grafik-Programm mithilfe des <span lang="en">Crop-Tools</span> auf die gewünschte Größe, in meinem Fall 40x40 Pixel.</p>
<p><img src="http://www.emanuel-kluge.de/wp-content/uploads/2009/10/icon-crop-tool.jpg" alt="Icon mit dem Crop-Tool auf die richtige Groesse bringen" title="Icon mit dem Crop-Tool auf die richtige Groesse bringen" width="480" height="431" class="aligncenter size-full wp-image-754" /></p>
<p>Das machen wir mit allen <span lang="en">Icons</span>, die wir benötigen. Danach widmen wir uns dem <abbr title="Hypertext Markup Language" lang="en">HTML</abbr>-Teil:</p>
<pre>
<dfn><abbr title="Hypertext Markup Language" lang="en">HTML</abbr></dfn>
<code class="block">&lt;ul id=&quot;iconbar&quot;&gt;
	&lt;li&gt;
		&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;
		&lt;span class=&quot;s2&quot;&gt;&lt;/span&gt;
		&lt;span class=&quot;s3&quot;&gt;&lt;/span&gt;
		&lt;span class=&quot;s4&quot;&gt;&lt;/span&gt;
		&lt;a href=&quot;http://name.tld/feed/&quot; title=&quot;Den RSS-Feed abonnieren&quot;&gt;
			&lt;img src=&quot;images/rss.png&quot; alt=&quot;Den RSS-Feed abonnieren&quot; width=&quot;40&quot; height=&quot;40&quot; title=&quot;Den RSS-Feed abonnieren&quot; /&gt;
		&lt;/a&gt;
	&lt;/li&gt;
&lt;/ul&gt;
</code>
</pre>
<p>Basis ist eine ungeordnete Liste. Der Übersichtlichkeit halber habe ich nur einen Listenpunkt angegeben. Die Liste kann natürlich beliebig erweitert werden. Innerhalb der Listenelemente sind vier <code class="inline">span</code>-Elemente. Diese bilden die Abdeckungen des jweiligen <span lang="en">Icons</span>, welche ähnlich einer Blende zu allen Seiten wegfahren, wenn man mit dem <span lang="en">Cursor</span> drüber geht.</p>
<p>Als nächstes kommt der <span lang="en">jQuery</span>-Teil:</p>
<pre>
<dfn lang="en">JavaScript</dfn>
<code class="block">jQuery(document).ready(function($) {
	$(&#x27;body&#x27;).addClass(&#x27;js_active&#x27;);
	$(&#x27;#iconbar li&#x27;).each(function(i) {
		$(this).hover(function() {
			$(&#x27;span.s1&#x27;, this).stop().animate({&#x27;left&#x27; : &#x27;-20px&#x27;}, {queue:false,duration:500});
			$(&#x27;span.s2&#x27;, this).stop().animate({&#x27;top&#x27; : &#x27;-20px&#x27;}, {queue:false,duration:500});
			$(&#x27;span.s3&#x27;, this).stop().animate({&#x27;right&#x27; : &#x27;-20px&#x27;}, {queue:false,duration:500});
			$(&#x27;span.s4&#x27;, this).stop().animate({&#x27;bottom&#x27; : &#x27;-20px&#x27;}, {queue:false,duration:500});
		}, function() {
			$(&#x27;span.s1&#x27;, this).animate({&#x27;left&#x27; : &#x27;0&#x27;}, {queue:false,duration:500});
			$(&#x27;span.s2&#x27;, this).animate({&#x27;top&#x27; : &#x27;0&#x27;}, {queue:false,duration:500});
			$(&#x27;span.s3&#x27;, this).animate({&#x27;right&#x27; : &#x27;0&#x27;}, {queue:false,duration:500});
			$(&#x27;span.s4&#x27;, this).animate({&#x27;bottom&#x27; : &#x27;0&#x27;}, {queue:false,duration:500});
		});
	});
});
</code>
</pre>
<p>Als erstes fügen wir dem <code class="inline">body</code>-Element die Klasse &quot;<code class="inline" lang="en">js_active</code>&quot; hinzu. Dadurch werden die <code class="inline">span</code>-Elemente sichtbar. So ist dafür gesorgt, dass die <span lang="en">Social Icon Bar</span> auch ohne Effekt funktioniert, wenn der Besucher <span lang="en">JavaScript</span> deaktiviert hat. Als nächtes wird mit der <code class="inline">each()</code>-Funktion auf die einzelnen Elemente der ungeordneten Liste zugegriffen. Fährt der Besucher mit dem <span lang="en">Cursor</span> über eines der Listen-Elemente, fahren die <code class="inline">span</code>-Elemente ausgelöst durch die <code class="inline">animate()</code>-Funktion von <span lang="en">jQuery</span> in die jeweils vorgegebene Richtung. Der Wert <code class="inline">500</code> gibt an, dass dieser Vorgang eine halbe Sekunde dauern soll. Bewegt man den <span lang="en">Cursor</span> vom Listen-Element weg, gehen die <code class="inline">span</code>-Elemente wieder in ihre Ausgangsposition.</p>
<p>Zum Schluss muss das ganze natürlich noch ansprechend mithilfe von <abbr title="Cascading Stylesheet" lang="en">CSS</abbr> ausgerichtet werden:</p>
<pre>
<dfn><abbr title="Cascading Stylesheet" lang="en">CSS</abbr></dfn>
<code class="block">#iconbar {
	clear: left;
	overflow: hidden;
	list-style: none;
}

#iconbar li {
	width: 40px;
	height: 40px;
	margin-right: 10px;
	float: left;
	position: relative;
	overflow: hidden;
	border: 1px solid #999;
	-moz-border-radius: 2px;
	-khtml-border-radius: 2px;
	-webkit-border-radius: 2px;
	border-radius: 2px;
}

#iconbar li span {
	display: none;
}

body.js_active #iconbar li span {
	display: block;
	width: 20px;
	height: 20px;
	position: absolute;
	background-color: #FFF;
	opacity: 0.7;
	cursor: pointer;
}

.s1 {
	left: 0;
	top: 0;
}

.s2 {
	top: 0;
	right: 0;
}

.s3 {
	right: 0;
	bottom: 0;
}

.s4 {
	bottom: 0;
	left: 0;
}
</code>
</pre>
<p>Die Listen-Elemente sind 40 Pixel breit und hoch, und werden nach links ge<span lang="en">floated</span>. Wichtig beim Listen-Element sind die Angaben <code class="inline" lang="en">position: relative;</code>, damit die darin liegenden <code class="inline">span</code>-Elemente absolut positioniert werden können, und <code class="inline" lang="en">overflow: hidden;</code>, damit die <code class="inline">span</code>-Elemente beim <span lang="en">Mouseover</span> auch wirklich verschwinden. Zusätzlich geben wir den Listen-Elementen noch eine leichte Eckenrundung mit.</p>
<p>Die <code class="inline">span</code>-Elemente sind durch die <abbr title="Cascading Stylesheet" lang="en">CSS</abbr>-Angabe <code class="inline" lang="en">display: none;</code> eigentlich unsichtbar. Ist <span lang="en">JavaScript</span> allerdings im <span lang="en">Browser</span> des Besuchers aktiviert, bekommt das <code class="inline" lang="en">body</code>-Element die Klasse &quot;<code class="inline" lang="en">js_active</code>&quot; hinzugefügt und es greift die darunter liegende <span lang="en">Stylesheet</span>-Angabe. Die <code class="inline">span</code>-Elemente sind nun 20x20 Pixel groß und absolut positioniert. Durch die Angabe <code class="inline" lang="en">opacity: 0.7;</code> werden sie außerdem leicht durchsichtig und geben einen Blick auf das dahinter liegende <span lang="en">Icon</span> frei. Durch die Angabe <code class="inline" lang="en">cursor: pointer;</code> wird der <span lang="en">Cursor</span> schon beim Überfahren der <code class="inline">span</code>-Elemente zur - für <span lang="en">Links</span> charakteristischen - Hand. Das erhöht die <span lang="en">User Experience</span>.</p>
<p>Zum Schluss werden die einzelnen <code class="inline">span</code>-Elemente noch positioniert und schon ist die <span lang="en">Social Icon Bar</span> fertig. Ihr könnt sie wie ich in die <span lang="en">Sidebar</span> integrieren oder unter jeden <span lang="en">Blog</span>-Eintrag für die <span lang="en">Bookmark-Links</span>. Möglichkeiten gibt es wie immer viele.</p>
<p>Solltet ihr noch Fragen haben oder Probleme auftreten, nutzt die Kommentar-Funktion und scheut euch nicht, mir Fragen zu stellen. Ansonsten danke ich für eure Aufmerksamkeit und - falls euch der Artikel gefallen hat - würde mich freuen, wenn ihr ihn einschlägigen <span lang="en">Bookmark</span>-Diensten zuführt.</p>
<hr /><p>Verwandte Beitr&auml;ge:<ul>
<li><a href='http://www.emanuel-kluge.de/tutorial/hover-und-spotlight-effekt-in-bildergalerie-mit-jquery/' rel='bookmark' title='Hover- und Spotlight-Effekt in Bildergalerie mit jQuery'>Hover- und Spotlight-Effekt in Bildergalerie mit jQuery</a></li>
<li><a href='http://www.emanuel-kluge.de/tutorial/animierte-image-caption-mit-jquery-unter-wordpress/' rel='bookmark' title='Animierte Image-Caption mit jQuery unter WordPress'>Animierte Image-Caption mit jQuery unter WordPress</a></li>
<li><a href='http://www.emanuel-kluge.de/tutorial/rising-curtain-effekt-bei-input-feldern-mit-jquery/' rel='bookmark' title='&#8220;Rising Curtain&#8221;-Effekt bei Input-Feldern mit jQuery'>&#8220;Rising Curtain&#8221;-Effekt bei Input-Feldern mit jQuery</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.emanuel-kluge.de/tutorial/social-icon-bar-mit-jquery/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Animierte Image-Caption mit jQuery unter WordPress</title>
		<link>http://www.emanuel-kluge.de/tutorial/animierte-image-caption-mit-jquery-unter-wordpress/</link>
		<comments>http://www.emanuel-kluge.de/tutorial/animierte-image-caption-mit-jquery-unter-wordpress/#comments</comments>
		<pubDate>Tue, 22 Sep 2009 14:18:02 +0000</pubDate>
		<dc:creator>Emanuel</dc:creator>
				<category><![CDATA[HTML/CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Image-Caption]]></category>

		<guid isPermaLink="false">http://www.emanuel-kluge.de/?p=658</guid>
		<description><![CDATA[Demo &#124; Download Google liebt es ja, wenn unter oder neben Bildern noch ein beschreibender Text steht. Deswegen hat WordPress vor einiger Zeit die Image-Caption eingeführt. Diese kann man - wenn man kein Freund von Bildunterschriften ist - mit jQuery jedoch so manipulieren, dass sie nur bei einem MouseOver erscheint. Wie das geht, erkläre ich [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.emanuel-kluge.de/wp-content/uploads/2009/09/animierte-image-caption-mit-jquery-unter-wordpress.jpg" alt="Animierte Image-Caption mit jQuery unter WordPress" title="Animierte Image-Caption mit jQuery unter WordPress" width="480" height="293" class="aligncenter size-full wp-image-661" /></p>
<div class="dedo"><a href="http://www.emanuel-kluge.de/demo/animierte-image-caption-mit-jquery-unter-wordpress/" title="Demo &mdash; Animierte Image-Caption mit jQuery unter WordPress" rel="nofollow">Demo</a> | <a href="http://www.emanuel-kluge.de/wp-content/uploads/2009/09/animierte-image-caption-mit-jquery-unter-wordpress.zip" title="Download &mdash; Animierte Image-Caption mit jQuery unter WordPress">Download</a></div>
<p><span lang="en">Google</span> liebt es ja, wenn unter oder neben Bildern noch ein beschreibender Text steht. Deswegen hat <strong lang="en">WordPress</strong> vor einiger Zeit die <strong lang="en">Image-Caption</strong> eingeführt. Diese kann man - wenn man kein Freund von Bildunterschriften ist - mit <strong lang="en">jQuery</strong> jedoch so manipulieren, dass sie nur bei einem <strong lang="en">MouseOver</strong> erscheint. Wie das geht, erkläre ich in diesem Tutorial.</p>
<p>Wie gehabt als erstes der <abbr title="Hypertext Markup Language" lang="en">HTML</abbr>-Teil:</p>
<pre>
<dfn><abbr title="Hypertext Markup Language" lang="en">HTML</abbr></dfn>
<code class="block">&lt;div class=&quot;wp-caption&quot; style=&quot;width: ???px&quot;&gt;
	&lt;img src=&quot;/path/to/img.jpg&quot; alt=&quot;Dies ist eine Beschreibung&quot; title=&quot;Dies ist eine Beschreibung&quot; width=&quot;???&quot; height=&quot;???&quot; class=&quot;size-full wp-image-3402&quot; /&gt;
	&lt;p class=&quot;wp-caption-text&quot;&gt;Dies ist eine Beschreibung&lt;/p&gt;
&lt;/div&gt;
</code>
</pre>
<p>Dies ist der <span lang="en">Caption</span>-Quelltext, der von <span lang="en">WordPress</span> ausgegeben wird. Anstatt der Fragezeichen kommen natürlich die richtigen Höhen- und Breitenangaben, ebenso wie der richtige Pfad zum Bild.</p>
<p>Als nächstes ein bißchen <abbr title="Cascading Stylesheet" lang="en">CSS</abbr> für das entsprechende Aussehen:</p>
<pre>
<dfn><abbr title="Cascading Stylesheet" lang="en">CSS</abbr></dfn>
<code class="block">.wp-caption {
	position: relative;
	margin-bottom: 20px;
	border: 3px solid #999;
	overflow: hidden;
	-moz-border-radius: 2px;
	-khtml-border-radius: 2px;
	-webkit-border-radius: 2px;
	border-radius: 2px;
}

.wp-caption-text {
	padding: 5px 10px;
	background-color: #333;
	color: #EEE;
	border-top: 1px solid #666;
}
</code>
</pre>
<p>Wichtig hierbei ist die Angabe &quot;<code class="inline">position: relative</code>&quot;, da wir beim Verschieben des Bildes mit einem negativen <code class="inline">margin</code> arbeiten und der <abbr title="Internet Explorer" lang="en">IE</abbr>6 ohne diesen Zusatz rumzickt. Des weiteren ist die Angabe &quot;<code class="inline" lang="en">overflow: hidden</code>&quot; wichtig, da der <span lang="en">Caption-Text</span> sonst nicht verschwinden würde.</p>
<p>Alle anderen Angaben zu Farben, Innen- und Außenabständen können ohne weiteres angepasst werden.</p>
<p>Zum Schluss den nötigen <span lang="en">JavaScript</span>- <abbr title="beziehungsweise">bzw</abbr>. <span lang="en">jQuery</span>-Teil, ohne den hier gar nichts läuft:</p>
<pre>
<dfn><abbr title="Hypertext Markup Language" lang="en">HTML</abbr></dfn>
<code class="block">&lt;head&gt;
  &lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
</code>
</pre>
<p>Im Kopf-Bereich binden wir die <span lang="en">jQuery-Library</span> ein.</p>
<pre>
<dfn lang="en">JavaScript</dfn>
<code class="block">jQuery(document).ready(function($) {
	$(&#x27;div.wp-caption&#x27;).each(function(i) {
		var img_ = $(&#x27;img&#x27;, this);
		var img_height = img_.attr(&#x27;height&#x27;);
		var p_height = $(&#x27;p&#x27;, this).outerHeight();

		$(this).height(img_height);
		$(this).hover(function() {
			img_.animate({marginTop : -p_height}, 500);
		}, function() {
			img_.animate({marginTop : &#x27;0&#x27;}, 500);
		});
	});
});
</code>
</pre>
<p>Mit der <code class="inline">each()</code>-Funktion wird jede einzelne <span lang="en">Image-Caption</span > auf der Seite angesprochen. Danach wird die Höhe des dazugehörigen Bildes und der Beschreibung gespeichert. Als nächstes wird die Höhe des <span lang="en">Caption</span >-<code class="inline">div</code> gleich der Höhe des Bildes gesetzt, so dass die Beschreibung abgeschnitten und nicht sichtbar ist.</p>
<p>Daraufhin wird eine <code class="inline">hover()</code>-Funktion aufgemacht. Fährt man mit dem <span lang="en">Cursor</span> über eine <span lang="en">Image-Caption</span>, bekommt das dazugehörige Bild einen negativen <code class="inline">margin-top</code>, der der Höhe der Beschreibung entspricht, so dass diese in den sichtbaren Bereich fährt. Verlässt man die <span lang="en">Image-Caption</span> wieder mit dem <span lang="en">Cursor</span>, wird der <code class="inline">margin-top</code> des Bildes wieder auf Null gesetzt. Das ganze wird mit der <code class="inline">animate()</code>-Funktion von <span lang="en">jQuery</span> animiert.</p>
<p>Das war es auch schon, fertig ist die animierte <span lang="en">Image-Caption</span> unter <span lang="en">WordPress</span>. Wobei natürlich nichts dagegen spricht, das ganze außerhalb von <span lang="en">WordPress</span> einzusetzen. Wie immer verweise ich an die Kommentar-Funktion, falls es Fragen gibt oder etwas nicht so funktioniert, wie es soll.</p>
<hr /><p>Verwandte Beitr&auml;ge:<ul>
<li><a href='http://www.emanuel-kluge.de/tutorial/animierte-navigation-mit-jquery/' rel='bookmark' title='Animierte Navigation mit jQuery'>Animierte Navigation mit jQuery</a></li>
<li><a href='http://www.emanuel-kluge.de/tutorial/hover-und-spotlight-effekt-in-bildergalerie-mit-jquery/' rel='bookmark' title='Hover- und Spotlight-Effekt in Bildergalerie mit jQuery'>Hover- und Spotlight-Effekt in Bildergalerie mit jQuery</a></li>
<li><a href='http://www.emanuel-kluge.de/html-css/ajax-wordpress-theme-backbone-js/' rel='bookmark' title='Studie &ldquo;Backboned&rdquo;: AJAX-powered WordPress-Theme mit Backbone.js'>Studie &ldquo;Backboned&rdquo;: AJAX-powered WordPress-Theme mit Backbone.js</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.emanuel-kluge.de/tutorial/animierte-image-caption-mit-jquery-unter-wordpress/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

