OpenLayers OpenLayers

Changeset 6416

Show
Ignore:
Timestamp:
02/29/08 03:37:12 (11 months ago)
Author:
euzuro
Message:

be very very careful about how we deal with the wheel. only take action when over scrollable items or over the main map. all of this is explained in the ticket and patch it is really late and i dont feel like typing it again. basically, this puppy means that scrolling on controls or in popups will no longer zoom the map unwantedly. that is good. thank you cr5 and IRC for taking such care of me. (r=cr5) (Closes #1382)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/openlayers/lib/OpenLayers/Handler/MouseWheel.js

    r6004 r6416  
    6767     */ 
    6868    onWheelEvent: function(e){ 
    69         // first check keyboard modifiers 
    70         if (!this.checkModifiers(e)) { 
     69         
     70        // make sure we have a map and check keyboard modifiers 
     71        if (!this.map || !this.checkModifiers(e)) { 
    7172            return; 
    7273        } 
    73         // first determine whether or not the wheeling was inside the map 
    74         var inMap = false; 
     74         
     75        // Ride up the element's DOM hierarchy to determine if it or any of  
     76        //  its ancestors was:  
     77        //   * specifically marked as scrollable 
     78        //   * one of our layer divs 
     79        //   * the map div 
     80        // 
     81        var overScrollableDiv = false; 
     82        var overLayerDiv = false; 
     83        var overMapDiv = false; 
     84         
    7585        var elem = OpenLayers.Event.element(e); 
    76         while(elem != null) { 
    77             if (this.map && elem == this.map.div) { 
    78                 inMap = true; 
    79                 break; 
    80             } 
     86        while((elem != null) && !overMapDiv && !overScrollableDiv) { 
     87 
     88            if (!overScrollableDiv) { 
     89                try { 
     90                    if (elem.currentStyle) { 
     91                        overflow = elem.currentStyle["overflow"]; 
     92                    } else { 
     93                        var style =  
     94                            document.defaultView.getComputedStyle(elem, null); 
     95                        var overflow = style.getPropertyValue("overflow"); 
     96                    } 
     97                    overScrollableDiv = ( overflow &&  
     98                        (overflow == "auto") || (overflow == "scroll") ); 
     99                } catch(err) { 
     100                    //sometimes when scrolling in a popup, this causes  
     101                    // obscure browser error 
     102                } 
     103            } 
     104 
     105            if (!overLayerDiv) { 
     106                for(var i=0; i < this.map.layers.length; i++) { 
     107                    if (elem == this.map.layers[i].div) {  
     108                        overLayerDiv = true; 
     109                        break; 
     110                    } 
     111                } 
     112            } 
     113            overMapDiv = (elem == this.map.div); 
     114 
    81115            elem = elem.parentNode; 
    82116        } 
    83117         
    84         if (inMap) { 
    85             var delta = 0; 
    86             if (!e) { 
    87                 e = window.event; 
    88             } 
    89             if (e.wheelDelta) { 
    90                 delta = e.wheelDelta/120;  
    91                 if (window.opera && window.opera.version() < 9.2) { 
    92                     delta = -delta; 
    93                 } 
    94             } else if (e.detail) { 
    95                 delta = -e.detail / 3; 
    96             } 
    97             if (delta) { 
    98                 // add the mouse position to the event because mozilla has a bug 
    99                 // with clientX and clientY (see https://bugzilla.mozilla.org/show_bug.cgi?id=352179) 
    100                 // getLonLatFromViewPortPx(e) returns wrong values 
    101                 if (this.mousePosition) { 
    102                     e.xy = this.mousePosition; 
    103                 }  
    104                 if (!e.xy) { 
    105                     // If the mouse hasn't moved over the map yet, then 
    106                     // we don't have a mouse position (in FF), so we just 
    107                     // act as if the mouse was at the center of the map. 
    108                     // Note that we can tell we are in the map -- and  
    109                     // this.map is ensured to be true above. 
    110                     e.xy = this.map.getPixelFromLonLat(this.map.getCenter()); 
    111                 } 
    112                 if (delta < 0) { 
    113                    this.callback("down", [e, delta]); 
    114                 } else { 
    115                    this.callback("up", [e, delta]); 
    116                 } 
    117             } 
    118              
    119             //only wheel the map, not the window 
     118        // Logic below is the following: 
     119        // 
     120        // If we are over a scrollable div or not over the map div: 
     121        //  * do nothing (let the browser handle scrolling) 
     122        // 
     123        //    otherwise  
     124        //  
     125        //    If we are over the layer div:  
     126        //     * zoom/in out 
     127        //     then 
     128        //     * kill event (so as not to also scroll the page after zooming) 
     129        // 
     130        //       otherwise 
     131        // 
     132        //       Kill the event (dont scroll the page if we wheel over the  
     133        //        layerswitcher or the pan/zoom control) 
     134        // 
     135        if (!overScrollableDiv && overMapDiv) { 
     136            if (overLayerDiv) { 
     137                this.wheelZoom(e); 
     138            } 
    120139            OpenLayers.Event.stop(e); 
    121140        } 
    122141    }, 
    123142 
     143    /** 
     144     * Method: wheelZoom 
     145     * Given the wheel event, we carry out the appropriate zooming in or out, 
     146     *     based on the 'wheelDelta' or 'detail' property of the event. 
     147     *  
     148     * Parameters: 
     149     * e - {Event} 
     150     */ 
     151    wheelZoom: function(e) { 
     152         
     153        var delta = 0; 
     154        if (!e) { 
     155            e = window.event; 
     156        } 
     157        if (e.wheelDelta) { 
     158            delta = e.wheelDelta/120;  
     159            if (window.opera && window.opera.version() < 9.2) { 
     160                delta = -delta; 
     161            } 
     162        } else if (e.detail) { 
     163            delta = -e.detail / 3; 
     164        } 
     165        if (delta) { 
     166            // add the mouse position to the event because mozilla has  
     167            // a bug with clientX and clientY (see  
     168            // https://bugzilla.mozilla.org/show_bug.cgi?id=352179) 
     169            // getLonLatFromViewPortPx(e) returns wrong values 
     170            if (this.mousePosition) { 
     171                e.xy = this.mousePosition; 
     172            }  
     173            if (!e.xy) { 
     174                // If the mouse hasn't moved over the map yet, then 
     175                // we don't have a mouse position (in FF), so we just 
     176                // act as if the mouse was at the center of the map. 
     177                // Note that we can tell we are in the map -- and  
     178                // this.map is ensured to be true above. 
     179                e.xy = this.map.getPixelFromLonLat( 
     180                    this.map.getCenter() 
     181                ); 
     182            } 
     183            if (delta < 0) { 
     184               this.callback("down", [e, delta]); 
     185            } else { 
     186               this.callback("up", [e, delta]); 
     187            } 
     188        } 
     189    }, 
     190     
    124191    /** 
    125192     * Method: mousemove 
  • trunk/openlayers/tests/Handler/test_MouseWheel.html

    r6131 r6416  
    5858        var delta = 120; 
    5959        if (window.opera && window.opera.version() < 9.2)  delta = -delta; 
    60         handler.onWheelEvent({'target':map.div, wheelDelta: delta}); 
     60        handler.onWheelEvent({'target':map.layers[0].div, wheelDelta: delta}); 
    6161        t.ok(pass, "evt.xy was set even without a mouse move"); 
    6262    }