12

Is there a way to prevent the zoom_change event from being triggered if it occurs due to fitBounds() ?

I am having an issue where I need to do a search on the server from client when there is a zoom change to map but every time I call fitBounds() it causes zoom_change to trigger which causes the client to do another search on the server. I am only interested in zoom_change done by users and not programmatically using fitBounds.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Encore PTL
  • 8,084
  • 10
  • 43
  • 78

6 Answers6

10

When you do a fitBounds in your program, set a global flag. When the zoom_changed event fires, if the flag is set, clear it, otherwise send your request off to the server.

geocodezip
  • 158,664
  • 13
  • 220
  • 245
  • 1
    That is what I am currently doing but when there is one marker and I get bounds for just one marker and do map.fitBounds(bounds) it triggers zoom_changed event twice. So the way I solve this is now I keep a global array and push an object into it every time I call fitBounds but when the bounds south west and north east coordinates are same (meaning you have all markers in one place or just one marker on map) then I push another object into the array and when the array is empty in trigger a redo search on server – Encore PTL Oct 25 '12 at 23:42
5

After many frustrating hours, here is my solution:

  var tiles_listener = google.maps.event.addListenerOnce(map, 'tilesloaded', function() {
    var zoom_listener = google.maps.event.addListener(map, 'zoom_changed', function() {
      reloadMarkers();
    });
  });

Note that I am calling addListenerOnce for tilesloaded to ensure that the zoome_changed listener is only added once, after the first fitBounds completes.

Abram
  • 39,950
  • 26
  • 134
  • 184
4

It's an old question, but it may be useful to others. I had the same problem, zoom_changed been triggered every time I called fitBounds() when adding several markers to a map. What I did was to add the listener to the map_changed event after the map was completely loaded, like this:

google.maps.event.addListener(map, 'tilesloaded', function() {
    google.maps.event.addListener(map, 'zoom_changed', function() {
Patrick D'Souza
  • 3,491
  • 2
  • 22
  • 39
kito
  • 181
  • 1
  • 5
  • 1
    This is not a good approach. zoom_changed will fire multiple times for zoom in and out due to tiles loading triggering it again and again. – Abram Dec 01 '15 at 04:19
  • 1
    Oh my god. @Abram, your comment was a lifesaved. I was pulling my hair out trying to figure out why every zoom event in my code was causing multiple zoom_changed events to fire, and your comment here gave me what I needed. Jesus Christ. You'd think a zoom_changed event would only fire when the zoom changes... – Kyle Baker Feb 14 '17 at 06:04
1

There is another way to do that by removing that that event. I think it would be much easier and cleaner than adding a global variable.

 vm.map.events.bounds_changed = function() {
   google.map.event.removeListener(zoom_changed);
   }

Another way (forgotten to add that):

     vm.map.events.bounds_changed = function() {
google.map.event.addEventListener(zoom_changed,function(mapper,eventName,args){});
           }
abby37
  • 597
  • 6
  • 21
0

In my app, I may fire off zoom change events programmatically, either via setZoom(), fitBounds(), or setOptions().

MAN = {};
MAN.globalMap = google.maps.Map(document.getElementById('map'));

I then route all programmatic calls to set the zoom through wrapper functions that flip a flag to false before they go on to set the zoom.

MAN.savedZoom = MAN.globalMap.getZoom();
MAN.saveZoomFlag = true;
// we want it to always be true, unless zoom was
// changed programatically.

MAN.setZoom = function setZoom(zoomLevel) {
  console.log("won't save that I'm setting zoomLevel to " + zoomLevel);
  this.saveZoomFlag = false;
  MAN.globalMap.setZoom(zoomLevel);
};

MAN.fitBounds = function fitBounds(bounds) {
  console.log("setting bounds, won't save zoomlevel.");
  this.saveZoomFlag = false;
  MAN.globalMap.fitBounds(bounds);
};

MAN.setOptions = function setOptions(options) {
  console.log("setting options, won't save zoomlevel.");
  this.saveZoomFlag = false;
  MAN.globalMap.setOptions(options);
};

I then declare a listeners. At first I was declaring only the first, and was puzzled that it wasn't working:

  google.maps.event.addListener(
    MAN.globalMap,
    'zoom_changed',
    function zoom_changed_listener() {
      console.log(
        "zoom changed to " +
        MAN.globalMap.getZoom() + "; " +
        (MAN.saveZoomFlag ? "saving." : "not saving.")
      );
      if (MAN.saveZoomFlag) {
        console.trace("saving");
        MAN.savedZoom = MAN.globalMap.getZoom();
      }
      MAN.saveZoomFlag = true;
    }
  );

you may also find the idle event helpful, however, if you're just trying to avoid the initial set. See more about the maps events here: https://developers.google.com/maps/documentation/javascript/events

Kyle Baker
  • 3,424
  • 2
  • 23
  • 33
-3

I suppose this should be simple. Have a variable say

var z = map.getZoom(); //scope this variable appropriately(somewhere before you call the fitbounds()

and then after the map.fitbounds() immediately do

map.setZoom(z); //this automatically changes the zoom level back to the previous level
Shiridish
  • 4,942
  • 5
  • 33
  • 64