5
votes

I'm working on a web app that integrates with google maps and I'm having an issue with zoom_changed event firing twice after calling fitBounds. The only reference I have to fitBounds is in updateMap. The only time I attach the event listener is in createMap.

The second call to the zoom changed handler is causing another trigger to update the map.

I've read this article already: Do not fire 'zoom_changed' event when calling fitBounds function on map

The flag is working fine for the first event. But why is there another zoom_changed event being fired?

Even better, how can I prevent the second zoom_changed event from firing?

Here is what I'm seeing in my console log:

updateMap, fitbounds: 0
calling fitbounds...
zoom changed
mapEventHandler, fitbounds: 1
zoom changed
mapEventHandler, fitbounds: 0

Here is the code for my update map function which calls fitBounds:

var mapZoomOrDragEventInProgress = false;
var fitBoundsCalledCount = 0;
var map = null;

updateMap = function () {
    console.log("updateMap, fitbounds: " + fitBoundsCalledCount);

    var bounds = fitBoundsForVenues();

    deleteAndUpdateMarkers();

    if (!mapZoomOrDragEventInProgress) {
        bn.spg.map.vars.fitBoundsCalledCount++;
        if (markers.length > 1) {
            console.log("calling fitbounds...");
            map.fitBounds(bounds);
        } else {
            console.log("setting zoom...");
            map.setCenter(bounds.getCenter());
            map.setZoom(13);
        }
    }

    mapZoomOrDragEventInProgress = false;
}

Here is my create map function:

createMap = function() {
    if (map === null) {
        var bounds = fitBoundsForVenues();

        var mapOptions = {
            center: bounds.getCenter(),
            zoom: 13,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };

        map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

        google.maps.event.addListener(map, 'zoom_changed', zoomChangedEventHandler)
        google.maps.event.addListener(map, 'dragend', dragendEventHandler);
     }
}

Here is my event handler:

zoomChangedEventHandler = function () {
    console.log("zoom changed");
    console.log("mapEventHandler, fitbounds: " + fitBoundsCalledCount);

    //we want to handle only user zoom events, NOT zoom_events triggered from fit bounds or set_zoom
    if (fitBoundsCalledCount === 0) {
        mapZoomOrDragEventInProgress = true;
        var coords = getViewportCoordinates();
        updateVenuesAndMapAsync(coords.lat, coords.lng, coords.radius);
    } else {
        fitBoundsCalledCount--;
    }
}
1
can you give us a demo/link to the page?Dr.Molle
Unfortunately I can't. This project is still under development. My theory at the moment is that possibly we've attached two click handlers to the link that displays the map. If that turns out to not be the case, then I don't know what it is other than fitBounds just really fires two events.bluce
Having the same issue. This is what I figured out. fitBounds() tries to fit given bounds in the map viewport. It also changes the zoom level of the map accordingly. When bounds are very far from each other, fitBounds() fails to set the zoom level as it goes below Minimum zoom limit. So it sets the zoom level to zero. Which causes zoom_changed to fire twice.M Hussain

1 Answers

1
votes

I can't tell you where the 2nd zoom_changed-even has been triggered(I'm sure a single call of fitBounds() is not be the reason)

But instead of using these counters I would suggest to remove the zoom_changed-listener at the begin of updateMap() and to re-assign the listener at the end of updateMap()