My favorites | Sign in
Project Home Issues
New issue   Search
for
  Advanced search   Search tips   Subscriptions
Issue 1371: map.bounds_changed event fires repeatedly when the map is moving
33 people starred this issue and may be notified of changes. Back to list
Status:  Fixed
Owner:  ----
Closed:  Sep 2009


Sign in to add a comment
 
Reported by [email protected], Jun 5, 2009
Not sure if this is a bug or feature request. The issue is that the map's 
bounds_changed event fires repeatedly when the map is panning or dragging; 
I'd expect it to fire only when the move has finished. 

If this is by design, then there is a need for some other event to fire when 
movement has finished, whatever sort of action initiated the movement 
(double-click, drag, zoom control, pan control). The existing bounds_changed 
works like this for zoom-related movements, and it's possible to work around 
it when the move is from a drag, but I couldn't see a way to do so when the 
move came from a click on the large nav control.
Jun 5, 2009
#1 pamela.fox
Hmm, I'm also not sure if that's a bug or feature. We'll look into it.
Status: Confirmed
Labels: Internal-1901897
Jul 24, 2009
#2 jdpatterson
You can work around this behavior with a setTimeout() call to only act on the event once after it stops firing.

This fires the event after dragging has stopped for half a second.

function fireIfLastEvent()
{
    if (lastEvent.getTime() + 500 <= new Date().getTime())
    {
        alert('i am cool');
    }
}

function scheduleDelayedCallback()
{
    lastEvent = new Date();
    setTimeout(fireIfLastEvent, 500);
}

event.addListener(map, "bounds_changed", scheduleDelayedCallback);
Jul 27, 2009
#3 [email protected]
You can refer to this article inside javascript to fire only when the move has finished.

http://blog.finalevil.com/2009/07/google-maps-api-v3.html

Jul 27, 2009
#4 jdpatterson
Your method does not take into account resizes or zooms.  The solution I have above does and also stops too 
many events firing if the user zooms many levels at once for instance.
Aug 11, 2009
#5 d.l%[email protected]
 Issue 1516  has been merged into this issue.
Sep 5, 2009
#6 [email protected]
It is a feature.  Please do not change it without another way to track movement. 
Otherwise, I will have no way to know which tiles are visible.  I have to replace
CANVAS tiles in sync with map tiles.  I suppose "center_changed" plus "zoom_changed"
could be used but "bounds_changed" does both.

Sep 5, 2009
#7 [email protected]
In the old API I would achieve this affect by combining the dragend and zoomend
function (which, looking at the docs, might be the same as moveend, but i'd have to
test that out to be sure).

If this is by design, then please keep it by all means.. but there needs to be an
event (or even a combination of events) that fires whenever the map:

1). has loaded and ready to do stuff to
2). has completed a drag (essentially an onmouseup on the map)
3). has zoomed in/out

those are the only three things that I can think of. I just need a way to know when
to make a server request to load new objects onto the map when the user has changed
something about the bounds.
Sep 5, 2009
#8 [email protected]
An optimal 'moveend' event would return a map state object with URL parameter
key:value pairs.{ll:coords, spn:span, t:mapType} like undocumented 'softstateurlhook'
does in v2.
Sep 13, 2009
#9 [email protected]
Agree with fuhrysteve above in terms of having a guaranteed state where the map is done moving and the 
get_bounds will work.

Right now the behavior I'm seeing is that sometimes when you get the dragend event the bounds aren't finished, 
which means you can't reliably go to the server on the drag end.  It would seem that if you rely on the behavior 
that jdpatterson is recommending above, then you could end up in a state where the user drags the map, 
pauses for a second, without releasing the map, and then drags again, which could end up with some strange 
conditions depending on how long the server takes to return etc.
Sep 18, 2009
#10 d.l%[email protected]
(No comment was entered for this change.)
Status: FixedNotReleased
Sep 19, 2009
#11 info%[email protected]
I would also like to vote for a "moveend" off the map, as explained in another issue
that I created:

https://code.google.com/p/gmaps-api-issues/issues/detail?id=1692
Sep 22, 2009
#12 d.l%[email protected]
(No comment was entered for this change.)
Status: Fixed
Labels: Fixed-16
Sep 22, 2009
#13 [email protected]
Could someone explain precisely what has changed with this bug being fixed? I am
still getting dozens of calls to this function while dragging the map.. has a
different callback function that has been added?
Sep 22, 2009
#14 d.l%[email protected]
A new Map event "idle" has been added, which fires when the map hasn't moved for a bit.
Sep 23, 2009
#15 [email protected]
This is really an excellent, and really an ambitious fix. Thanks a lot!
Sep 24, 2009
#16 [email protected]
In combination with map.panTo, this event behaves just like bounds_changed. Does it 
need some tricks to work with panTo, too?
Oct 12, 2009
#17 d.l%[email protected]
I confirmed the 'idle' event works with panTo and panBy functions.  Are you still
having an issue with it?
Oct 13, 2009
#18 [email protected]
Yes and No. When the action of the event is a simple alert, then it's OK. However, when 
you want to create a new OverlayView object (eg. CustomMarker.prototype = new 
google.maps.OverlayView();), it just fails. Using map.setCenter instead of map.panTo, 
it works indeed... I will give a try to start / restart a timer upon event "idle", 
maybe it is a workaround...
Oct 23, 2009
#19 [email protected]
Is it just me or does idle seem to work very similarly to bounds_changed in that it
is constantly triggered while a zoom or pan is still in progress?  The description
says it should fire after panning or zooming.  Is this a bug?
Oct 23, 2009
#20 [email protected]
There is a slight delay, it seems, with idle. bounds_changed appears kindof like a
chain gun, firing a lot of times a second. Idle is a much less severe than that.

I agree though: "firing after panning or zooming" would be an inaccurate description
of this method. More like "fires occasionally while zooming / panning" would be more
accurate.
Jan 16, 2011
#21 [email protected]
I've found that the idle method fires "unexpectedly" while I'm still dragging the map but have "paused dragging" (i.e. I'm still holding down left click, I've just stopped moving the mouse). It appears as though whatever it is in Google's code that fires the idle event recognizes that the map has been still for a period, even though I'm still interacting with it. Still far better than trying to monitor bounds_changed, would be great if there was something to the effect of onInteractionComplete.
Jan 17, 2011
#22 [email protected]
I wanted to deal with the unexpected firing of idle, and have my respondToMapChange method only run when the user is done interacting with the map. I wound up coming up with a series of listeners to deal with the issue. Basically, the idle listener deals with the pan button and zooming by itself. It works with the drag events to handle dragging. They work together because I found dragging, followed by stopping but not letting go, to fire idle "unexpectedly" (though sensibly, as it was idle). 

This code is working well so far. FYI, this code lives inside of a Mootools class, hence the bind call (http://mootools.net/docs/core/Types/Function#Function:bind).

    google.maps.event.addListener(this.map.map, 'idle', function() {
        if (this.isMapDragging) {
            this.idleSkipped = true;
            return;
        }
        this.idleSkipped = false;
        this._respondToMapChange();
    }.bind(this));
    google.maps.event.addListener(this.map.map, 'dragstart', function() {
        this.isMapDragging = true;
    }.bind(this));
    google.maps.event.addListener(this.map.map, 'dragend', function() {
        this.isMapDragging = false;
        if (this.idleSkipped == true) {
            this._respondToMapChange();
            this.idleSkipped = false;
        }
    }.bind(this));
    google.maps.event.addListener(this.map.map, 'bounds_changed', function() {
        this.idleSkipped = false;
    }.bind(this));
Dec 21, 2012
#23 [email protected]
Well still no appropriate fix for this?
May 10, 2013
#25 [email protected]
Here is a little snippet that will remove all redundant 'bound_changed' call's:

var timeout;
google.maps.event.addListener(map, 'bounds_changed', function () {
window.clearTimeout(timeout);
timeout = window.setTimeout(function () {
	//do stuff on event
	});
}, 500); //time in ms, that will reset if next 'bounds_changed' call is send, otherwise code will be executed after that time is up
Feb 4, 2014
#26 [email protected]
Not sure why this is marked as fixed, I'm still having the issue.
Mar 20, 2014
#27 [email protected]
I am having the same problem too. The bug was reported in 2009.
Feb 18, 2016
#28 [email protected]
Still would be great to have an event that:
 * fires when any user actions have terminated (zoom, pan, drag) and the key used to do this has been released
 * guarantees that new bounds and center are available
 * does not need any delay to be fired like idle does

Sign in to add a comment

Powered by Google Project Hosting