Archiv nach Autor

jQuery Mobile – Der Seitenaufbau

Bevor man damit beginnt seine ersten mobile Websites zu bauen, gibt es einige grundlegende Punkte die Struktur betreffend zu wissen.
Zunächst einmal arbeiten wir unter dem HTML5 Doctype. Was in mobilen Endgeräten glücklicherweise kein Problem ist, da diese HTML5 in sogut wie allen Fällen verstehen.

Der HTML Head mit den für jQuery Mobile notwendigen JS-Skripten, sieht nun wie folgt aus:

1
2
3
4
5
6
7
8
<!DOCTYPE html>
<html>
	<head>
	<title>Meine mobile Website</title>
	<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.css" />
	<script src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
	<script src="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.js"></script>
</head>

Für das Framework benötigen wir im HTML Teil nun ein spezielles Attribut mit der Bezeichnung “data-role”, das den allgemein Aufbau der Seite definiert.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div data-role="page">
<body>
 
<div data-role="page">
 
	<div data-role="header">
		<h1>Meine mobile Website</h1>
	</div>
 
	<div data-role="content">
		<p>Hier der normale Seiteninhalt..</p>
	</div>
 
	<div data-role="footer">
		<p>Allgemeine Seiteninfo</p>
	</div>
</div>
 
</body>
</html>
</div>

Der notwendigen Attributausprägungen sind hierbei page, header, content und footer. Jedes einzelne dieser Divs ist frei mit normalen HTML Tags befüllbar.

Damit haben wir nun schon unsere erste statische Seite. Obwohl wir ein Javascript Framework benutzen, brauche wir bisher dafür noch kein Javascript. Alle notwendigen Schritte laufen im Hintergrund ab.

Im nächsten Teil widmen wir uns dann der Verlinkung mittels Ajax und dem Wechsel zwischen verschiedenen Seiten..

fadeToggle – die Neue in jQuery 1.4.4

Diese Woche ist jQuery in einem neuen Release erschienen. Neben einigen Bugfixes und kleinen Ändererungen gibt es auch die neue Funktion “fadeToogle”. Sie funktioniert vom Prinzip her genauso wie “toggleClass” und “slideToogle” und dient, wie die anderen, dazu möglichst einfach zwischen verschiedenen Zuständen zu wechseln. Wir wollen das an zwei Beispielen verdeutlichen.

Werfen wir vorher einen Blick auf die Signatur der neuen Methode:
.fadeToggle( [ duration ], [ easing ], [ callback ] )

Duration ist die Zeit in der das Fading ausgeführt wird
Easing ist die Art des Effektes, wobei es standardmäßig hier keine relevanten Änderungsoptionen gibt
Eine Callback Funktion um nach der Animation beliebigen Code auszuführen.

Der Javascript Code sieht nun wie folgt aus:

?View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    // Variable um aktuellen Sichtbarkeitsstatus zu speichern
    var toogleState = "visible"
 
    $(document).ready(function() {
        //Beispiel 1
        $("button:first").click(function() {
          $("div#fadingBox").fadeToggle("slow", "linear");
        });
 
        //Beispiel 2
        $("button:last").click(function () {
          $("p:first").fadeToggle("fast", function () {
 
            if(toogleState == "visible"){
                $("button:last").text("zeigen");
                toogleState = "invisible";
            }
            else{
                $("button:last").text("verstecken");
                toogleState = "visible";
            }
 
          });
        });
 
    });

Das erste Beispiel ist ein Box die einfach aus- und wieder eingeblendet wird. Ohne, dass der aktuelle Anzeigestatus sichtbar oder abrufbar wäre.

Das zweite Beispiel zeigt einen einfachen Workaround, um mit dem aktuellen Anzeigemodus zu arbeiten. Also ist das Element gerade sichtbar oder nicht. Die hier vorgestellte Variante ist einfacherer Natur. Es wäre natürlich auch möglich, direkt den Sichtbarkeitsstatus des Objektes selbst abzufragen und entsprechend zu reagieren. Die vorgestellte Möglichkeit wurde wegen der besseren Nachvollziehbarkeit so gewählt. Allerdings wäre sie für größere Projekte wegen einer schlechteren Wartbarkeit weniger zu empfehlen.

Eine Demo dazu findet ihr hier.
Weder das CSS noch das JS sind ausgelagert, also einfach rechte Maustaste und Quelltext anzeigen lassen.

Typeface mit font-weight:bold

Als Webentwickler kennt man das Problem mit kommerziellen Schriftarten, die aus dem Corporate Design stammen, aber nicht als Webfont zur Verfügung stehen. Beliebt sind dafür immer verschiedenste Formen des Image-Replacements. Die Nachteile davon liegen auf der Hand:

  • Keine optimale Suchmaschinerkennung
  • Hoher Änderungs- und Verwaltungsaufwand
  • Text nicht kopierbar
  • Problem der Barrierefreiheit

Neben der Bilderlösung dürfte sIFR eine bekannte Methode sein. Hier wird der Text aus einem bestimmten HTML-Tag gelesen und durch einen Flashfilm mit eingebettem Font ersetzt. In der Theorie gut, in der Praxis schwierig wegen eines enorm hohen Konfigurationsaufwands.

Nach dem gleichen Prinzip funktioniert das js-Plugin Typeface. Nur ist es etwas praktischer in der Handhabung.
Der folgende Code bindet einen normalen Font und einen später beschriebenen Bold-Font ein:

?View Code JAVASCRIPT
1
2
3
<script src="typeface-0.14.js"><!--mce:0--></script>
<script src="mysrcFont.typeface.js"><!--mce:1--></script>
<script src="mysrcFontBold.typeface.js"><!--mce:2--></script>

Um dem Text die entsprechende Schriftart zuzuweißen, benutzt man einfach die CSS Anweisung font-family.

1
2
<div id="text" style="font-family: mySrc Font;">
Lorum ipsolum...</div>

Den Namen des im syle-Attribut verwendeten Fonts kann man in den jeweiligen js-Dateien nachlesen.
Das Ganze hat zwei Nachteile, wie sie auch schon auf der Website beschrieben werden. Performanceprobleme bei größeren Textmengen und Standard-CSS Hovereffekte funktionieren nicht mehr.
Damit der Font in eine Javascript Datei umgewandelt werden muss er in einem Truetype oder Opentype Format vorliegen. Nicht immer ist bei diesen Schriften auch die fette Variante integriert. Um das in den Griff zu bekommen, kann man mit einem Font Bearbeitungstool nur die Bold-Variante exportieren und diese ebenfalls umwandeln. Bindet man nun diese beide JS-Dateien ein und weist die Bold-Schrift einem einem HTML-Element zu, passiert abgesehen von einer Fehlerausgabe in der Firebug Konsole nichts.
Die Lösung dafür ist ganz einfach. Der Font-Converter auf der Typeface Website integriert auch Informationen über Schriftschnitte weshalb der CSS-Selektor diese Info auch benötigt:

1
2
3
4
5
6
7
8
#text{
  font-family: mySrc Font, Verdana, Arial;
}
 
#boldFont{
  font-family: mySrc Boldfont, Verdana, Arial;
  font-weight: bold;
}

Damit ist der Workaround für die Einbettung von normalen und bold Schriften perfekt.

Cufón – Eine Javascript alternative zu sIFR
sIFR 3 r436 – scroll-Problem im Firefox 3, ie6/7

jQuery load function – Ajax the simple way (Part 1)

Mit der load Funktion lassen sich einfach HTML-Elemente einer Datei in die Aktuelle einfügen. Diese Funktion ist in erster Linie für den “import” von HTML-Code gedacht und entspricht damit nicht dem typischen Ajax-Request bei dem bspw. ein PHP Skript angesprochen wird, das Daten aus der Datenbank liest und/oder andere serverseitige Prozesse anstösst.

Soviel erstmal zur Theorie, der Funktionsaufruf sieht wie folgt aus:

?View Code JAVASCRIPT
1
 $('#someElement').load('/someFile #mydiv');

So kurz so einfach. In das Element mit der id “someElement” wird der gesamte Inhalt eines divs mit der id “mydiv” geladen. Das geniale dabei ist, dass sich “mydiv” überhaupt nicht im aktuellen Dokument befindet, sondern in der Datei “someFile”.
Als zweiten Parameter kann man der load Funktion auch noch Daten als sogenanntes Key/Value Paar übergeben.

?View Code JAVASCRIPT
1
 $('#someElement').load('someFile.php',{'param': 'someValue'});

Das enspricht allerdings jetzt schon eher dem normalen Ajax-Request. Das oder die Key/Value Paare werden dem php-Skript als post-Paramter übergeben. Natürlich verliert man damit den Vorteil des vorigen Beispiels sich einfach DOM-Elemente aus einem anderen HTML-Skript zu holen. Aber falls man das Ergebnis eines Request einfach direkt ohne weitere Verarbeitung in ein Element einfügen möchte, ist das eine sehr einfache und komfortable Variante.

Im nächsten Teil wird es dann um die anderen fortgeschritten jQuery Ajax Varianten wie get, getJSON, etc. gehen.

jQuery HowTo: Traversing

Travesieren gehört zum grundlegenden Handwerkszeug, wenn man fortgeschrittene Animationen mittels jQuery durchführen möchte. Hier ein kleine Anleitung zum Auffinden bestimmter Elemente.

Parent

 »Child1
 »Child2
 »Child3
 »Child4

Was passiert hier? Basis ist diese HTML Struktur:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div id="someParent" style="border: 1px dotted #ccc">Parent
<div>
 Child1
</div>
<div class="move">
 Child2
</div>
<div>
 Child3
</div>
<div class="move not">
 Child4
</div>
</div>
 
<div id="someWrapper">
<a  id="testone" href="#">Move all</a>
<a id="testtwo" href="#">Move filtered</a>
</div>

Folgender Javascript-Code führt die Animation aus. Ausgehend von dem Link wird mit den Methoden parent das div “someWrapper” selektiert, prev wählt das vorige Element mit der id “someParent” und schlussendlich werden mit children alle Elemente innerhalb von “someParent” selektiert.
Die id’s im Beispiel dienen nur der Veranschaulichung. Die zu animierenden Elemente werden ausschließlich über die Struktur des DOM gefunden.

jQuery Code für “Move all”:

?View Code JAVASCRIPT
1
2
3
4
jQuery("#testone").click(function () {
    jQuery(this).parent().prev().children().animate({'paddingLeft':'20px'},200);
     return false;
});

Nun zur fortgeschrittenen Variante. Basis dafür sind die jQuery Funktion, filter und not.
jQuery Code für “Move filtered”:

?View Code JAVASCRIPT
1
2
3
4
jQuery("#testtwo").click(function () {
   jQuery(this).parent().prev().children().filter(".move").not(".not").animate({'paddingLeft':'20px'},200);
    return false;
});

Praxistipp: jqTransform Button width einstellen

So nett und schön das jqTransform Plugin auch ist, macht es i.A. doch ein paar kleine Probleme. Neben der unterschiedlichen Interpretation der Breite von Textfeldern in FF und IE, lässt sich auch die Breite der Standardbuttons nicht aus dem eigenen CSS einstellen.

Wer dies tun möchte und die entsprechende Einstellung nicht finden kann, dem sei hier eine kleine Hilfe geboten. Dazu müsst ihr die jqtransform.css öffnen und in Z.36 dem Selektor “button.jqTransformButton span span” die neue Eigenschaft width zuweisen.
Das kann dann beispielsweise wie folgt aussehen:

1
2
3
4
5
6
7
8
9
10
11
12
13
button.jqTransformButton span span {
	background: transparent url(img/btn_left.gif) no-repeat top left;
	color: #333;
	padding: 10px 4px 0px 8px;
	font-weight: normal;
	font-size: 12px;
	line-height: 13px;
	display: block;
	text-decoration: none;
	height: 33px;
	width:auto;
	min-width: 100px;
}

Praxistipp – jqTransform width bug

Wer jqTransform schon einmal benutzt hat wird sicherlich festgestellt haben, dass der Internet Explorer und der Firefox Browser die Textfelder in einer unterschiedlichen Breite darstellen.
Das ist zurückzuführen auf das size-Attribut, dass selbst wenn nicht im input Feld verankert im IE mitberücksichtigt wird.

Ein kleiner Workaround dafür ist, die Berechnung des Size-Attributs im js-Code zu entfernen. Selbstverständlich mit der Folge, dass dieses Attribut nicht mehr zu diesem Zweck eingesetzt werden kann. Was ich persönlich als nicht weiter schlimm erachte, da zur Best Practice des Webprogrammieres gehört, die Festlegung von Oberflächeneigenschaften über das CSS zu definieren.

Nun zum Workaround:

?View Code JAVASCRIPT
1
2
3
4
5
// Z. 107 in der jquery.transform.js
	if($input.attr('size')){
		inputSize = $input.attr('size')*10;
		$input.css('width',inputSize);
	}

Diesen Codeteil könnt ihr einfach löschen, da es zur falschen Berechnung der Breite für die Textfelder führt. Ich konnte keine ungewollten Seiteneffekte feststellen. Wenn ihr etwas findet, wäre ich dankbar für Kommentare.

Praxistip – jqTransform und display:none

Wenn jemand schon einmal versucht hat ein, mit jqTransform umgewandeltes Formularfeld, in einem auf display:none gesetzten HTML-Element anzuzeigen, dürfte er auf Probleme gestossen sein.
Das lässt sich mit einem kleinen Workaround, ohne in das Original js ändern zu müssen, leicht beheben.

Zuerst die display Eigenschaft wieder sichtbar setzen

1
2
3
4
5
6
<form action="some.php" id="myForm" method="post">
  <div style="display:block" id="status">
     <input type="text" value="content" />
  </div>
</form>
</div>

Wäre die CSS-Eigenschaft display auf none gesetzt, würde das eingebaute jqTransform zur fehlenhaften Anzeige führen. Um dieses Element jetzt trotzdem nicht anzuzeigen kann man einfach folgendes Codestück im “document ready” Event von jQuery einbauen

?View Code JAVASCRIPT
1
2
3
4
5
6
<script type="text/javascript">
jQuery(document).ready(function($) {
     //some code...
 
     jQuery('#status').hide('fast');
 });

Das Prinzip lässt sich mit entsprechenden jQuery Selektoren natürlich auch auf mehrere Elemente übertragen.

IxEdit – jQuery the easy way

Mit IxEdit ist es möglich JQuery Funktionen ohne JS-Programmierung direkt on-the-Fly im Browser den gewünschten HTML Elementen zuzuweißen. Statt vieler weiterer Worte das Demo Video:

Wenn ihr es ausprobieren wollt, so gehts:

1. Als erstes die notwendigen IxEdit Dateien von IxEdit herunterladen

2. Das das Google Gears Firefox Addon Google Gears Portable installieren und Browser neu starten

3. Im entpackten IxEdit Ordner die index.html aufrufen

Nun könnt ihr den bestehenden HTML Elementen nach belieben jQuery Events zuweißen. Das Tool ist ideal zum Experimentieren mit verschiedenen Effekten und auch allgemein um sich einen besseren Überblick über die Möglichkeiten von JQuery zu verschaffen.

Nachdem alle gewünschten Effekte integriert sind, wird mit der Deploy-Funktion der entsprechende jQuery Code angezeigt, der dann in das Quelldokument kopiert werden kann.

Easy oder!?

Praxistip: Output Element des jQuery Validate Plugin ändern

Das allseits bekannte jQuery Plugin um Formularfelder zu validieren funktioniert im Standardszenarion sogut wie problemlos.

Schwieriger wird es schon wenn mehrere Plugins auf ein Formular angewendet werden, bei denen die Plugins eigene DOM-Elemente hinzufügen. Beispielsweise jqTransform

Glücklicherweise bietet das validate Plugin dafür eine wunderbare Funktion, nämlich errorPlacement.
Die Funktion sieht so aus:

?View Code JAVASCRIPT
1
2
3
 errorPlacement: function(error, element) {
     error.appendTo( element.TRAVERSINGFUNKTION );
   },

Nehmen wir ein Formular:

1
2
3
4
5
6
7
<form action="somescript.php" id="form" method="get">
   <input type="text" name="user">
   <label><label>
   <input type="text" name="pw">
   <label><label>
</form>
 <div id="error"></div>

Per Default wird vom validate Plugin ein Label-Tag hinter jedes input-Feld eingefügt. Will man nun den error an einer anderen Stelle zeigen kann man die Funktion folgendermaßen umschreiben:

?View Code JAVASCRIPT
1
2
3
4
5
$("#form").validate({
  errorPlacement: function(error, element) {
     error.appendTo( element.next() );
   }
});

Die Fehlermeldungen würde nun ausgehend vom input (element) in das nächste DOM Element, in unserem Fall das label-Tag, geschrieben werden.
Natürlich haben wir mit diesem Beispiel nur wieder das Ausgangsverhalten des Plugins erreicht. Dieses Prinzip lässt leicht auf komplexere Anwendungsfälle übertragen. Wie beispielsweise bei erwähntem jqTransform, bei dem um das input-Feld mehrere Divs gelegt werden. Die Fehlermeldung des Validate Plugins wird dann unterhalb (auf z-Ebene) der Felder angezeigt. Durch travesieren durch den DOM-Baum können die Fehlermeldungen beliebig positioniert werden.