Google Map event bounds_changed triggered multiple times when dragging

JavascriptGoogle MapsDom Events

Javascript Problem Overview


I have a google map with markers. I want my markers to be refreshed when the map is moved/zoomed...

Google recommend to use the event bounds_changed for that, but when I move the map, the event is triggered for each pixel that I move the map. I want the map to be refreshed only when the user stopped moving the map, i.e. when he released the mouse button after dragging.

How can I do that ?

Javascript Solutions


Solution 1 - Javascript

It turns out it was a reported bug: http://code.google.com/p/gmaps-api-issues/issues/detail?id=1371.

The Google team recommend to use the event "idle". For example :

google.maps.event.addListener(map, 'idle', function() {
});

Solution 2 - Javascript

While the selected answer is best for most circumstances. If you want to control the delay yourself, you can simply use something like;

 var mapupdater;

 {....}

 google.maps.event.addListener(map, "bounds_changed", mapSettleTime); 


 function mapSettleTime() {
	 clearTimeout(mapupdater);
	 mapupdater=setTimeout(getMapMarkers,500);
 }
 

Solution 3 - Javascript

Add a timeout, that runs your code 500ms after the event fires, each time the event fires clear the timeout and create a new one.

google.maps.event.addListener(map, 'bounds_changed', (function () {
    var timer;
    return function() {
        clearTimeout(timer);
        timer = setTimeout(function() {
            // here goes an ajax call
        }, 500);
    }
}()));

Solution 4 - Javascript

You should check how a debounce function works. A nice article by Taylor Case define it as follows:

> This function is built in order to limit the amount of times a > function is called — scroll events, mousemove events, and keypress > events are all great examples of events that we might want to capture, > but can be quite taxing if we capture them every single time they > fire.

So you define the function somewhere in your code:

function debounce(fn, time) {
  let timeout;
  return function() {
    const args = arguments;
    const functionCall = () => fn.apply(this, args);
    clearTimeout(timeout);
    timeout = setTimeout(functionCall, time);
  }
}

Then you just use that function when adding your listener:

google.maps.event.addListener(myMap, 'bounds_changed', debounce(() => { /* Do something here */ }, 250));

It seems that 250 ms is a good frequency to use here.

Solution 5 - Javascript

try using both zoom_changed and dragend

Solution 6 - Javascript

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMatthieu NapoliView Question on Stackoverflow
Solution 1 - JavascriptMatthieu NapoliView Answer on Stackoverflow
Solution 2 - Javascript0x1bView Answer on Stackoverflow
Solution 3 - JavascriptHimanshu KhuranaView Answer on Stackoverflow
Solution 4 - JavascriptMau MuñozView Answer on Stackoverflow
Solution 5 - JavascriptGalenView Answer on Stackoverflow
Solution 6 - JavascriptyadavrView Answer on Stackoverflow