1 /* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
2 * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
3 * full text of the license. */
6 * @requires OpenLayers/Handler.js
10 * Class: OpenLayers.Handler.MouseWheel
11 * Handler for wheel up/down events.
14 * - <OpenLayers.Handler>
16 OpenLayers.Handler.MouseWheel = OpenLayers.Class(OpenLayers.Handler, {
18 * Property: wheelListener
24 * Property: mousePosition
25 * {<OpenLayers.Pixel>} mousePosition is necessary because
26 * evt.clientX/Y is buggy in Moz on wheel events, so we cache and use the
27 * value from the last mousemove.
32 * Constructor: OpenLayers.Handler.MouseWheel
35 * control - {<OpenLayers.Control>}
36 * callbacks - {Object} An object containing a single function to be
37 * called when the drag operation is finished.
38 * The callback should expect to recieve a single
39 * argument, the point geometry.
42 initialize: function(control, callbacks, options) {
43 OpenLayers.Handler.prototype.initialize.apply(this, arguments);
44 this.wheelListener = OpenLayers.Function.bindAsEventListener(
45 this.onWheelEvent, this
53 OpenLayers.Handler.prototype.destroy.apply(this, arguments);
54 this.wheelListener = null;
58 * Mouse ScrollWheel code thanks to http://adomas.org/javascript-mouse-wheel/
62 * Method: onWheelEvent
63 * Catch the wheel event and handle it xbrowserly
68 onWheelEvent: function(e){
70 // make sure we have a map and check keyboard modifiers
71 if (!this.map || !this.checkModifiers(e)) {
75 // Ride up the element's DOM hierarchy to determine if it or any of
77 // * specifically marked as scrollable
78 // * one of our layer divs
81 var overScrollableDiv = false;
82 var overLayerDiv = false;
83 var overMapDiv = false;
85 var elem = OpenLayers.Event.element(e);
86 while((elem != null) && !overMapDiv && !overScrollableDiv) {
88 if (!overScrollableDiv) {
90 if (elem.currentStyle) {
91 overflow = elem.currentStyle["overflow"];
94 document.defaultView.getComputedStyle(elem, null);
95 var overflow = style.getPropertyValue("overflow");
97 overScrollableDiv = ( overflow &&
98 (overflow == "auto") || (overflow == "scroll") );
100 //sometimes when scrolling in a popup, this causes
101 // obscure browser error
106 for(var i=0, len=this.map.layers.length; i<len; i++) {
107 // Are we in the layer div? Note that we have two cases
108 // here: one is to catch EventPane layers, which have a
109 // pane above the layer (layer.pane)
110 if (elem == this.map.layers[i].div
111 || elem == this.map.layers[i].pane) {
117 overMapDiv = (elem == this.map.div);
119 elem = elem.parentNode;
122 // Logic below is the following:
124 // If we are over a scrollable div or not over the map div:
125 // * do nothing (let the browser handle scrolling)
129 // If we are over the layer div:
132 // * kill event (so as not to also scroll the page after zooming)
136 // Kill the event (dont scroll the page if we wheel over the
137 // layerswitcher or the pan/zoom control)
139 if (!overScrollableDiv && overMapDiv) {
143 OpenLayers.Event.stop(e);
149 * Given the wheel event, we carry out the appropriate zooming in or out,
150 * based on the 'wheelDelta' or 'detail' property of the event.
155 wheelZoom: function(e) {
162 delta = e.wheelDelta/120;
163 if (window.opera && window.opera.version() < 9.2) {
166 } else if (e.detail) {
167 delta = -e.detail / 3;
170 // add the mouse position to the event because mozilla has
171 // a bug with clientX and clientY (see
172 // https://bugzilla.mozilla.org/show_bug.cgi?id=352179)
173 // getLonLatFromViewPortPx(e) returns wrong values
174 if (this.mousePosition) {
175 e.xy = this.mousePosition;
178 // If the mouse hasn't moved over the map yet, then
179 // we don't have a mouse position (in FF), so we just
180 // act as if the mouse was at the center of the map.
181 // Note that we can tell we are in the map -- and
182 // this.map is ensured to be true above.
183 e.xy = this.map.getPixelFromLonLat(
188 this.callback("down", [e, delta]);
190 this.callback("up", [e, delta]);
197 * Update the stored mousePosition on every move.
200 * evt - {Event} The browser event
203 * {Boolean} Allow event propagation
205 mousemove: function (evt) {
206 this.mousePosition = evt.xy;
212 activate: function (evt) {
213 if (OpenLayers.Handler.prototype.activate.apply(this, arguments)) {
214 //register mousewheel events specifically on the window and document
215 var wheelListener = this.wheelListener;
216 OpenLayers.Event.observe(window, "DOMMouseScroll", wheelListener);
217 OpenLayers.Event.observe(window, "mousewheel", wheelListener);
218 OpenLayers.Event.observe(document, "mousewheel", wheelListener);
228 deactivate: function (evt) {
229 if (OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {
230 // unregister mousewheel events specifically on the window and document
231 var wheelListener = this.wheelListener;
232 OpenLayers.Event.stopObserving(window, "DOMMouseScroll", wheelListener);
233 OpenLayers.Event.stopObserving(window, "mousewheel", wheelListener);
234 OpenLayers.Event.stopObserving(document, "mousewheel", wheelListener);
241 CLASS_NAME: "OpenLayers.Handler.MouseWheel"