Changeset 7615

Show
Ignore:
Timestamp:
07/30/08 14:23:19 (6 years ago)
Author:
crschmidt
Message:

Change getMousePosition to only be called automatically *if* the 'includeXY'
flag on the Events object is set to true. This ends up meaning that we save a
lot of unneccesary getMousePosition calls because (for example) the layer
doesn't need to include the .xy property. In addition, we add in speed
improvements via caching to the getMousePosition, courtesy the work from
pgiraud (which was worked on further by tcoulter) -- this results in
significantly improved getMousePosition performance improvements in 'real life'
situations that are more like the cases that people use OpenLayers, with a
higher number of containing divs (and also clearly demonstrate a gain in
performance even in the simple case.)

The end result is:

  • In typical map movement over the map, (n / n+1) fewer calls to getMousePosition, where n is the number of active layers when dragging over the map.
  • In the simple case, 40% faster getMousePosition performance -- and in more complex cases, significantly more performance improvements.

To drop the former improvement, which may affect some applications (as
described in the includeXY documentation) simply set:

OpenLayers.Events.prototype.includeXY = true;

This will restore the 'every element has an xy property always' behavior
that was the case beore this patch.

r=me,tschaub, work by pgiraud related to (See #1509), and (Closes #1459)

Location:
trunk/openlayers/lib/OpenLayers
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/openlayers/lib/OpenLayers/Control/PanZoomBar.js

    r7341 r7615  
    166166        this.slider = slider; 
    167167         
    168         this.sliderEvents = new OpenLayers.Events(this, slider, null, true); 
     168        this.sliderEvents = new OpenLayers.Events(this, slider, null, true, 
     169                                            {includeXY: true}); 
    169170        this.sliderEvents.on({ 
    170171            "mousedown": this.zoomBarDown, 
     
    198199        this.zoombarDiv = div; 
    199200         
    200         this.divEvents = new OpenLayers.Events(this, div, null, true); 
     201        this.divEvents = new OpenLayers.Events(this, div, null, true,  
     202                                                {includeXY: true}); 
    201203        this.divEvents.on({ 
    202204            "mousedown": this.divClick, 
  • trunk/openlayers/lib/OpenLayers/Events.js

    r7610 r7615  
    393393    fallThrough: null, 
    394394 
     395    /**  
     396     * APIProperty: includeXY 
     397     * {Boolean} Should the .xy property automatically be created for browser 
     398     *    mouse events? In general, this should be false. If it is true, then 
     399     *    mouse events will automatically generate a '.xy' property on the  
     400     *    event object that is passed. (Prior to OpenLayers 2.7, this was true 
     401     *    by default.) Otherwise, you can call the getMousePosition on the 
     402     *    relevant events handler on the object available via the 'evt.object' 
     403     *    property of the evt object. So, for most events, you can call: 
     404     *    function named(evt) {  
     405     *        this.xy = this.object.events.getMousePosition(evt)  
     406     *    }  
     407     * 
     408     *    This option typically defaults to false for performance reasons: 
     409     *    when creating an events object whose primary purpose is to manage 
     410     *    relatively positioned mouse events within a div, it may make 
     411     *    sense to set it to true. 
     412     * 
     413     *    This option is also used to control whether the events object caches 
     414     *    offsets. If this is false, it will not: the reason for this is that 
     415     *    it is only expected to be called many times if the includeXY property 
     416     *    is set to true. If you set this to true, you are expected to clear  
     417     *    the offset cache manually (using this.clearMouseCache()) if: 
     418     *        the border of the element changes 
     419     *        the location of the element in the page changes 
     420    */ 
     421    includeXY: false,       
     422 
    395423    /** 
    396424     * Constructor: OpenLayers.Events 
     
    403431     * fallThrough - {Boolean} Allow events to fall through after these have 
    404432     *                         been handled? 
    405      */ 
    406     initialize: function (object, element, eventTypes, fallThrough) { 
     433     * options - {Object} Options for the events object. 
     434     */ 
     435    initialize: function (object, element, eventTypes, fallThrough, options) { 
     436        OpenLayers.Util.extend(this, options); 
    407437        this.object     = object; 
    408438        this.element    = element; 
     
    692722     */ 
    693723    handleBrowserEvent: function (evt) { 
    694         evt.xy = this.getMousePosition(evt);  
     724        if (this.includeXY) { 
     725            evt.xy = this.getMousePosition(evt); 
     726        }  
    695727        this.triggerEvent(evt.type, evt); 
    696728    }, 
     729 
     730    /** 
     731     * APIMethod: clearMouseCache 
     732     * Clear cached data about the mouse position. This should be called any  
     733     *     time the element that events are registered on changes position  
     734     *     within the page. 
     735     */ 
     736    clearMouseCache: function() {  
     737        this.element.scrolls = null; 
     738        this.element.lefttop = null; 
     739        this.element.offsets = null; 
     740    },       
    697741 
    698742    /** 
     
    707751     */ 
    708752    getMousePosition: function (evt) { 
     753        if (!this.includeXY) { 
     754            this.clearMouseCache(); 
     755        } else if (!this.element.hasScrollEvent) { 
     756            OpenLayers.Event.observe(window, 'scroll',  
     757                OpenLayers.Function.bind(this.clearMouseCache, this));  
     758            this.element.hasScrollEvent = true; 
     759        } 
     760         
     761        if (!this.element.scrolls) { 
     762            this.element.scrolls = []; 
     763            this.element.scrolls[0] = (document.documentElement.scrollLeft 
     764                         || document.body.scrollLeft); 
     765            this.element.scrolls[1] = (document.documentElement.scrollTop 
     766                         || document.body.scrollTop); 
     767        } 
     768 
     769        if (!this.element.lefttop) { 
     770            this.element.lefttop = []; 
     771            this.element.lefttop[0] = (document.documentElement.clientLeft || 0); 
     772            this.element.lefttop[1] = (document.documentElement.clientTop || 0); 
     773        } 
     774         
    709775        if (!this.element.offsets) { 
    710776            this.element.offsets = OpenLayers.Util.pagePosition(this.element); 
    711             this.element.offsets[0] += (document.documentElement.scrollLeft 
    712                          || document.body.scrollLeft); 
    713             this.element.offsets[1] += (document.documentElement.scrollTop 
    714                          || document.body.scrollTop); 
     777            this.element.offsets[0] += this.element.scrolls[0]; 
     778            this.element.offsets[1] += this.element.scrolls[1]; 
    715779        } 
    716780        return new OpenLayers.Pixel( 
    717             (evt.clientX + (document.documentElement.scrollLeft 
    718                          || document.body.scrollLeft)) - this.element.offsets[0] 
    719                          - (document.documentElement.clientLeft || 0),  
    720             (evt.clientY + (document.documentElement.scrollTop 
    721                          || document.body.scrollTop)) - this.element.offsets[1] 
    722                          - (document.documentElement.clientTop || 0) 
     781            (evt.clientX + this.element.scrolls[0]) - this.element.offsets[0] 
     782                         - this.element.lefttop[0],  
     783            (evt.clientY + this.element.scrolls[1]) - this.element.offsets[1] 
     784                         - this.element.lefttop[1] 
    723785        );  
    724786    }, 
  • trunk/openlayers/lib/OpenLayers/Map.js

    r7596 r7615  
    427427                                            this.div,  
    428428                                            this.EVENT_TYPES,  
    429                                             this.fallThrough); 
     429                                            this.fallThrough,  
     430                                            {includeXY: true}); 
    430431        this.updateSize(); 
    431432        if(this.eventListeners instanceof Object) { 
     
    12031204    updateSize: function() { 
    12041205        // the div might have moved on the page, also 
    1205         this.events.element.offsets = null; 
     1206        this.events.clearMouseCache(); 
    12061207        var newSize = this.getCurrentSize(); 
    12071208        var oldSize = this.getSize();