JQuery Kochbuch (German Edition)
einem Objekt mit dem Prototype des Konstruktors eine Methode hinzufügen.
Wofür gibt es dann
jQuery.fn
überhaupt? Warum nutzt man nicht einfach
jQuery.prototype
, so wie jeder andere objektorientierte JavaScript-Code? Nun, es geht nicht nur darum, ein paar Zeichen einzusparen.
Die allererste Version von jQuery (noch lange vor 1.0) hat das
prototype
-Feature von JavaScript nicht genutzt, um Methoden für ein jQuery-Objekt bereitzustellen. Es hat Referenzen auf jede Eigenschaft und Methode in
jQuery.fn
(später als
$.fn
bezeichnet) in das jQuery-Objekt kopiert , indem es das Objekt durchlaufen hat.
Da es sich dabei um hunderte von Methoden handelt kann und dies bei jedem Aufruf von
$()
geschieht, kann das ziemlich langsam sein. Daher wurde der Code geändert und der JavaScript-Prototype genutzt, um all das Kopieren zu vermeiden. Um zu verhindern, dass Plugins, die
$.fn
schon nutzten, zerstört werden, wurde dieses zu einem Alias für
$.prototype
:
$.fn = $.prototype;
Das ist der Grund, warum
jQuery.fn
heutzutage existiert – weil Plugins schon 2006
$.fn
verwendet haben!
----
Einen eigenen Iterator schreiben
Problem
Sie haben in einem jQuery-Objekt mehrere Elemente selektiert und müssen diese durchlaufen, wobei zwischen jeder Iteration eine kurze Pause liegen soll. Damit kann man zum Beispiel die Elemente nacheinander anzeigen:
Achtung!
Auf die Plätze!
Fertig!
Los!
Sie haben
each()
ausprobiert, aber damit werden natürlich alle Elemente auf einmal behandelt:
$('.reveal').each( function() {
$(this).show();
});
// Das war nicht besser als diese einfachere Version:
$('.reveal').show();
Lösung
Schreiben Sie einen eigenen Iterator, der
setTimeout()
nutzt, um die Callbacks ein wenig zu verzögern:
// Iterieren über ein Array (meist ein jQuery-Objekt, kann aber
// jedes Array sein) und Aufruf einer Callback-Funktion für jedes
// Element mit einer Zeitverzögerung zwischen jedem Aufruf.
// Der Callback erhält die gleichen Argumente wie ein normaler
// jQuery.each()-Callback.
jQuery.slowEach = function( array, interval, callback ) {
if( ! array.length ) return;
var i = 0;
next();
function next() {
if( callback.call( array[i], i, array[i] ) !== false )
if( ++i < array.length )
setTimeout( next, interval );
}
return array;
};
// Iterieren über "this" (ein jQuery-Objekt) und Aufrufen einer Callback-
// Funktion für jedes Element mit einer Zeitverzögerung zwischen
// jedem Aufruf.
// Der Callback erhält die gleichen Argumente wie ein normaler
// jQuery(...).each()-Callback.
jQuery.fn.slowEach = function( interval, callback ) {
return jQuery.slowEach( this, interval, callback );
};
Dann ändern Sie einfach Ihren Code für
.each()
in
.slowEach()
und ergänzen den Verzögerungswert:
// Alle halbe Sekunde ein Element anzeigen
$('.reveal').slowEach( 500, function() {
$(this).show();
});
Diskussion
Die jQuery-Methode
.each()
ist kein Hexenwerk. Reduzieren wir den Code der Implementierung in Version 1.3.2 auf den häufigsten Anwendungsfall (das Iterieren über ein jQuery-Objekt), bleibt eine recht einfache Schleife:
jQuery.each = function( object, callback ) {
var value, i = 0, length = object.length;
for(
value = object[0];
i < length && callback.call( value, i, value ) !== false;
value = object[++i]
) {}
return object;
};
Dies ließe sich auch etwas besser lesbar schreiben:
jQuery.each = function( object, callback ) {
for(
var i = 0, length = object.length;
i < length;
++i
) {
var value = object[i];
if( callback.call( value, i, value ) === false )
break;
}
return object;
};
Wir können ähnliche Funktionen schreiben, um über Arrays oder jQuery-Objekte auf anderen, nützlichen Wegen zu iterieren. Ein einfacheres Beispiel als
.slowEach()
ist eine Methode, die rückwärts über ein jQuery-Objekt iteriert:
// Rückwärts über ein Array oder jQuery-Objekt iterieren
jQuery.reverseEach = function( object, callback ) {
for( var value, i = object.length; --i >= 0; ) {
var value = object[i];
console.log( i, value );
if( callback.call( value, i, value ) === false )
break;
}
};
// Rückwärts über "this" (ein jQuery-Objekt) iterieren
jQuery.fn.reverseEach = function( callback ) {
jQuery.reverseEach( this, callback );
return this;
};
Dabei wird nicht versucht, alle Fälle zu behandeln, um die sich
.each()
kümmert, sondern nur die einfachsten
Weitere Kostenlose Bücher