Überflüssige Wiederholungen vermeiden
Problem
Sie wollen ein paar DOM-Elemente beim Laden der Seite verbergen, anzeigen oder anders bearbeiten und dies auch zu einem späteren Zeitpunkt als Reaktion auf bestimmte Events wiederholen:
$(document).ready( function() { // Sichtbarkeit beim Starten setzen $('#state').toggle( $('#country').val() == 'US' ); $('#province').toggle( $('#country').val() == 'CA' ); // Sichtbarkeit ändern, wenn der Wert per Maus geändert wird $('#country').change( function() { $('#state').toggle( $(this).val() == 'US' ); $('#province').toggle( $(this).val() == 'CA' ); }); // Sichtbarkeit auch ändern, wenn der Wert per Tastatur geändert wird $('#country').keyup( function() { $('#state').toggle( $(this).val() == 'US' ); $('#province').toggle( $(this).val() == 'CA' ); }); });
Der Code funktioniert, aber Sie wollen ihn vereinfachen, so dass es nicht so viel doppelten Code gibt.
Note
Warum nutzen wir sowohl das change
- als auch das keyup
-Event? Viele Websites kümmern sich bei
einer Auswahlliste nur um das change
-Event. Das funktioniert prima, wenn Sie mit
der Maus eine Auswahl treffen. Wenn Sie aber in die Liste klicken
und dann die Pfeiltasten nutzen, um eine der Optionen auszuwählen,
passiert nichts – Tastenbetätigungen feuern in einer Auswahlliste
keine change
-Events. Kümmern Sie sich
auch um das keyup
-Event, dann reagiert
die Auswahlliste auch auf die Pfeiltasten und hilft damit
Anwendern, die mit der Tastatur arbeiten (müssen).
Lösung 1
Verschieben Sie den doppelten Code in eine
Funktion und rufen Sie diese sowohl beim Laden der Webseite als
auch als Reaktion auf die Events auf. Mit der jQuery-Methode
.bind()
verbinden Sie beide Eventhandler gleichzeitig.
Und speichern Sie Daten, die mehr als einmal genutzt werden, in
Variablen:
$(document).ready( function() { var $country = $('#country'); function setVisibility() { var value = $country.val(); $('#state').toggle( value == 'US' ); $('#province').toggle( value == 'CA' ); } setVisibility(); $country.bind( 'change keyup', setVisibility ); });
Lösung 2
Verwenden Sie das Event Triggering von jQuery,
um das Event direkt nach dem Binden zu feuern. Dazu kommen noch der
.bind()
-Trick und die lokalen
Variablen aus Lösung 1:
$(document).ready( function() { $('#country') .bind( 'change keyup', function() { var value = $(this).val(); $('#state').toggle( value == 'US' ); $('#province').toggle( value == 'CA' ); }) .trigger('change'); });
Diskussion
Es ist in fast jeder Programmiersprache gute
Praxis, doppelten Code in eine eigene Funktion auszulagern, die
dann von mehreren Orten aus aufgerufen werden kann. Lösung 1 folgt
diesem Ansatz: Statt den Code für das Setzen der Sichtbarkeit zu
wiederholen, gibt es ihn nur einmal in der Funktion setVisibility()
. Der Code ruft dann diese Funktion
direkt beim Starten und indirekt beim Feuern der Events
change
oder keyup
auf.
In Lösung 2 wird auch eine gemeinsame Funktion
für beide Fälle verwendet. Aber anstatt der Funktion einen Namen zu
geben, so dass man sie direkt beim Starten aufrufen kann, setzt der
Code die Funktion nur als Eventhandler für die change
- und keyup
-Events. Dann nutzt er die Methode
trigger()
, um eines der Events auszulösen – und damit
die Funktion indirekt aufzurufen.
Diese Vorgehensweisen sind mehr oder weniger austauschbar – es ist eher eine Geschmacksfrage, was Sie lieber nutzen wollen.