JQuery Kochbuch (German Edition)
Hinzufügen oder Entfernen eines Attributs foo="bar".
// Umschalten der Anwesenheit des Attributs, wenn add weggelassen wird.
jQuery.fn.toggleFoo = function( add ) {
return this.toggleAttr( 'foo', 'bar', null, add );
};
Diskussion
Es ist immer gut, sich vor einer schleichenden Featuritis zu schützen. Wenn wir wirklich nur Checkboxen umschalten können müssten, würde folgender Code ausreichen:
jQuery.fn.toggleCheck = function( on ) {
return on !== undefined ?
this.attr( 'checked', on ) :
this.each( function( i, element ) {
var $element = $(element);
$element.attr( 'checked', ! $element.attr('checked') );
});
};
Dies ist ein bisschen einfacher als unsere Methode
.toggleAttr()
, aber es ist nur für das Attribut
checked
nützlich und für nichts anderes. Was würden wir tun, wenn wir später die Methode
.toggleEnable()
bräuchten? Kopieren der Methode und Anpassen von ein paar Namen?
Die zusätzliche Arbeit, die wir in
.toggleAttr()
gesteckt haben, bringt uns viel Flexibilität: Wir können jetzt eine ganze Familie von Attributs-Umschaltern schreiben, die jeweils nur aus einer Zeile Code bestehen.
----
Note
Werfen Sie einen Blick in die Dokumentation für die von Ihnen genutzte Version von jQuery, bevor Sie solche neuen Hilfsmethoden schreiben. Es kann gut sein, dass zukünftige Versionen von jQuery bereits das haben, was Sie brauchen, so dass Sie sich schon von vorneherein den Aufwand des selbst Schreibens sparen können.
----
Performance-Killer finden
Problem
Ihre Site lädt zu langsam oder reagiert zu langsam auf Klicks und andere Benutzer-Interaktionen, und Sie wissen nicht, warum. Welcher Teil des Codes verbraucht da zuviel Zeit?
Lösung
Nutzen Sie einen Profiler – entweder einen der vielen verfügbaren oder einen einfachen, den Sie selbst programmieren können.
Diskussion
Mit einem Profiler kann man die Code-Abschnitte finden, die die meiste Zeit verbrauchen. Sie haben vermutlich mindestens einen guten JavaScript-ProfilerzurVerfügung. Firebug enthält einen und im IE 8 und in Safari 4 sind sie auch schon eingebaut. Dabei handelt es sich immer um Funktions-Profiler: Sie beginnen mit dem Profiling, arbeiten auf Ihrer Seite und beenden das Profiling wieder. Dann erhalten Sie einen Bericht, der zeigt, wie viel Zeit in jeder Funktion verbraucht wurde. Das kann ausreichen, um Ihnen zu zeigen, welchen Code-Abschnitten Beine gemacht werden müssen.
Es gibt auch ein paar Profiler, die speziell auf jQuery ausgerichtet sind und die Sie mit einer Web-Suche nach jquery profiler finden können. Damit lässt sich die Performance von Selektoren ermitteln und Sie können sich die Geschwindigkeit von jQuery-Funktionen genauer anschauen.
Für eine wirklich detaillierte Analyse, bei der Sie einzelne Abschnitte des Codes untersuchen müssen, die nicht ganzen Funktionen entsprechen, können Sie sich mit ein paar Zeilen Code einen einfachen Profiler schreiben. Vielleicht gehen Sie dabei ganz klassisch vor:
var t1 = +new Date;
// ... eigentlicher Code ...
var t2 = +new Date;
alert( ( t2 - t1 ) + ' milliseconds' );
----
Note
Der Code
+new Date
ist schlicht ein einfacherer Weg, das vertrautere
new Date().getTime()
zu schreiben: Man erhält die aktuelle Zeit in Millisekunden zurück.
Warum funktioniert das? Nun, der Teil
new Date
ist gleich: Man erhält ein
Date
.Objekt, das die aktuelle Zeit repräsentiert. (Die Klammern sind optional, da es keine Argumente gibt.) Der Operator
+
konvertiert das Objekt in eine Zahl. Dabei wird die Objekt-Methode
.valueOf()
aufgerufen.Und ganz zufällig liefert die Methode
.valueOf()
für ein
Date
-Objekt das Gleiche zurück wie
.getTime()
– die Uhrzeit in Millisekunden.
----
Wir können mit nur 15 Zeilen Code eine allgemeiner nutzbare Funktion schreiben:
(function() {
var log = [], first, last;
time = function( message, since ) {
var now = +new Date;
var seconds = ( now - ( since || last ) ) / 1000;
log.push( seconds.toFixed(3) + ': ' + message + '
' );
return last = +new Date;
};
time.done = function( selector ) {
time( 'total', first );
$(selector).html( log.join('') );
};
first = last = +new Date;
})();
Jetzt haben wir eine Funktion
time()
, diewir immer dann aufrufen können, wenn wir die vergangene Zeit seit dem letzten Aufruf von
time()
protokollieren wollen (oder optional seit einer bestimmten Zeitpunkt). Wenn wir fertig sind und die Ergebnisse ausgegeben haben wollen, rufen wir
time.done()
auf. Hier ein Beispiel:
//
Weitere Kostenlose Bücher