OpenLayers OpenLayers

Changeset 2867

Show
Ignore:
Timestamp:
03/23/07 14:22:38 (2 years ago)
Author:
sderle
Message:

Fix the event listener leak, which has been a serious problem when large numbers of markers etc. are created. Closes #510.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/openlayers/lib/OpenLayers/Control/Navigation.js

    r2803 r2867  
    6060    }, 
    6161 
     62    wheelChange: function(evt, deltaZ) { 
     63        console.log("wheel " + deltaZ); 
     64        var newZoom = this.map.getZoom() + deltaZ; 
     65        if (!this.map.isValidZoomLevel(newZoom)) return; 
     66 
     67        var size    = this.map.getSize(); 
     68        var deltaX  = size.w/2 - evt.xy.x; 
     69        var deltaY  = size.h/2 - evt.xy.y; 
     70        var newRes  = map.baseLayer.resolutions[newZoom]; 
     71        var zoomPoint = this.map.getLonLatFromPixel(evt.xy); 
     72        var newCenter = new OpenLayers.LonLat( 
     73                            zoomPoint.lon + deltaX * newRes, 
     74                            zoomPoint.lat - deltaY * newRes ); 
     75        console.log(newCenter.toString()); 
     76        this.map.setCenter( newCenter, newZoom ); 
     77    }, 
     78 
    6279    /** User spun scroll wheel up 
    6380     *  
    6481     */ 
    6582    wheelUp: function(evt) { 
    66         this.map.setCenter(this.map.getLonLatFromPixel(evt.xy), 
    67                            this.map.getZoom() + 1); 
     83        this.wheelChange(evt, 1); 
    6884    }, 
    6985 
     
    7288     */ 
    7389    wheelDown: function(evt) { 
    74         this.map.setCenter(this.map.getLonLatFromPixel(evt.xy), 
    75                            this.map.getZoom() - 1); 
     90        this.wheelChange(evt, -1); 
    7691    }, 
    7792     
  • trunk/openlayers/lib/OpenLayers/Events.js

    r2803 r2867  
    7373    for (var i = 0; i < OpenLayers.Event.observers.length; i++) { 
    7474      OpenLayers.Event.stopObserving.apply(this, OpenLayers.Event.observers[i]); 
    75       OpenLayers.Event.observers[i][0] = null; 
    7675    } 
    7776    OpenLayers.Event.observers = false; 
     
    9897        || element.detachEvent)) 
    9998      name = 'keydown'; 
     99 
     100    // find entry in this.observers cache array and remove it 
     101    var observers = OpenLayers.Event.observers; 
     102    var entry = [element, name, observer, useCapture]; 
     103    for (var i = 0; i < observers.length; i++) { 
     104        var observer = observers[i]; 
     105 
     106        //compare all 4 elements of entry with observer 
     107        var sameEntry = true;         
     108        for (var j = 0; j < entry.length; j++) { 
     109            if (entry[j] != observer[j]) { 
     110                sameEntry = false; 
     111                break; 
     112            } 
     113        } 
     114 
     115        //if we've found it, remove it from the observers array 
     116        if (sameEntry) { 
     117            observers.splice(i--, 1); 
     118            break;  
     119        } 
     120    } 
    100121 
    101122    if (element && element.removeEventListener) { 
     
    115136} 
    116137 
    117  
    118  
    119138/** 
    120139 * @class 
     
    145164 
    146165    /** 
     166    * @type Function: bound event handler attached to elements 
     167    * @private 
     168    */ 
     169    eventHandler: null, 
     170 
     171    /** @type Boolean */ 
     172    fallThrough: null, 
     173 
     174    /** 
    147175     * @constructor  
    148176     *  
     
    161189        this.listeners  = new Object(); 
    162190 
     191        // keep a bound copy of handleBrowserEvent() so that we can 
     192        // pass the same function to both Event.observe() and .stopObserving() 
     193        this.eventHandler = this.handleBrowserEvent.bindAsEventListener(this); 
     194 
    163195        // if eventTypes is specified, create a listeners list for each  
    164196        // custom application event. 
     
    174206 
    175207    /** 
     208     *  
     209     */ 
     210    destroy: function () { 
     211        if (this.element) { 
     212            this.detachFromElement(); 
     213        } 
     214        this.element = null; 
     215 
     216        this.listeners = null; 
     217        this.object = null; 
     218        this.eventTypes = null; 
     219        this.fallThrough = null; 
     220        this.eventHandler = null; 
     221    }, 
     222 
     223    /** 
    176224    * @param {HTMLDOMElement} element a DOM element to attach browser events to 
    177225    */ 
     
    186234 
    187235            // use Prototype to register the event cross-browser 
    188             OpenLayers.Event.observe(element, eventType,  
    189                 this.handleBrowserEvent.bindAsEventListener(this)); 
     236            OpenLayers.Event.observe(element, eventType, this.eventHandler); 
    190237        } 
    191238        // disable dragstart in IE so that mousedown/move/up works normally 
    192239        OpenLayers.Event.observe(element, "dragstart", OpenLayers.Event.stop); 
     240    }, 
     241     
     242    /** 
     243     * @private 
     244     */ 
     245    detachFromElement: function () { 
     246        for (var i = 0; i < this.BROWSER_EVENTS.length; i++) { 
     247            var eventType = this.BROWSER_EVENTS[i]; 
     248 
     249            OpenLayers.Event.stopObserving( 
     250                this.element, eventType, this.eventHandler); 
     251        } 
     252 
     253        // re-enable dragstart in IE 
     254        OpenLayers.Event.stopObserving( 
     255            this.element, "dragstart", OpenLayers.Event.stop); 
    193256    }, 
    194257 
     
    228291        } 
    229292    }, 
    230     // TODO: get rid of this in 3.0 
    231     // Decide whether listeners should be called in the order they were 
    232     // registered or in reverse order. 
     293 
     294    /** 
     295     *   TODO: get rid of this in 3.0 - Decide whether listeners should be  
     296     *         called in the order they were registered or in reverse order. 
     297     *  
     298     * @param {String} type Name of the event to register 
     299     * @param {Object} obj The object to bind the context to for the callback#. 
     300     *                     If no object is specified, default is the Events's  
     301     *                     'object' property. 
     302     * @param {Function} func The callback function. If no callback is  
     303     *                        specified, this function does nothing. 
     304     */ 
    233305    registerPriority: function (type, obj, func) { 
    234306 
  • trunk/openlayers/tests/test_Events.html

    r2541 r2867  
    202202        t.eq(a, 5, "if Events has no object set and an event is registered also with no object, triggerEvent() calls it without trying to set the context to null");         
    203203    } 
     204 
     205    function test_05_Event_destroy (t) { 
     206        t.plan(2); 
     207        var start = OpenLayers.Event.observers.length; 
     208        var div   = OpenLayers.Util.getElement('test'); 
     209        var obj   = {}; 
     210        var events = new OpenLayers.Events(obj, div); 
     211        // +1 because of blocking dragstart in attachToElement() 
     212        t.eq(OpenLayers.Event.observers.length, 
     213             start + OpenLayers.Events.prototype.BROWSER_EVENTS.length + 1, 
     214             "construction increases the number of event observers"); 
     215        events = events.destroy(); 
     216        t.eq(OpenLayers.Event.observers.length, start, 
     217             "destruction restores the number of event observers"); 
     218    } 
    204219    
    205220  // --> 
     
    208223<body> 
    209224    <div id="map" style="width: 1024px; height: 512px;"/> 
     225    <div id="test"></div> 
    210226</body> 
    211227</html>