template

Index :: Javascript :: Maus: Wheel

Das Mausrad dient als 1-dimensionales Kontrollinstrument zum Verschieben von Objekten/Werten entlang einer Koordinate. Es eignet sich z.B. zum Scrollen von Dokumenten in Y-Richtung oder zum Hinein-/Herauszoomen in Z-Richtung.

Im Unterschied zu vielen anderen Controls liefert das Mausrad keinen absoluten Wert, sondern eine Differenzangabe, das sogenannte Delta. Dieser Delta-Wert ist nicht standardisiert und hängt von Browsertyp, Betriebssystem, Hardware und Benutzereinstellungen ab.
Meistens will das verarbeitende Skript nur wissen, in welche Richtung das Rad gedreht wurde, d.h. eine Information wie 1 (für nach oben) oder -1 (für nach unten) ist völlig ausreichend. Der vom Browser gelieferte Wert muss also vom eingeklinkten Event-Handler bezüglich Vorzeichen und Einheiten erst formatiert werden.

Eine Wheel-Abfrage hat freilich nur Sinn, wenn der Benutzer eine entsprechende Maus verwendet. Deshalb sollte man immer alternative Möglichkeiten wie etwa Scrollbar-Derivate, Plus/Minus-Schaltflächen oder Tastatursteuerung bereitstellen.


Interne Funktionsweise

Auf der obersten Stufe der Ereignisabfrage steht eine eigene Funktion, hier FuWheel() genannt, die den Delta-Wert (normalerweise 1 oder -1) entgegennimmt und die erforderlichen Aktionen durchführt. Welche dies sind, hängt ganz vom Anwendungsfall ab:
function FuWheel(d) {
  // ... Delta verwerten ...
}
Sie wird von einem eigenen Event-Handler aufgerufen, der hier EvWheel() heisst und die Aufgabe hat, den Delta-Wert zu ermitteln und je nach Browserumgebung zu korrigieren:
function EvWheel(e) { var d=0; e=e||window.event;
  if (e.wheelDelta) { d=e.wheelDelta/120; if (window.opera) d=-d; } else if (e.detail) d=-e.detail/3;
  if (d) FuWheel(d); if (e.preventDefault) e.preventDefault(); return e.returnValue=false;
}
Die Installation von EvWheel() erfolgt entweder bereits beim Laden der Seite oder erst später zur Laufzeit.
Hier sehen wir die Initialisierung der Ereignisabfrage; sie betrifft das Element obj, dessen Mausrad-Event abgefangen werden soll:
if (obj.addEventListener) obj.addEventListener('DOMMouseScroll',EvWheel,false);
obj.onmousewheel=EvWheel;
Da onmousewheel nicht in allen Umgebungen zur Verfügung steht, wird präventiv auch versucht, die addEventListener-Methode zu benutzen.

Verwaltung mehrerer Wheel-Objekte

Manchmal sollen auf einer Seite gleich mehrere Elemente individuell auf das Mausrad reagieren. Zwar könnte man nun für jedes Objekt einen separaten Event-Handler schreiben, aber damit entstünde viel redundanter Code. Zwecks Übersicht und Pflegbarkeit bleibt man besser bei einen einzigen, zentralen Handler, der dann jeweils die Delta-Verarbeitungsfunktion des betreffenden Objekts aufruft.
Zum Ansprechen einer solchen Verarbeitungsfunktion (hier: FuWheel()) wird der Ausdruck this verwendet, der sich ja innerhalb des Handlers auf das entsprechende Objekt bezieht:
function EvWheel(e) { var d=0; e=e||window.event;
  if (e.wheelDelta) { d=e.wheelDelta/120; if (window.opera) d=-d; } else if (e.detail) d=-e.detail/3;
  if (d) this.FuWheel(d); if (e.preventDefault) e.preventDefault(); return e.returnValue=false;
}
Die Erweiterung eines Objekts um seine FuWheel-Funktion gestaltet sich simpel, z.B. mithilfe einer anonymen Funktion. Meist wird auch noch eine Variable (hier: whVal) zur Speicherung einer aktuellen Skalenposition benötigt.
obj.whVal = 0;
obj.FuWheel = function(d) {
  // ... Delta verwerten: this.whVal+=d; ...
}

Zur Einbindung des Handlers benutzt man eine Hilfsfunktion (hier SetWheel), der man das gewünschte Objekt übergeben kann. In einem zweiten Parameter lässt sich auch eine FuWheel-Funktion angeben, die der Handler bei dieser Gelegenheit gleich zuweist.
Entsprechend kann mittels RemWheel() die Abfrage des Objekts wieder deaktiviert werden.
function SetWheel(obj,fu) { if (fu) obj.FuWheel=fu;
  if (obj.addEventListener) obj.addEventListener('DOMMouseScroll',EvWheel,false);
  obj.onmousewheel=EvWheel;
}
function RemWheel(obj) {
  if (obj.removeEventListener) obj.removeEventListener('DOMMouseScroll',EvWheel,false);
  obj.onmousewheel=function(){return true;}
}

Das eigentliche Initialisieren des Objekts erfolgt entweder beim Laden der Seite oder erst irgendwann zur Laufzeit und könnte dann etwa so aussehen (die Delta-Verarbeitungsfunktion FuWheel() wird hier anonym deklariert):
obj.whVal = 50;
SetWheel(obj, function(d) {
  // ... Delta verwerten: this.whVal+=d; ...
});

Demo

Vertikales Scrolling (Y-Achse)
Hier wird eine Tabelle überwacht: Sie reagiert auf Drehung des Mausrads mit dem Umfärben (gelb/grau) der breiten Zellen, wodurch der Effekt eines sich nach oben bzw. unten bewegenden Balkens entsteht.
Test
Zoom (Z-Achse) - Beispiel 1
Hier wird eine Zelle überwacht: Sie reagiert auf Drehung des Mausrads mit der Schriftgrößenänderung des enthaltenen Textes.
Zoom (Z-Achse) - Beispiel 2
Hier wird ein Image überwacht: Es reagiert auf Drehung des Mausrads mit der Skalierung seiner Größe.

Index :: Javascript


template