From 7f18a7b3df8f9d3192e29d2a7feda5088baaca49 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Tue, 26 Mar 2013 11:53:27 +0100 Subject: [PATCH] Backbuffer and transitionend only when there are tiles When an application zooms the map programmatically right after initialization, there will be an empty backbuffer. This should be avoided, because it adds an unnecessary DOM element. The tile.onLoadEnd handler registers a transitionend listener on the image of the last loaded tile. But if loading was aborted, there will be no image. The new logic registers the transitionend event on the last child of the layer div, which is not necessarily the tile we're handling loadend for. When the backbuffer is empty (i.e. no tile was loaded at the time the backbuffer was created), it will be removed immediately. --- lib/OpenLayers/Layer/Grid.js | 29 ++++++++++++++++++----------- tests/Layer/Grid.html | 4 +++- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/lib/OpenLayers/Layer/Grid.js b/lib/OpenLayers/Layer/Grid.js index 0b47935bd0..8e9e56e9af 100644 --- a/lib/OpenLayers/Layer/Grid.js +++ b/lib/OpenLayers/Layer/Grid.js @@ -1110,18 +1110,25 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { } //if that was the last tile, then trigger a 'loadend' on the layer if (this.numLoadingTiles === 0) { - if(this.backBuffer) { - this._transitionElement = tile.imgDiv; - for (var i=this.transitionendEvents.length-1; i>=0; --i) { - OpenLayers.Event.observe(this._transitionElement, - this.transitionendEvents[i], - this._removeBackBuffer); + if (this.backBuffer) { + if (this.backBuffer.childNodes.length === 0) { + // no tiles transitioning, remove immediately + this.removeBackBuffer(); + } else { + // wait until transition has ended or delay has passed + this._transitionElement = this.div.lastChild; + var transitionendEvents = this.transitionendEvents; + for (var i=transitionendEvents.length-1; i>=0; --i) { + OpenLayers.Event.observe(this._transitionElement, + transitionendEvents[i], + this._removeBackBuffer); + } + // the removal of the back buffer is delayed to prevent + // flash effects due to the animation of tile displaying + this.backBufferTimerId = window.setTimeout( + this._removeBackBuffer, this.removeBackBufferDelay + ); } - // the removal of the back buffer is delayed to prevent - // flash effects due to the animation of tile displaying - this.backBufferTimerId = window.setTimeout( - this._removeBackBuffer, this.removeBackBufferDelay - ); } this.loading = false; this.events.triggerEvent("loadend"); diff --git a/tests/Layer/Grid.html b/tests/Layer/Grid.html index 1a4d9abfca..3f7861f222 100644 --- a/tests/Layer/Grid.html +++ b/tests/Layer/Grid.html @@ -1334,7 +1334,9 @@ t.ok(layer.backBuffer === map.layerContainerDiv.firstChild, '[a] back buffer is first child of layer container div'); - // Mark one tile loaded, to see if back buffer removal gets scheduled. + // Mark one tile loaded and add an element to the backbuffer, to see if + // backbuffer removal gets scheduled. + layer.backBuffer.appendChild(document.createElement('img')); layer.grid[1][1].onImageLoad(); t.ok(layer.backBufferTimerId !== null,