You correctly remove previous layer(s) only once the data for the new layer is received, but not its tiles (images). That is why your map appears empty for a short time.
You could first attach your removeAllLayersExcept
callback to the "load"
event of your new Tile Layer.
Fired when the tile layer loaded all visible tiles.
Then you would also leave a short timeout before actually removing other layer(s), because the new tiles will appear with a little delay and transition, even if they are correctly loaded already.
cartodb.createLayer(map, layerSource)
.addTo(map)
.done(function(layer) {
//removeAllLayersExcept(layer);
layer.once("load", function () { // Remove only once the new tile layer has downloaded all tiles in view port.
removeAllLayersExcept(layer);
});
setTimeout(updateMap, 1000);
})
.error(function(err) {
console.log("error: " + err);
});
function removeAllLayersExcept(new_layer) {
console.log('new_layer._leaflet_id:' + new_layer._leaflet_id);
var layer_index = 0;
map.eachLayer(function(layer) {
if (layer_index > 0 && layer._leaflet_id != new_layer._leaflet_id) {
console.log('layer removed:' + layer._leaflet_id);
//map.removeLayer(layer);
setTimeout(function () { // give a little time before removing previous tile layer because new one will appear with some transition.
map.removeLayer(layer);
}, 500);
}
layer_index++;
});
}
Demo: http://jsfiddle.net/fLkqgf4q/5/
Note: you may also need to harden your removeAllLayersExcept
function to cover the case where a more recent Tile Layer is loaded before a previous one (due to some back connectivity or whatever). Otherwise the previous layer will make the new one being removed from map. But then you also need to handle the case when the user manually drags the cursor backwards.